Skip to content

SC-6: rsync daemon/server mode - #8

Merged
iampryce merged 1 commit into
mainfrom
sc-6-daemon-mode
Aug 1, 2026
Merged

iampryce merged 1 commit into
mainfrom
sc-6-daemon-mode

Conversation

@iampryce

@iampryce iampryce commented Aug 1, 2026

Copy link
Copy Markdown
Contributor

rsyncd.conf parsing (modules, read-only, list, exclude, auth users, secrets file, max connections, defaults, comments, line continuation), rsync:// URL parsing, real @rsyncd greeting/handshake, module listing with list=false hiding, MD4 challenge-response auth verified against rsync's actual source (secret-then-challenge, no seed byte, unpadded base64 - proven via raw wire-byte inspection that passwords never cross the wire). Module access control (read-only blocks uploads, exclude reuses sync.CompileRules). Wired into existing pipeline.Sender/Receiver, no duplicated transfer logic. --daemon --config --port CLI mode with real TCP listener.

Two real bugs found: DialGreeting had client/server speaking order reversed (deadlocked over io.Pipe, would've been masked by real TCP's OS buffering); Serve's per-connection goroutine had no panic recovery, so one bad connection could crash the whole daemon - fixed, plus added bounded line-length reads to close a memory-exhaustion vector on unauthenticated input.

Scope: classic MD4 only (no digest negotiation), exact-match auth users, no secrets-file permission checking, max connections parsed but unenforced, exclude on downloads only. Transfer after handshake still uses gob, not real rsync wire format - same boundary as SSH transport.

Clean on native Windows and cross-compiled Linux.

rsyncd.conf parsing (modules, read-only, list, exclude, auth users,
secrets file, max connections, defaults, comments, line continuation),
rsync:// URL parsing, real @rsyncd greeting/handshake, module listing
with list=false hiding, MD4 challenge-response auth verified against
rsync's actual source (secret-then-challenge, no seed byte, unpadded
base64 - proven via raw wire-byte inspection that passwords never
cross the wire). Module access control (read-only blocks uploads,
exclude reuses sync.CompileRules). Wired into existing
pipeline.Sender/Receiver, no duplicated transfer logic. --daemon
--config --port CLI mode with real TCP listener.

Two real bugs found: DialGreeting had client/server speaking order
reversed (deadlocked over io.Pipe, would've been masked by real TCP's
OS buffering); Serve's per-connection goroutine had no panic recovery,
so one bad connection could crash the whole daemon - fixed, plus added
bounded line-length reads to close a memory-exhaustion vector on
unauthenticated input.

Scope: classic MD4 only (no digest negotiation), exact-match auth
users, no secrets-file permission checking, max connections parsed but
unenforced, exclude on downloads only. Transfer after handshake still
uses gob, not real rsync wire format - same boundary as SSH transport.

Clean on native Windows and cross-compiled Linux.
@iampryce
iampryce requested a review from jasonmiller-cc August 1, 2026 05:45
@iampryce
iampryce merged commit 768bd4b into main Aug 1, 2026
2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant