summaryrefslogtreecommitdiffstats
path: root/src/lockdown.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lockdown.c')
-rw-r--r--src/lockdown.c257
1 files changed, 210 insertions, 47 deletions
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)