Add Support For Password-Protected Receivers - #26
Merged
Conversation
Receivers with "Require Password" enabled use a password you set rather than a rotating onscreen code, so nothing appears on the TV and the old prompt sent you looking for one. A failed pair-pin-start is likewise normal for those receivers, so warn instead of exiting. Also read the whole line: fmt.Scanln stops at the first space and silently truncated any password containing one.
A receiver that rejects SETUP answers with a bare status and no body, so there is nothing to go on without seeing what was actually sent. Dumps both the setup plist and the audio stream descriptor in a stable key order, with byte slices summarised, so two runs can be diffed.
Owner
|
Thanks for this! Password option appears to work great. It doesn't appear the PTP path is implemented correctly. Testing locally I'm seeing the stream stop after the first correct broadcast frame. Couple other minor things:
|
A receiver with "Require Password" enabled challenges SETUP with 401 and a WWW-Authenticate Digest header, which nothing answered, so mirroring to it was impossible. The challenge carries no qop or algorithm, so this is RFC 2069 digest: MD5(HA1:nonce:HA2). The retry lives inside rtspRequest/httpRequest rather than at the 24 call sites, so every request is covered uniformly and the mirroring code is untouched. The nonce is cached on first sight, so only the first request on a connection pays for a retry: a receiver that challenges one request challenges them all. The Digest username is fixed at "AirPlay", matching the realm="airplay" that mirroring receivers advertise. It is deliberately not configurable: the challenge never carries a username and it is folded into HA1, so a wrong guess is indistinguishable from a wrong password -- an option there would only offer a second way to produce the same 401. Renames -pin to -code rather than adding a second flag beside it. The two carry the same thing from the user's point of view -- whatever the receiver is asking for, an onscreen PIN or a configured password -- and the receiver, not the user, decides which one it wants. $DOUBLETAKE_CODE is preferred and takes precedence, since a command line is visible to other users in ps and lands in shell history. A code no longer implies pairing. -pin forced a full pair-setup, which is wrong for a password: that is needed on every session, so re-pairing each run would discard working credentials. -pair still asks for one explicitly. Verified against AppleTV14,1 / tvOS 26.5 (AirTunes/950.7.1): realm="airplay", username "AirPlay", uri as the absolute request URI. Full password-protected mirroring session, 14x 200.
jamescoman
force-pushed
the
push-yzzksuzywvmy
branch
from
August 5, 2026 03:34
583146e to
97b7ff5
Compare
Contributor
Author
|
Thanks for taking a look! I thought the PTP issue was a result of differences in our testing hardware, Now that this is back to just adding password support, there's no net change in
|
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds support for receivers with Require Password enabled (on an Apple TV:
Settings → AirPlay and HomeKit). Such a receiver challenges the mirroring
SETUPwith HTTP Digest auth; nothing answered it, so mirroring failed withHTTP 401and there was no way past it.DOUBLETAKE_CODE='...' doubletake -target 192.168.1.77Commits
this was developed against.
assumed an onscreen 4-digit code, and
fmt.Scanlntruncated anything with aspace in it.
-debug— dumps the SETUP descriptorin a stable key order so two runs can be diffed. This is what made the rest
tractable.
— the fix itself.
Each builds and tests independently.
Notes on the implementation
The challenge carries no
qoporalgorithm, so this is RFC 2069 digest:MD5(HA1:nonce:HA2). The retry lives insidertspRequest/httpRequestratherthan at the ~24 call sites, so every request is covered uniformly and the
mirroring code is untouched by this PR. The nonce is cached on first sight, so
only the first request on a connection pays for a retry — a receiver that
challenges one request challenges them all.
The Digest username is fixed at
AirPlay, matching therealm="airplay"thatmirroring receivers advertise. It is deliberately not configurable: the
challenge never carries a username and it is folded into HA1, so a wrong guess
is indistinguishable from a wrong password, and an option there would only
offer a second way to produce the same 401.
-pinis renamed to-coderather than adding a second flag beside it. Thetwo carry the same thing from the user's point of view — whatever the receiver
is asking for, an onscreen PIN or a configured password — and the receiver, not
the user, decides which it wants. This PR adds no net new flags.
$DOUBLETAKE_CODEis preferred and takes precedence, since a command line isvisible to other users in
psand lands in shell history.One behaviour change worth flagging: a code no longer forces a full re-pair the
way
-pindid. A password is needed on every session, so re-pairing each runwould discard working credentials.
-pairstill requests one explicitly.Verification
End to end against a password-protected AppleTV14,1 / tvOS 26.5
(AirTunes/950.7.1): full mirroring session, 13× 200, a single 401 (the expected
first challenge), no warnings.
realm="airplay", usernameAirPlay,uriasthe absolute request URI — a path-only
uriis rejected with another 401.Unit tests cover challenge parsing (including a real receiver nonce), the
digest computation against an independently-derived vector, the retry decision
table, and end-to-end cases against a fake receiver: a challenged request is
retried with credentials, a request with no password configured is not retried
at all, and later requests reuse the cached challenge instead of being
challenged again.
Dropped after review
An earlier revision also advertised
timingProtocol=PTPfor pair-verifiedsessions, on the theory that receivers reject the legacy NTP clock with a bare
400. @omarroth found the resulting stream stalled after the first frame, andon re-testing I could not reproduce the
400at all — the same receiver nowcompletes SETUP on NTP in 133 ms and streams cleanly. That commit is gone and
timingProtocolis back to plain NTP.