summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorGravatar Martin Szulecki2013-08-18 05:28:53 +0200
committerGravatar Martin Szulecki2013-09-17 11:43:33 +0200
commitec720cc1c30ac3f9b7996575e835565f60ce2b3e (patch)
treef92476e06ce36ab56348544fb9ae614ec10d904c /src
parent36e636a727ecbae7083878ceb493b26046a47179 (diff)
downloadlibimobiledevice-ec720cc1c30ac3f9b7996575e835565f60ce2b3e.tar.gz
libimobiledevice-ec720cc1c30ac3f9b7996575e835565f60ce2b3e.tar.bz2
Refactor userpref logic to use plist format and implement trust dialog handling
iOS 7 introduced a new pairing workflow which increases security by showing a trust dialog to the user before pairing with the host is allowed. The userpref system was refactored to use the native plist format, too. Configuration files of the native implementations are used on each platform. Former configuration files are no longer in use and can be deleted.
Diffstat (limited to 'src')
-rw-r--r--src/idevice.c2
-rw-r--r--src/lockdown.c257
-rw-r--r--src/lockdown.h4
3 files changed, 214 insertions, 49 deletions
diff --git a/src/idevice.c b/src/idevice.c
index c605da3..4a6f544 100644
--- a/src/idevice.c
+++ b/src/idevice.c
@@ -668,7 +668,7 @@ idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection)
668 key_data_t root_cert = { NULL, 0 }; 668 key_data_t root_cert = { NULL, 0 };
669 key_data_t root_privkey = { NULL, 0 }; 669 key_data_t root_privkey = { NULL, 0 };
670 670
671 userpref_error_t uerr = userpref_get_keys_and_certs(&root_privkey, &root_cert, NULL, NULL); 671 userpref_error_t uerr = userpref_device_record_get_keys_and_certs(connection->udid, &root_privkey, &root_cert, NULL, NULL);
672 if (uerr != USERPREF_E_SUCCESS) { 672 if (uerr != USERPREF_E_SUCCESS) {
673 debug_info("Error %d when loading keys and certificates! %d", uerr); 673 debug_info("Error %d when loading keys and certificates! %d", uerr);
674 } 674 }
diff --git a/src/lockdown.c b/src/lockdown.c
index b07366b..7c516c1 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -30,6 +30,7 @@
30#define __USE_GNU 1 30#define __USE_GNU 1
31#include <stdio.h> 31#include <stdio.h>
32#include <ctype.h> 32#include <ctype.h>
33#include <unistd.h>
33#ifdef HAVE_OPENSSL 34#ifdef HAVE_OPENSSL
34#include <openssl/pem.h> 35#include <openssl/pem.h>
35#include <openssl/x509.h> 36#include <openssl/x509.h>
@@ -47,6 +48,11 @@
47#include "common/userpref.h" 48#include "common/userpref.h"
48#include "asprintf.h" 49#include "asprintf.h"
49 50
51#ifdef WIN32
52#include <windows.h>
53#define sleep(x) Sleep(x*1000)
54#endif
55
50#define RESULT_SUCCESS 0 56#define RESULT_SUCCESS 0
51#define RESULT_FAILURE 1 57#define RESULT_FAILURE 1
52 58
@@ -209,28 +215,18 @@ lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char *
209 return ret; 215 return ret;
210} 216}
211 217
212/** 218static lockdownd_error_t lockdownd_client_free_simple(lockdownd_client_t client)
213 * Closes the lockdownd client session if one is running and frees up the
214 * lockdownd_client struct.
215 *
216 * @param client The lockdown client
217 *
218 * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
219 */
220lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
221{ 219{
222 if (!client) 220 if (!client)
223 return LOCKDOWN_E_INVALID_ARG; 221 return LOCKDOWN_E_INVALID_ARG;
222
224 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; 223 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
225 224
226 if (client->session_id) { 225 if (client->session_id) {
227 lockdownd_stop_session(client, client->session_id);
228 free(client->session_id); 226 free(client->session_id);
229 } 227 }
230 228
231 if (client->parent) { 229 if (client->parent) {
232 lockdownd_goodbye(client);
233
234 if (property_list_service_client_free(client->parent) == PROPERTY_LIST_SERVICE_E_SUCCESS) { 230 if (property_list_service_client_free(client->parent) == PROPERTY_LIST_SERVICE_E_SUCCESS) {
235 ret = LOCKDOWN_E_SUCCESS; 231 ret = LOCKDOWN_E_SUCCESS;
236 } 232 }
@@ -244,6 +240,36 @@ lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
244 } 240 }
245 241
246 free(client); 242 free(client);
243
244 return ret;
245}
246
247/**
248 * Closes the lockdownd client session if one is running and frees up the
249 * lockdownd_client struct.
250 *
251 * @param client The lockdown client
252 *
253 * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
254 */
255lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
256{
257 if (!client)
258 return LOCKDOWN_E_INVALID_ARG;
259
260 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
261
262
263 if (client->session_id) {
264 lockdownd_stop_session(client, client->session_id);
265 }
266
267 if (client->parent) {
268 lockdownd_goodbye(client);
269 }
270
271 ret = lockdownd_client_free_simple(client);
272
247 return ret; 273 return ret;
248} 274}
249 275
@@ -674,6 +700,33 @@ lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *cli
674 return LOCKDOWN_E_SUCCESS; 700 return LOCKDOWN_E_SUCCESS;
675} 701}
676 702
703static lockdownd_error_t lockdownd_client_reconnect(idevice_t device, lockdownd_client_t *client, const char *label)
704{
705 lockdownd_error_t ret = LOCKDOWN_E_SUCCESS;
706 int attempts = 3;
707 char *udid = NULL;
708
709 /* free resources of lockownd_client */
710 ret = lockdownd_client_free_simple(*client);
711 *client = NULL;
712
713 /* try to reconnect */
714 do {
715 debug_info("reconnecting to udid %s, %d remaining attempts", udid, attempts);
716 ret = lockdownd_client_new(device, client, label);
717 if (ret == LOCKDOWN_E_SUCCESS) {
718 debug_info("reconnected to lockdownd with err %d", ret);
719 break;
720 }
721 sleep(1);
722 } while(attempts--);
723
724 free(udid);
725 udid = NULL;
726
727 return ret;
728}
729
677/** 730/**
678 * Creates a new lockdownd client for the device and starts initial handshake. 731 * Creates a new lockdownd client for the device and starts initial handshake.
679 * The handshake consists out of query_type, validate_pair, pair and 732 * The handshake consists out of query_type, validate_pair, pair and
@@ -698,8 +751,10 @@ lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdown
698 751
699 lockdownd_error_t ret = LOCKDOWN_E_SUCCESS; 752 lockdownd_error_t ret = LOCKDOWN_E_SUCCESS;
700 lockdownd_client_t client_loc = NULL; 753 lockdownd_client_t client_loc = NULL;
754 char *system_buid = NULL;
701 char *host_id = NULL; 755 char *host_id = NULL;
702 char *type = NULL; 756 char *type = NULL;
757 int product_version_major = 0;
703 758
704 ret = lockdownd_client_new(device, &client_loc, label); 759 ret = lockdownd_client_new(device, &client_loc, label);
705 if (LOCKDOWN_E_SUCCESS != ret) { 760 if (LOCKDOWN_E_SUCCESS != ret) {
@@ -719,22 +774,55 @@ lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdown
719 free(type); 774 free(type);
720 } 775 }
721 776
722 userpref_get_host_id(&host_id); 777 /* get product version */
778 plist_t product_version_node = NULL;
779 char* product_version = NULL;
780 lockdownd_get_value(client_loc, NULL, "ProductVersion", &product_version_node);
781 if (product_version_node && plist_get_node_type(product_version_node) == PLIST_STRING) {
782 plist_get_string_val(product_version_node, &product_version);
783 product_version_major = strtol(product_version, NULL, 10);
784 }
785
786 if (product_version_major >= 7) {
787 userpref_get_system_buid(&system_buid);
788
789 /* set our BUID for the trust dialog so the next pairing can succeed */
790 lockdownd_set_value(client_loc, NULL, "UntrustedHostBUID", plist_new_string(system_buid));
791 free(system_buid);
792 system_buid = NULL;
793 }
794
795 userpref_device_record_get_host_id(client_loc->udid, &host_id);
723 if (LOCKDOWN_E_SUCCESS == ret && !host_id) { 796 if (LOCKDOWN_E_SUCCESS == ret && !host_id) {
724 ret = LOCKDOWN_E_INVALID_CONF; 797 ret = LOCKDOWN_E_INVALID_CONF;
725 } 798 }
726 799
727 if (LOCKDOWN_E_SUCCESS == ret && !userpref_has_device_public_key(client_loc->udid)) 800 if (LOCKDOWN_E_SUCCESS == ret && !userpref_has_device_record(client_loc->udid)) {
801 /* attempt pairing */
728 ret = lockdownd_pair(client_loc, NULL); 802 ret = lockdownd_pair(client_loc, NULL);
729 803
804 if (ret == LOCKDOWN_E_SUCCESS && product_version_major >= 7) {
805 /* the trust dialog was dissmissed, thus the device will reconnect after pairing */
806 lockdownd_client_reconnect(device, &client_loc, label);
807 }
808 }
809
730 /* in any case, we need to validate pairing to receive trusted host status */ 810 /* in any case, we need to validate pairing to receive trusted host status */
731 ret = lockdownd_validate_pair(client_loc, NULL); 811 ret = lockdownd_validate_pair(client_loc, NULL);
732 812
733 /* if not paired yet, let's do it now */ 813 /* if not paired yet, let's do it now */
734 if (LOCKDOWN_E_INVALID_HOST_ID == ret) { 814 if (LOCKDOWN_E_INVALID_HOST_ID == ret) {
735 ret = lockdownd_pair(client_loc, NULL); 815 ret = lockdownd_pair(client_loc, NULL);
816
817 if (ret == LOCKDOWN_E_SUCCESS && product_version_major >= 7) {
818 /* the trust dialog was dissmissed, thus the device will reconnect after pairing */
819 lockdownd_client_reconnect(device, &client_loc, label);
820 }
821
736 if (LOCKDOWN_E_SUCCESS == ret) { 822 if (LOCKDOWN_E_SUCCESS == ret) {
737 ret = lockdownd_validate_pair(client_loc, NULL); 823 ret = lockdownd_validate_pair(client_loc, NULL);
824 } else if (LOCKDOWN_E_PAIRING_DIALOG_PENDING == ret) {
825 debug_info("Device shows the pairing dialog.");
738 } 826 }
739 } 827 }
740 828
@@ -772,19 +860,13 @@ static plist_t lockdownd_pair_record_to_plist(lockdownd_pair_record_t pair_recor
772 if (!pair_record) 860 if (!pair_record)
773 return NULL; 861 return NULL;
774 862
775 char *host_id_loc = pair_record->host_id;
776
777 /* setup request plist */ 863 /* setup request plist */
778 plist_t dict = plist_new_dict(); 864 plist_t dict = plist_new_dict();
779 plist_dict_insert_item(dict, "DeviceCertificate", plist_new_data(pair_record->device_certificate, strlen(pair_record->device_certificate))); 865 plist_dict_insert_item(dict, "DeviceCertificate", plist_new_data(pair_record->device_certificate, strlen(pair_record->device_certificate)));
780 plist_dict_insert_item(dict, "HostCertificate", plist_new_data(pair_record->host_certificate, strlen(pair_record->host_certificate))); 866 plist_dict_insert_item(dict, "HostCertificate", plist_new_data(pair_record->host_certificate, strlen(pair_record->host_certificate)));
781 if (!pair_record->host_id) 867 plist_dict_insert_item(dict, "HostID", plist_new_string(pair_record->host_id));
782 userpref_get_host_id(&host_id_loc);
783 plist_dict_insert_item(dict, "HostID", plist_new_string(host_id_loc));
784 plist_dict_insert_item(dict, "RootCertificate", plist_new_data(pair_record->root_certificate, strlen(pair_record->root_certificate))); 868 plist_dict_insert_item(dict, "RootCertificate", plist_new_data(pair_record->root_certificate, strlen(pair_record->root_certificate)));
785 869 plist_dict_insert_item(dict, "SystemBUID", plist_new_string(pair_record->system_buid));
786 if (!pair_record->host_id)
787 free(host_id_loc);
788 870
789 return dict; 871 return dict;
790} 872}
@@ -800,7 +882,7 @@ static plist_t lockdownd_pair_record_to_plist(lockdownd_pair_record_t pair_recor
800 * 882 *
801 * @return LOCKDOWN_E_SUCCESS on success 883 * @return LOCKDOWN_E_SUCCESS on success
802 */ 884 */
803static lockdownd_error_t generate_pair_record_plist(key_data_t public_key, char *host_id, plist_t *pair_record_plist) 885static lockdownd_error_t generate_pair_record_plist(const char *udid, char* system_buid, char *host_id, key_data_t public_key, plist_t *pair_record_plist)
804{ 886{
805 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; 887 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
806 888
@@ -808,25 +890,18 @@ static lockdownd_error_t generate_pair_record_plist(key_data_t public_key, char
808 key_data_t host_cert = { NULL, 0 }; 890 key_data_t host_cert = { NULL, 0 };
809 key_data_t root_cert = { NULL, 0 }; 891 key_data_t root_cert = { NULL, 0 };
810 892
811 ret = lockdownd_gen_pair_cert(public_key, &device_cert, &host_cert, &root_cert); 893 ret = lockdownd_gen_pair_cert_for_udid(udid, public_key, &device_cert, &host_cert, &root_cert);
812 if (ret != LOCKDOWN_E_SUCCESS) { 894 if (ret != LOCKDOWN_E_SUCCESS) {
813 return ret; 895 return ret;
814 } 896 }
815 897
816 char *host_id_loc = host_id;
817
818 if (!host_id)
819 userpref_get_host_id(&host_id_loc);
820
821 /* setup request plist */ 898 /* setup request plist */
822 *pair_record_plist = plist_new_dict(); 899 *pair_record_plist = plist_new_dict();
823 plist_dict_insert_item(*pair_record_plist, "DeviceCertificate", plist_new_data((const char*)device_cert.data, device_cert.size)); 900 plist_dict_insert_item(*pair_record_plist, "DeviceCertificate", plist_new_data((const char*)device_cert.data, device_cert.size));
824 plist_dict_insert_item(*pair_record_plist, "HostCertificate", plist_new_data((const char*)host_cert.data, host_cert.size)); 901 plist_dict_insert_item(*pair_record_plist, "HostCertificate", plist_new_data((const char*)host_cert.data, host_cert.size));
825 plist_dict_insert_item(*pair_record_plist, "HostID", plist_new_string(host_id_loc)); 902 plist_dict_insert_item(*pair_record_plist, "HostID", plist_new_string(host_id));
826 plist_dict_insert_item(*pair_record_plist, "RootCertificate", plist_new_data((const char*)root_cert.data, root_cert.size)); 903 plist_dict_insert_item(*pair_record_plist, "RootCertificate", plist_new_data((const char*)root_cert.data, root_cert.size));
827 904 plist_dict_insert_item(*pair_record_plist, "SystemBUID", plist_new_string(system_buid));
828 if (!host_id)
829 free(host_id_loc);
830 905
831 if (device_cert.data) 906 if (device_cert.data)
832 free(device_cert.data); 907 free(device_cert.data);
@@ -863,8 +938,10 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_
863 plist_t dict_record = NULL; 938 plist_t dict_record = NULL;
864 key_data_t public_key = { NULL, 0 }; 939 key_data_t public_key = { NULL, 0 };
865 int pairing_mode = 0; /* 0 = libimobiledevice, 1 = external */ 940 int pairing_mode = 0; /* 0 = libimobiledevice, 1 = external */
941 char* host_id = NULL;
942 char* system_buid = NULL;
866 943
867 if (pair_record && pair_record->host_id) { 944 if (pair_record && pair_record->system_buid && pair_record->host_id) {
868 /* valid pair_record passed? */ 945 /* valid pair_record passed? */
869 if (!pair_record->device_certificate || !pair_record->host_certificate || !pair_record->root_certificate) { 946 if (!pair_record->device_certificate || !pair_record->host_certificate || !pair_record->root_certificate) {
870 return LOCKDOWN_E_PLIST_ERROR; 947 return LOCKDOWN_E_PLIST_ERROR;
@@ -883,34 +960,73 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_
883 return ret; 960 return ret;
884 } 961 }
885 debug_info("device public key follows:\n%.*s", public_key.size, public_key.data); 962 debug_info("device public key follows:\n%.*s", public_key.size, public_key.data);
963
886 /* get libimobiledevice pair_record */ 964 /* get libimobiledevice pair_record */
887 ret = generate_pair_record_plist(public_key, NULL, &dict_record); 965 userpref_get_system_buid(&system_buid);
966 userpref_device_record_get_host_id(client->udid, &host_id);
967 userpref_device_record_set_value(client->udid, USERPREF_SYSTEM_BUID_KEY, plist_new_string(system_buid));
968
969 ret = generate_pair_record_plist(client->udid, system_buid, host_id, public_key, &dict_record);
970
971 if (host_id)
972 free(host_id);
973 if (system_buid)
974 free(system_buid);
975
888 if (ret != LOCKDOWN_E_SUCCESS) { 976 if (ret != LOCKDOWN_E_SUCCESS) {
977 if (public_key.data)
978 free(public_key.data);
889 if (dict_record) 979 if (dict_record)
890 plist_free(dict_record); 980 plist_free(dict_record);
891 return ret; 981 return ret;
892 } 982 }
893 } 983 }
894 984
895 /* Setup Pair request plist */ 985 if (!strcmp("Pair", verb)) {
986 /* get wifi mac */
987 plist_t wifi_mac_node = NULL;
988 lockdownd_get_value(client, NULL, "WiFiAddress", &wifi_mac_node);
989
990 /* save wifi mac address in config */
991 if (wifi_mac_node) {
992 userpref_device_record_set_value(client->udid, USERPREF_WIFI_MAC_ADDRESS_KEY, plist_copy(wifi_mac_node));
993 plist_free(wifi_mac_node);
994 wifi_mac_node = NULL;
995 }
996 }
997
998 /* setup pair request plist */
896 dict = plist_new_dict(); 999 dict = plist_new_dict();
897 plist_dict_add_label(dict, client->label); 1000 plist_dict_add_label(dict, client->label);
898 plist_dict_insert_item(dict,"PairRecord", dict_record); 1001 plist_dict_insert_item(dict, "PairRecord", plist_copy(dict_record));
899 plist_dict_insert_item(dict, "Request", plist_new_string(verb)); 1002 plist_dict_insert_item(dict, "Request", plist_new_string(verb));
1003 plist_dict_insert_item(dict, "ProtocolVersion", plist_new_string(LOCKDOWN_PROTOCOL_VERSION));
1004
1005 plist_t options = plist_new_dict();
1006 plist_dict_insert_item(options, "ExtendedPairingErrors", plist_new_bool(1));
1007 plist_dict_insert_item(dict, "PairingOptions", options);
900 1008
901 /* send to device */ 1009 /* send to device */
902 ret = lockdownd_send(client, dict); 1010 ret = lockdownd_send(client, dict);
903 plist_free(dict); 1011 plist_free(dict);
904 dict = NULL; 1012 dict = NULL;
905 1013
906 if (ret != LOCKDOWN_E_SUCCESS) 1014 if (ret != LOCKDOWN_E_SUCCESS) {
1015 if (public_key.data)
1016 free(public_key.data);
1017 plist_free(dict_record);
907 return ret; 1018 return ret;
1019 }
908 1020
909 /* Now get device's answer */ 1021 /* Now get device's answer */
910 ret = lockdownd_receive(client, &dict); 1022 ret = lockdownd_receive(client, &dict);
911 1023
912 if (ret != LOCKDOWN_E_SUCCESS) 1024 if (ret != LOCKDOWN_E_SUCCESS) {
1025 if (public_key.data)
1026 free(public_key.data);
1027 plist_free(dict_record);
913 return ret; 1028 return ret;
1029 }
914 1030
915 if (strcmp(verb, "Unpair") == 0) { 1031 if (strcmp(verb, "Unpair") == 0) {
916 /* workaround for Unpair giving back ValidatePair, 1032 /* workaround for Unpair giving back ValidatePair,
@@ -928,13 +1044,25 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_
928 if (ret == LOCKDOWN_E_SUCCESS) { 1044 if (ret == LOCKDOWN_E_SUCCESS) {
929 debug_info("%s success", verb); 1045 debug_info("%s success", verb);
930 if (!pairing_mode) { 1046 if (!pairing_mode) {
1047 debug_info("internal pairing mode");
931 if (!strcmp("Unpair", verb)) { 1048 if (!strcmp("Unpair", verb)) {
932 /* remove public key from config */ 1049 /* remove public key from config */
933 userpref_remove_device_public_key(client->udid); 1050 userpref_remove_device_record(client->udid);
934 } else { 1051 } else {
935 /* store public key in config */ 1052 if (!strcmp("Pair", verb)) {
936 userpref_set_device_public_key(client->udid, public_key); 1053 debug_info("getting EscrowBag from response");
1054
1055 /* add returned escrow bag if available */
1056 plist_t escrow_bag = plist_dict_get_item(dict, "EscrowBag");
1057 if (escrow_bag && plist_get_node_type(escrow_bag) == PLIST_DATA) {
1058 userpref_device_record_set_value(client->udid, USERPREF_ESCROW_BAG_KEY, plist_copy(escrow_bag));
1059 plist_free(escrow_bag);
1060 escrow_bag = NULL;
1061 }
1062 }
937 } 1063 }
1064 } else {
1065 debug_info("external pairing mode");
938 } 1066 }
939 } else { 1067 } else {
940 debug_info("%s failure", verb); 1068 debug_info("%s failure", verb);
@@ -950,6 +1078,10 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_
950 ret = LOCKDOWN_E_PASSWORD_PROTECTED; 1078 ret = LOCKDOWN_E_PASSWORD_PROTECTED;
951 } else if (!strcmp(value, "InvalidHostID")) { 1079 } else if (!strcmp(value, "InvalidHostID")) {
952 ret = LOCKDOWN_E_INVALID_HOST_ID; 1080 ret = LOCKDOWN_E_INVALID_HOST_ID;
1081 } else if (!strcmp(value, "UserDeniedPairing")) {
1082 ret = LOCKDOWN_E_USER_DENIED_PAIRING;
1083 } else if (!strcmp(value, "PairingDialogResponsePending")) {
1084 ret = LOCKDOWN_E_PAIRING_DIALOG_PENDING;
953 } 1085 }
954 free(value); 1086 free(value);
955 } 1087 }
@@ -958,10 +1090,18 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_
958 error_node = NULL; 1090 error_node = NULL;
959 } 1091 }
960 } 1092 }
1093
1094 if (dict_record) {
1095 plist_free(dict_record);
1096 dict_record = NULL;
1097 }
1098
961 plist_free(dict); 1099 plist_free(dict);
962 dict = NULL; 1100 dict = NULL;
1101
963 if (public_key.data) 1102 if (public_key.data)
964 free(public_key.data); 1103 free(public_key.data);
1104
965 return ret; 1105 return ret;
966} 1106}
967 1107
@@ -1115,11 +1255,12 @@ lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client)
1115 * system failed, LOCKDOWN_E_SSL_ERROR if the certificates could not be 1255 * system failed, LOCKDOWN_E_SSL_ERROR if the certificates could not be
1116 * generated 1256 * generated
1117 */ 1257 */
1118lockdownd_error_t lockdownd_gen_pair_cert(key_data_t public_key, key_data_t * odevice_cert, 1258lockdownd_error_t lockdownd_gen_pair_cert_for_udid(const char *udid, key_data_t public_key, key_data_t * odevice_cert,
1119 key_data_t * ohost_cert, key_data_t * oroot_cert) 1259 key_data_t * ohost_cert, key_data_t * oroot_cert)
1120{ 1260{
1121 if (!public_key.data || !odevice_cert || !ohost_cert || !oroot_cert) 1261 if (!public_key.data || !odevice_cert || !ohost_cert || !oroot_cert)
1122 return LOCKDOWN_E_INVALID_ARG; 1262 return LOCKDOWN_E_INVALID_ARG;
1263
1123 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; 1264 lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
1124 userpref_error_t uret = USERPREF_E_UNKNOWN_ERROR; 1265 userpref_error_t uret = USERPREF_E_UNKNOWN_ERROR;
1125 1266
@@ -1148,7 +1289,7 @@ lockdownd_error_t lockdownd_gen_pair_cert(key_data_t public_key, key_data_t * od
1148 host_privkey.data = NULL; 1289 host_privkey.data = NULL;
1149 host_privkey.size = 0; 1290 host_privkey.size = 0;
1150 1291
1151 uret = userpref_get_keys_and_certs(&root_privkey, &root_cert, &host_privkey, &host_cert); 1292 uret = userpref_device_record_get_keys_and_certs(udid, &root_privkey, &root_cert, &host_privkey, &host_cert);
1152 if (USERPREF_E_SUCCESS == uret) { 1293 if (USERPREF_E_SUCCESS == uret) {
1153 /* generate device certificate */ 1294 /* generate device certificate */
1154 ASN1_INTEGER* sn = ASN1_INTEGER_new(); 1295 ASN1_INTEGER* sn = ASN1_INTEGER_new();
@@ -1209,7 +1350,7 @@ lockdownd_error_t lockdownd_gen_pair_cert(key_data_t public_key, key_data_t * od
1209 key_data_t pem_root_cert = { NULL, 0 }; 1350 key_data_t pem_root_cert = { NULL, 0 };
1210 key_data_t pem_host_cert = { NULL, 0 }; 1351 key_data_t pem_host_cert = { NULL, 0 };
1211 1352
1212 uret = userpref_get_certs_as_pem(&pem_root_cert, &pem_host_cert); 1353 uret = userpref_device_record_get_certs_as_pem(udid, &pem_root_cert, &pem_host_cert);
1213 if (USERPREF_E_SUCCESS == uret) { 1354 if (USERPREF_E_SUCCESS == uret) {
1214 /* copy buffer for output */ 1355 /* copy buffer for output */
1215 membp = BIO_new(BIO_s_mem()); 1356 membp = BIO_new(BIO_s_mem());
@@ -1395,6 +1536,10 @@ lockdownd_error_t lockdownd_gen_pair_cert(key_data_t public_key, key_data_t * od
1395 1536
1396 gnutls_free(der_pub_key.data); 1537 gnutls_free(der_pub_key.data);
1397#endif 1538#endif
1539 /* save device cert in config */
1540 if (odevice_cert->size) {
1541 userpref_device_record_set_value(udid, USERPREF_DEVICE_CERTIFICATE_KEY, plist_new_data((char*)odevice_cert->data, (uint64_t)odevice_cert->size));
1542 }
1398 1543
1399 return ret; 1544 return ret;
1400} 1545}
@@ -1429,9 +1574,24 @@ lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char
1429 /* setup request plist */ 1574 /* setup request plist */
1430 dict = plist_new_dict(); 1575 dict = plist_new_dict();
1431 plist_dict_add_label(dict, client->label); 1576 plist_dict_add_label(dict, client->label);
1432 plist_dict_insert_item(dict,"HostID", plist_new_string(host_id));
1433 plist_dict_insert_item(dict,"Request", plist_new_string("StartSession")); 1577 plist_dict_insert_item(dict,"Request", plist_new_string("StartSession"));
1434 1578
1579 /* add host id */
1580 if (host_id) {
1581 plist_dict_insert_item(dict, "HostID", plist_new_string(host_id));
1582 }
1583
1584 /* add system buid */
1585 char *system_buid = NULL;
1586 userpref_get_system_buid(&system_buid);
1587 if (system_buid) {
1588 plist_dict_insert_item(dict, "SystemBUID", plist_new_string(system_buid));
1589 if (system_buid) {
1590 free(system_buid);
1591 system_buid = NULL;
1592 }
1593 }
1594
1435 ret = lockdownd_send(client, dict); 1595 ret = lockdownd_send(client, dict);
1436 plist_free(dict); 1596 plist_free(dict);
1437 dict = NULL; 1597 dict = NULL;
@@ -1471,6 +1631,7 @@ lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char
1471 if (session_node && (plist_get_node_type(session_node) == PLIST_STRING)) { 1631 if (session_node && (plist_get_node_type(session_node) == PLIST_STRING)) {
1472 plist_get_string_val(session_node, &client->session_id); 1632 plist_get_string_val(session_node, &client->session_id);
1473 } 1633 }
1634
1474 if (client->session_id) { 1635 if (client->session_id) {
1475 debug_info("SessionID: %s", client->session_id); 1636 debug_info("SessionID: %s", client->session_id);
1476 if (session_id != NULL) 1637 if (session_id != NULL)
@@ -1478,7 +1639,9 @@ lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char
1478 } else { 1639 } else {
1479 debug_info("Failed to get SessionID!"); 1640 debug_info("Failed to get SessionID!");
1480 } 1641 }
1642
1481 debug_info("Enable SSL Session: %s", (use_ssl?"true":"false")); 1643 debug_info("Enable SSL Session: %s", (use_ssl?"true":"false"));
1644
1482 if (use_ssl) { 1645 if (use_ssl) {
1483 ret = property_list_service_enable_ssl(client->parent); 1646 ret = property_list_service_enable_ssl(client->parent);
1484 if (ret == PROPERTY_LIST_SERVICE_E_SUCCESS) { 1647 if (ret == PROPERTY_LIST_SERVICE_E_SUCCESS) {
@@ -1523,7 +1686,7 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char
1523 } 1686 }
1524 1687
1525 char *host_id = NULL; 1688 char *host_id = NULL;
1526 userpref_get_host_id(&host_id); 1689 userpref_device_record_get_host_id(client->udid, &host_id);
1527 if (!host_id) 1690 if (!host_id)
1528 return LOCKDOWN_E_INVALID_CONF; 1691 return LOCKDOWN_E_INVALID_CONF;
1529 if (!client->session_id) 1692 if (!client->session_id)
diff --git a/src/lockdown.h b/src/lockdown.h
index 30ebc15..9c2be44 100644
--- a/src/lockdown.h
+++ b/src/lockdown.h
@@ -27,6 +27,8 @@
27#include "libimobiledevice/lockdown.h" 27#include "libimobiledevice/lockdown.h"
28#include "property_list_service.h" 28#include "property_list_service.h"
29 29
30#define LOCKDOWN_PROTOCOL_VERSION "2"
31
30struct lockdownd_client_private { 32struct lockdownd_client_private {
31 property_list_service_client_t parent; 33 property_list_service_client_t parent;
32 int ssl_enabled; 34 int ssl_enabled;
@@ -36,6 +38,6 @@ struct lockdownd_client_private {
36}; 38};
37 39
38lockdownd_error_t lockdownd_get_device_public_key(lockdownd_client_t client, key_data_t * public_key); 40lockdownd_error_t lockdownd_get_device_public_key(lockdownd_client_t client, key_data_t * public_key);
39lockdownd_error_t lockdownd_gen_pair_cert(key_data_t public_key, key_data_t * device_cert, key_data_t * host_cert, key_data_t * root_cert); 41lockdownd_error_t lockdownd_gen_pair_cert_for_udid(const char *udid, key_data_t public_key, key_data_t * device_cert, key_data_t * host_cert, key_data_t * root_cert);
40 42
41#endif 43#endif