]> git.ipfire.org Git - thirdparty/shairport-sync.git/commitdiff
Update pair_ap to 0.7 (fixes incorrect pair-list response)
authorejurgensen <espenjurgensen@gmail.com>
Tue, 13 Jul 2021 20:28:34 +0000 (22:28 +0200)
committerejurgensen <espenjurgensen@gmail.com>
Tue, 13 Jul 2021 20:28:34 +0000 (22:28 +0200)
pair_ap/README.md
pair_ap/pair.h
pair_ap/pair_homekit.c

index 1c855444c5763c15aab7372e546e52574b6fe253..d6b00d654bea2ae448ea13160ff10f02ccdf7c93 100644 (file)
@@ -2,9 +2,10 @@
 C client implementation of pairing for:
 * Apple TV device verification, which became mandatory with tvOS 10.2 (this is
   called fruit mode in pair_ap)
-* Homekit pairing (for AirPlay 2, not working for Home app)
+* Homekit pairing (also for AirPlay 2)
 
 Credit goes to @funtax and @ViktoriiaKh for doing some of the heavy lifting.
+
 ## Requirements
 - libsodium
 - libgcrypt or libopenssl
@@ -33,7 +34,7 @@ The controller uses `/pair-add` to make sure that all devices on a network get
 the ID and public key of all the other devices, so that the user only needs to
 pair a device once.
 
-### Normal pairing
+### Normal pairing with one-time code
 For a normal first-time pairing, the client needs a one-time code (the device
 announces via mDNS whether a code is required). The client calls
 `/pair-pin-start` and the device displays the code. There is also QR-based
@@ -42,12 +43,12 @@ pairing, which is (probably?) an encoded code.
 After obtaining the code, the client initiates a three step `/pair-setup`
 sequence, which results in both peers registering each other's ID and public
 key. Henceforth, a pairing is verified with the two step `/pair-verify`, where
-the parties check each-others identify. Saving the peer's ID + public key isn't
+the parties check eachothers identify. Saving the peer's ID + public key isn't
 strictly necessary if client or server doesn't care about verifying the peer,
 i.e. that `/pair-setup` has actually been completed.
 
 The result of `/pair-verify` is a shared secret that is used for symmetric
-encryption of the following communinacation between the parties.
+encryption of the following communication between the parties.
 
 ### Transient pairing
 Some devices don't require a code from the user for pairing (e.g. an Airport
@@ -55,8 +56,7 @@ Express 2). If so, the client just needs to go through a two-step `/pair-setup`
 sequence which results in a shared secret, which is then used for encrypted
 communication. A fixed code of 3939 is used.
 
-Such devices don't appear to be fully Homekit compatible - they will not, for
-instance - appear in the Home app.
+The controller can still use `/pair-add` etc. towards such devices.
 
 ## "fruit" pairing
 Like normal Homekit pairing, this consists of first requesting a code with
@@ -69,4 +69,5 @@ shared secret.
 - [AirPlayAuth](https://github.com/funtax/AirPlayAuth)
 - [AirPlayAuth-ObjC](https://github.com/ViktoriiaKh/AirPlayAuth-ObjC)
 - [ap2-sender](https://github.com/ViktoriiaKh/ap2-sender)
+- [airplay2-receiver](https://github.com/ckdo/airplay2-receiver)
 - [csrp](https://github.com/cocagne/csrp)
index 6324bc156e269ece65b7774aa5caa760befcdcc2..37f85b4ed679199cb50d70318b810de845b48aac 100644 (file)
@@ -4,7 +4,7 @@
 #include <stdint.h>
 
 #define PAIR_AP_VERSION_MAJOR 0
-#define PAIR_AP_VERSION_MINOR 5
+#define PAIR_AP_VERSION_MINOR 7
 
 #define PAIR_AP_DEVICE_ID_LEN_MAX 64
 
index 076ea14a7f010079756abde9ebe378eb4b939c86..f875d237e5a2c7e3e123427392007063f8ccc3b7 100644 (file)
@@ -2679,6 +2679,7 @@ server_add_remove_request(pair_cb cb, void *cb_arg, const uint8_t *in, size_t in
   pair_tlv_t *device_id;
   pair_tlv_t *pk;
   char id_str[PAIR_AP_DEVICE_ID_LEN_MAX] = { 0 };
+  uint8_t *public_key = NULL;
 
   request = message_process(in, in_len, &errmsg);
   if (!request)
@@ -2687,15 +2688,21 @@ server_add_remove_request(pair_cb cb, void *cb_arg, const uint8_t *in, size_t in
     }
 
   device_id = pair_tlv_get_value(request, TLVType_Identifier);
-  pk = pair_tlv_get_value(request, TLVType_PublicKey);
-  if (!device_id || device_id->size >= sizeof(id_str) || !pk || pk->size != crypto_sign_PUBLICKEYBYTES)
+  if (!device_id || device_id->size >= sizeof(id_str))
     {
       goto error;
     }
 
+  // Only present when adding
+  pk = pair_tlv_get_value(request, TLVType_PublicKey);
+  if (pk && pk->size == crypto_sign_PUBLICKEYBYTES)
+    {
+      public_key = pk->value;
+    }
+
   memcpy(id_str, device_id->value, device_id->size);
 
-  cb(pk->value, id_str, cb_arg);
+  cb(public_key, id_str, cb_arg);
 
   pair_tlv_free(request);
   return 0;
@@ -2757,9 +2764,12 @@ static int
 server_list_cb(uint8_t public_key[crypto_sign_PUBLICKEYBYTES], const char *device_id, void *cb_arg)
 {
   pair_tlv_values_t *response = cb_arg;
+  uint8_t permissions = 1; // Means admin (TODO don't hardcode - let caller set)
 
   pair_tlv_add_value(response, TLVType_Identifier, (unsigned char *)device_id, strlen(device_id));
   pair_tlv_add_value(response, TLVType_PublicKey, public_key, crypto_sign_PUBLICKEYBYTES);
+  pair_tlv_add_value(response, TLVType_Permissions, &permissions, sizeof(permissions));
+
   return 0;
 }