openairplay / airplay2-receiver

AirPlay 2 Receiver - Python implementation
2.13k stars 133 forks source link

Not compatible with this version of iTunes #12

Open Neustradamus opened 3 years ago

Neustradamus commented 3 years ago

Originally: https://github.com/ckdo/airplay2-receiver/issues/2

@joerg-krause commented Jun 22, 2020

The FairPlay authentification works fine with iOS, but fails with iTunes: The AirPlay device "myap2" is not compatible with this version of iTunes.

Something i noticed: iTunes sends an OPTION request with an "Apple-Challenge".

@ckdo commented Jun 22, 2020

@joerg-krause Which version iTunes do you use ? Apple-Challenge refers to RSA Authentication, which is not allowed for AP2

@joerg-krause commented Jun 22, 2020

iTunes version is 12.10.7.3. This is the log:

$ python ap2-receiver.py -m myap2 -n wlp5s0 Interface: wlp5s0 IPv4: 192.168.178.118 IPv6: fd00::89a1:4d7b:fa87:7be0

mDNS service registered Starting RSTP server, press Ctrl-C to exit... serving at port 7000 Got connection with 192.168.178.33:49339 CSeq: 1 User-Agent: iTunes/12.10.7 (Windows; Microsoft Windows 7 Service Pack 1 x64 Professional Edition (Build 7601); x64) (dt:2) Client-Instance: 8E6AFF7283B34602 DACP-ID: 8E6AFF7283B34602 Active-Remote: 222309246 Apple-Challenge: 3zeVCckh56X+LikSee2wQg

@ckdo commented Jun 22, 2020

Thanks @joerg-krause , Windows version of iTunes does not support FairPlay authentication. It either uses RSA authentication (regular raop devices) or MFi authentication with AP2 devices. I don't know if windows version of iTunes can accept RSA authentication for AP2 (mac version/ios devices does not), and I was actually interested in checking that (branch-RSA..) but it is still pending work.

@joerg-krause commented Jun 22, 2020 •

Thanks @ckdo for sharing the RSA branch. Actually, iTunes on Windows does support FairPlay v2 authentication. I've tested in by advertising the AP2 device as an AP1 device using only the _raop._tcp service. However, if I re-enable the _airplay._tcp service, iTunes sends the "Apple-Challenge" in the OPTIONS request stead of sending an fp-setup request.

@ckdo commented Jun 23, 2020 •

@joerg-krause RSA branch is updated to compute Apple-Response correctly. Apple-Response is accepted for _raop._tcp service, but for _airplay._tcp the dialog is stopping, so I guess RSA auth cannot be used on AP2 devices. In addition, windows version does not seems to support real Airplay2, protocol used is raop (ANNOUNCE for instance does not exist anymore with AP2 protocol) with previous MFi authentication.

@joerg-krause commented Jun 24, 2020

Thanks @ckdo ! I wonder, why iTunes on Windows sends the Apple-Challenge. What authentication algorithm does it expect, if not RSA? Looks like an unsolved mystery for now...

@joerg-krause commented Jul 3, 2020 •

@ckdo I managed to get iTunes on Windows to try to connect with the AirPlay 2 receiver using FairPlay v2. The features needs to be set to 0x3004A5D5A00 (The magic bit in the features is bit 25). iTunes needs several seconds before it sends the fp-setup request (so I guess some settings are not optimal yet):

Got connection with 192.168.178.136:49791 CSeq: 1 Content-Type: application/octet-stream Content-Length: 16 User-Agent: iTunes/12.10.7 (Windows; Microsoft Windows 10 x64 Professional Edition (Build 19041); x64) (dt:2) Client-Instance: 61A9F4C15E5B4DD7 DACP-ID: 61A9F4C15E5B4DD7 Active-Remote: 616789066

POST /fp-setup 00000000: 46 50 4C 59 02 01 01 00 00 00 00 04 02 00 00 BB FPLY............

As you can see, the fifth byte send in the request is 02, which is FairPlay v2. As the current code only implements FairPlay v3, further processing fails with an exception...

@ckdo commented Jul 3, 2020 •

Interesting findings ! Once authenticated, unfortunately it will not use Airplay2 protocol: 192.168.128.227 - - [03/Jul/2020 15:58:49] code 501, message Unsupported method ('ANNOUNCE')

Like said in this case ANNOUNCE method is used, so it means raop/ap1. But... it can be interesting to know that for instance to ensure backward compatibility with ap1 with a device publishing only a _airplay._tcp service.

@joerg-krause commented Jul 5, 2020

The ANNOUNCE method is advertised as supported method in the OPTIONS request even in AP2 devices. What makes you think the ANNOUNCE is an AP1 method?

@ckdo commented Jul 5, 2020

Yes so that AP2 devices ensure AP1 backward compatibility since there is one single enpoint for both protocols. Invano documented the methods used for AP2 here: https://emanuelecozzi.net/docs/airplay2/protocols

You can also quite easily check rtsp streams with a tcpdump since for iTunes/Windows they are not encrypted.

@joerg-krause commented Jul 6, 2020 •

I see!

As I am far more experienced with C than with Python, I fiddled around with the FairPlay v2 feature using shairplay. This is my experimental FP2 branch: https://github.com/joerg-krause/shairplay/tree/fairplay_v2.

iTunes on Windows successfully connects to the AirPlay device, but shairport aborts, while buffering. Something is wrong with the audio decryption. Maybe the audio is not encrypted using AES 128 CBC?

I hope, that adding FairPlay v2 support can be used as a backward compatibility for iTunes on Windows...

@ckdo commented Jul 6, 2020 •

Nice work I will check that... about encryption with Fairplayv2 I don't know but with MFi auth there's no particular change with encryption. Actually my initial goal for this project is to understand the "player" part of AP2... to implement in pulseaudio ( https://gitlab.freedesktop.org/pulseaudio/pulseaudio/-/merge_requests/194 ), with all benefits of AP2 and not only in AP1 compatibility mode as this MR does. So having "C" contributions is very welcome :)

@ckdo commented Jul 6, 2020 •

Is your latest code pushed onto shairplay branch ? There are several points I don't understand (only fply_2 is used, fply_header and payload are not used in response)

@joerg-krause commented Jul 6, 2020

The branch is named fairplay_v2. It is a single commit joerg-krause/shairplay@d5f0953. fply_header and fply_2 are used in fairplay_setup().

@ckdo commented Jul 6, 2020 •

Yes, but I mean there https://github.com/joerg-krause/shairplay/blob/d5f0953d2380502366592e30a0a59fe3879f3c59/src/lib/fairplay_playfair.c#L93-L97 : res only rely on fply_2, which does not use neither fply_header nor payload . Is it normal ?

@joerg-krause commented Jul 10, 2020

You're right! The reply needs to be distinguished whether by the request data. Depending on one byte set in the request, the header and payload data are needed for the response. That part is missing. I will add it soon, right now I am quite busy. Thanks for looking into it!

@joerg-krause commented Jul 20, 2020 •

Update: The missing part is not relevant for the fairplay v2 handshake. The main problem seems to be the decryption. I guess, there is a difference between v2 and v3 decryption.

I think the best approach is to use legacy RSA, for iTunes on Windows.

EDIT: RSA is only working when using the _raop._tcp bonjour service. When using the _airplay,_tcp service, it fails. However, if I first use the _raop._tcp service to connect iTunes on Windows with the AP device and then restart AP with the _airplay._tcp service instead of _raop._tcp, the authentification works, too.