Open AirPlay 2 Receiver
github.com
github.com
"""
GPLv2
Python implementation by systemcrash 2022
Original C implementation of OmgHax by (credit to original author and Foxsen)
If you want this to work, don't touch anything. It's a steaming hot
rats nest of crypto mess which works. It's quite performant.
Resist the urge to refactor. :)
Avoid +=, -=, ^= etc operators in Garble: they don't account for overflow.
"""
before going into lovely detail, containing lines (e.g. in a method appropriately called Garble) such as buffer1[15] = ((3 * (((buffer1[72] >> (buffer4[buffer1[190] % 21] & 7)) ^ (buffer1[72] << ((7 - (buffer4[buffer1[190] % 21] - 1) & 7)))) - (3 * buffer4[buffer1[126] % 21]))) ^ buffer1[15]) & 0xff
print(f'buffer1[15]:{hex(buffer1[15])}')
Really, really hats off to whoever worked this out. I have no idea where you'd start.This method can have some legal risk attached to it (INAL).
In fact, it’s what I’ve done to reverse engineer the encryption for Zwift for example (and a ton of other apps)
The carve-outs for interoperability might be useful here though.
Edit: this explicitly does not support FairPlay DRM'd playback, so the lack of DRM carve-outs shouldn't matter, as awful as the lack of carve-outs is.
(Apple uses an obfuscation technique that converts functions into massive switch loops, threading a control variable through on which math is done to figure out the next block of code to switch-jump through; they then use a duality between the bitwise logic and algebraic rings to turn what might be one instruction into five instructions in a different order, and often broken up by the inverted looping. I believe--but am not sure, as most of my knowledge of this stuff is from trailblazing myself over the years... I wrote the first decompiler for .NET a couple decades ago and have done a lot of work in the iPhone jailbreaking ecosystem on static analysis and runtime modification--that the literature-searchable terms for these are "parameterized control flow flattening" and "mixed-boolean-arithmetic".)
So like, in some sense, this is not at all how someone else who understands how the algorithm works would implement it: it isn't like "oh yeah, there's one semi-obvious way to do it, and I did it that way", and one might definitely argue this is "creative".
(I've personally avoided ever just copying and redistributing--even in translated form--logic from Apple like this, and that's part of the reason. It might still be OK, due to some fair use -styled exemptions relating to software interoperability, but the only ones I explicitly know about are with relation to reverse engineering to obtain that interop, not the part where you directly copy the resulting logic instruction-by-instruction.)
But the resulting output is automatically produced by an obfuscator. There's no creative human involvement in the process itself of how the obfuscated code came to be. Hell, the Copyright Office wrote extensive articles on why AI art can't be copyrighted.
If one were to take a small sample out of a copyrighted binary which only implemented functionality and had no remains of the creative process behind it, I'd wager they would be in the clear.
That said, I feel like machine code copyrightability is questionable on its face. A packaged binary with resources and assets such as text would be, but the machine code itself is a more complicated issue. Admittedly this would jeopardize libraries, since they don't contain any expressive elements like interactive programs do.
This file is also interesting: https://github.com/openairplay/airplay2-receiver/blob/master...
In particular:
AIRPORT_PRIVATE_KEY = ( "-----BEGIN RSA PRIVATE KEY-----\n" "MIIEpQIBAAKCAQEA5..."
Is that intentional? Surely it is, being a public repo, etc.
[1] https://www.theiphonewiki.com/wiki/AirPlay
[2] https://www.google.com/search?q=MIIEpQIBAAKCAQEA59dE8qLieIts...
With DRM, since the data itself isn't secret (in fact you want to decode it at the end so you can play the media), the strength of the cryptography itself doesn't matter and the objective is to frustrate and slow down any reverse-engineering attempts, so homebrew cryptography may actually make sense here as to prevent usage of any common cryptographic libraries and force the reverse-engineers to implement it from scratch.
For example, if buffer1[72]=107343, buffer1[190] = 25, and buffer[4]=18 (buffer1[72] >> (buffer4[buffer1[190] % 21] & 7)) (buffer1[72] >> (buffer4[25 % 21] & 7)) (buffer1[72] >> (buffer4[4] & 7)) (buffer1[72] >> (18 & 7)) (107343 >> 10) 104
https://docs.python.org/3/reference/expressions.html#shiftin...
>> and << operators accept integers as arguments. They shift the first argument to the left or right by the number of bits given by the second argument
i = 14; // Bit pattern 00001110
j = i >> 1; // here we have the bit pattern shifted by 1 thus we get 00000111 = 7 which is 14/2
https://docs.python.org/3/reference/expressions.html#binary-... & operator yields the bitwise AND of its arguments (*If both bits are 1, the corresponding result bit is set to 1. Otherwise, the corresponding result bit is set to 0. so 1100 & 1010 is 1000*)
^ operator yields the bitwise XOR (exclusive OR) of its arguments (*so 0101 ^ 1111 is 1010*)
https://docs.python.org/3/tutorial/inputoutput.html#fancier-... To use formatted string literals, begin a string with f or F before the opening quotation mark or triple quotation mark. Inside this string, you can write a Python expression between { and } characters that can refer to variables or literal values.
Bitwise examples from:https://en.wikipedia.org/wiki/Bitwise_operations_in_C
https://docs.microsoft.com/en-us/cpp/cpp/bitwise-exclusive-o...
2 years ago, I bought some used Yamaha (not "smart") speakers and AVR. They are 8 years old now and work flawlessly. My solution to making them "smart" was to just Cast to my Android TV that's plugged into the AVR.
That entire set up cost me <$200 and has no end in sight with a very clean upgrade path. It's unfortunate that so much modern hardware is paperweight in a few years just because the company can't be bothered to maintain the software.
or open source it and let enthusiasts maintain it.
As I understand Airport Express models from the 2000s still work with AirPlay from modern Apple devices too, though I don’t own any and can’t vouch for them personally.
But if you only ever want to play to 1 device, then you're set.
Assuming you're okay with AirPlay (which, admittedly, rules a lot of HN folks out) this is a $20-per-room device that gives you full lossless multiroom streaming including your choice of analog or optical out. Really great.
Shame there’s nothing similar for video airplay.
Isn't there? You can pick up 3rd/4th gen AppleTVs on eBay for $20 all day long.Basically the issues as detailed here, though I had it more recently than the 7.6 software update: https://tidbits.com/2020/09/28/third-generation-apple-tvs-su...
My friend with a ~5 year old denon also has no problem. So possible this is a discontinued firmware issue. YMMV
My guess is that when the receiver is awoken by Airplay, it is then attempting to connect to the “Last Used” input (or something) which disconnects Airplay.
Can confirm. I stream from my iPhone to a 2012 Airport Express hooked up to the aux in of a Sony HD radio.
They still maintain an old S1 app for older devices and I think those devices should still all work. I don’t think there’s a plan to “turn them off”. A lack of new features is something that may or may not be a problem.
Actually, I think audio companies in general have been pretty good about keeping products alive. Even the old Amazon Echo Gen 1 I think still works… and that’s a full-on smart device that exists for the smarts not the audio quality.
Their current app now supports S1 devices as well.
I love my Arc system as a "point in time" purchase, but I don't have high trust in or loyalty to Sonos in general.
I have a record player (and DAC) and an amp and passive speakers. I have the full HiFi setup - the record player is setup to avoid vibrations and the speakers are properly distanced from the wall etc. I can tell you without any hesitation that the price-per-minute-listened of my Sonos system is a small fraction of the HiFi (which will last 30 years). If I upgrade the Sonos every decade I’m sure it’ll still “make sense”. That’s excluding the cost of media for which records cost a lot more than streaming. Personally, I think the Sonos sound “more than good enough” to enjoy without missing anything from the record player.
That said, I don’t love the generation of eWaste, and I hope the Sonos lasts for more than a decade. And every day that Amazon/google keep their smart speakers alive is a good day for eWaste. I can only dream they’ll allow you to update the firmware when they finally EOL them. (I know they won’t though).
Ironically (considering that you're using Yamaha) their MusicCast system have had a reasonable lifespan (seven years on the third generation, although they no longer support their 2003 stuff).
But yes, I'm looking at dabbling with HifiBerry (https://www.hifiberry.com/) for streaming duties for my older stereo gear.
https://github.com/jishi/node-sonos-http-api
This allows you to e.g. set the Sonos speakers to play any audio URI.
Low latency, linkplay, HTTP API, you can join multiple of them together for whole home audio. Integrates into Home Assistant. Can play random URLs, can play spotify, airplay, etc. Wifi, ethernet, bluetooth.
By far the best product I've found. What I like the most is that it plays whatever I throw at it and I can turn any speaker into a smart speaker. It's also all local.
“Now for the bad news. In the last 24 hours my network security blocked: 6,936 calls to AMS ("The Cloud"); 9,523 calls to s000.linkplay.com, 6,050 calls to www.yahoo.com; 6,050 calls to www.microsoft.com; 9,650 calls to Amazon Technologies; 6,049 calls to Aliyun Computing - Beijing China;3,468 calls to Google; That was 94% of the attempted connections outside of LAN.”
You can block those from your router and keep it all local and play MP3s if you like (or air play)
Companies often buy services based on cost. If the cost is less to get a server in Beijing, many will choose to get one there.
The country in which the server is located has little to do with the privacy or security posture of the service.
Their Great Firewall makes it a no-go for practically everything and everyone. At the best of times the latency and packet loss are hideous, with abysmal throughput. And then you get cut off randomly for hours, days, or decades at a time on the whim of random CCP members with no recourse.
Paying them is a giant pain in the arse as well.
It is quite literally never the best option.
Hosting sites in Russian — in the middle the current war — would make more sense!
Personally, I run my smart home fully locally, but it's interesting to me to see the geographic location of the server emphasized so strongly.
If you're in the western world, you really should consider avoiding IoT devices that call home to Chinese servers. You could be turning yourself into a potential botnet member if things go geopolitically sideways by keeping these products on your network. If you have access to other networks from home, you're inviting access into those networks from a box that should only be there for streaming music.
Better if things don't call home at all, but second best is choosing western servers under control of western actors.
I hope that one day we no longer have to consider the political origin of servers our devices to call back to, but that's a few years away at least. In the meantime, devices that call back to noone are still the best.
wherever the server is
* you're inviting access into those networks
wherever the server is
Unless maybe I set the sub as a second airplay or Bluetooth device and run one of these [1]? I’m not really sure how all of that works.
For use with higher-quality bookshelf speakers, you can send the stereo line level signal to a 2-channel amp and pass the high-level speaker lines through your sub. I do this with Belkin AirPlay 2 receivers and it works well.
Not all subs have high-level passthrough though.
https://www.daytonaudio.com/product/776/sa70-70w-subwoofer-p...
I love this project, but for folks who use MacOS and want something that simply works, I can't recommend Airfoil highly enough.
Apple doesn't have AirPlay licensing for software products, just for hardware.
Not quite; Airfoil Satellite does not implement an AirPlay 2 receiver which is what this is all about. See https://weblog.rogueamoeba.com/2018/06/25/current-notes-on-a... :
> Can Airfoil Satellite receive AirPlay 2 audio? Airfoil Satellite receives audio via the AirPlay 1 protocol. Because of this, it can’t currently be part of a multi-speaker group receiving audio from iOS.
Still a great piece of software (that I also can recommend).
shairport-sync had it long brewing, I think it's currently still in a dev branch but does work to some extent.
https://github.com/mikebrady/shairport-sync/issues/535#issue...
EDIT: details here https://github.com/mikebrady/shairport-sync/blob/development...
I’m trying to avoid a bulky receiver and want something more custom, with the option to turn the sub off digitally.
Damn... that took a lot longer to extract the keys that AirPlay 1 did. I'd love to know more about this story.
Someone had already extracted the key which was used to encrypt the firmware, so you could download the firmware from Apple and look at the unencrypted firmware blob.
Perhaps even boot it using something like QEMU? But I never got anywhere with that...
This new app looks like a promising cross-platform replacement.
with open("data.dat", "ab") as f:
f.write(frame.planes[0].to_bytes())
in Audio's process() does indeed dump out the captured data to something that can be replayed.