FDH2 / UxPlay

AirPlay Unix mirroring server
GNU General Public License v3.0
1.34k stars 72 forks source link

iPad doesn't directly connect #253

Closed Booth1983 closed 6 months ago

Booth1983 commented 6 months ago

After several tries a problem came up. My system resets at every reboot and there for the login-log (.uxplay.pem) for uxplay is deleted at start up. So the airplay-server recreates it every time. I have the pin-option set. When it try to connect the iPad to uxplay the server seems to continue the login-process to the airplay-server before I submitted the pin. The iPad keeps asking me for the pin. When I type in the pin now the iPad doesn't connect and prompts a connection error. When I restart the uxplay-server now, the login with pin usually works fine.

I'll try to create a log in the new year.

If someone wants to try to recreate: Delete the login-log, start the uxplay-server, connect the iPad.

fduncanh commented 6 months ago

If the .pem file is deleted the public key of the uxplay server will change, and previous client registrations will become invalid. The client should think it is connecting to a new server, and send the pair-pin-start request.

After releasing uxplay 1.67, I saw that pair-ap (which implements a HomeKit pairing server) uses the DeviceID (hardware MAC address) to generate a unique but invariant public key).

My solution was to instead write a (private) key to the .uxplay.pem file (This would be available to to anyone with local file access to the host computer, but I don't think uxplay is hiding any big secrets that need protecting from those with file access). By contrast the MAC address would be visible over the network, and the method for generating the ED25519 keypair (private plus public) would be visible in the code, which is presumably less secure since it would not need local access. The DeviceID (immutable hardware address of the network card) could be separated from the network MAC address, (Apple clients generate a MAC address not linked to their true hardware one to avoid tracking) but still needs to be broadcast as part of the DNS_SD advertisement.

Still I see the advantages /simplicity of generating an immutable public key (+ private key) from the MAC address. uxplay now allows the MAC address to be specified in the startup file, so this would also fix the public key.

As released, uxplay-1.67 does not keep a record of clients that are registered, so if a client has recorded its registration with the server (recognized by the server public key and deviceID in the DNS_SD advertisement) it will skip the pair-setup-pin step and immediately issue a pair-verify request. In principle, uxplay could check the client's public key (sent with the pair-verify request) with a list of client registrations, if it kept one. Right now it doesn't keep records, and allows any client requesting pair-verify to proceed.

(pair-verify sets up an encrypted communication channel between client and server, but uxplay doesn't use it after it is set up and verified: I am unsure why this works, but it does, I think a true Apple TV would switch to fully-encrypted communications)

I presume a true AppleTV keeps records, but don't know if it really does. I have a trial version of uxplay that optionally keeps a list of previously-registered clients that it reads in at startup. (lists public key + deviceID) I want to add the device name (sent a bit later in the protocol) to this record so the admin could see what name the client was using, but I am not sure that such a security feature is particularly useful for uxplay. The problem with keeping records is to ensure the list doesn't grow too big.

Booth1983 commented 6 months ago

Okay... tuen I have to copy the pem to the Backup Files. No problem. :-)

fduncanh commented 6 months ago

@Booth1983 I have a new version in uxplay branch pin https://github.com/FDH2/UxPlay/tree/pin

which changes the default public key to one generated from the MAC address (which can be changed with option -m mac) After the v1.67 release, I saw that was what pair_ap used and it's cleaner and simpler (but less secure, if anyone cares)

Please test! It doesn't require the .uxplay.pem file

The pem file method is still available with the -key option.

(There is also a new -reg option to maintain a list of registered clients in $HOME/.uxplay.register or elsewhere; that probably is not useful for you unless it gets saved as a backup, if everything is erased at restart)

thiccaxe commented 6 months ago

Should the register file also note which server key the client paired against? And if the current server key has since changed, not consider that registered client entry as a "registered_client"?

fduncanh commented 6 months ago

The pin-pairing seems to be mainly to protect the client from pairing with the wrong server.

Here is a link to my write-up of the pin-pairing protocol in the wiki: https://github.com/FDH2/UxPlay/wiki/crypto#pair-verify-needed-each-time-a-rtsp-session-is-started

The client remembers the public keys of servers it has previously paired with. (In HomeKit pairing, it also apparently remembers the server DeviceID, but not in "Legacy Pairing")

The server broadcasts both its public key and DeviceID in the DNS_SD announcement. If the server requires pin-pairing, or if the client requires pin pairing, and the client recognizes the server public key as one it has previously paired with, it skips the pair-pin-start/pair-setup-pin steps and immediately initiates the pair-verify step that sets up a secure communication link (AES CTR 128) between server and client.

This strange thing about all this is that UxPlay already had implemented the pair-verify protocol which sets up encrypted communication, but doesn't use it after it has been verified. (The only thing I did was to add pair-setup-pin as an alternative to pair-setup). Is there some message needed to be sent to the client to make it switch to using encrypted communication after pair-verify is finished?

fduncanh commented 6 months ago

This should be fixed in the latest UxPlay v1.68, where (without the -key option) the ED25519 keypair is derived from the server's DeviceID (MAC address) and doesnt need to be stored in a file for persistence.