diff options
| -rw-r--r-- | src/lockdown.c | 89 |
1 files changed, 47 insertions, 42 deletions
diff --git a/src/lockdown.c b/src/lockdown.c index 71bb198..3e9164c 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -873,32 +873,64 @@ static plist_t lockdownd_pair_record_to_plist(lockdownd_pair_record_t pair_recor | |||
| 873 | } | 873 | } |
| 874 | 874 | ||
| 875 | /** | 875 | /** |
| 876 | * Generates a new pairing record plist and required certificates for the | 876 | * Generates a pair record plist with required certificates for a specific |
| 877 | * supplied public key of the device and the host_id of the caller's host | 877 | * device. If a pairing exists, it is loaded from the computer instead of being |
| 878 | * computer. | 878 | * generated. |
| 879 | * | 879 | * |
| 880 | * @param public_key The public key of the device. | 880 | * @param pair_record_plist Holds the pair record. |
| 881 | * @param host_id The HostID to use for the pair record plist. | ||
| 882 | * @param pair_record_plist Holds the generated pair record. | ||
| 883 | * | 881 | * |
| 884 | * @return LOCKDOWN_E_SUCCESS on success | 882 | * @return LOCKDOWN_E_SUCCESS on success |
| 885 | */ | 883 | */ |
| 886 | static 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) | 884 | static lockdownd_error_t generate_pair_record_plist(lockdownd_client_t client, plist_t *pair_record_plist) |
| 887 | { | 885 | { |
| 888 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; | 886 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 889 | 887 | ||
| 888 | char* host_id = NULL; | ||
| 889 | char* system_buid = NULL; | ||
| 890 | key_data_t public_key = { NULL, 0 }; | ||
| 891 | |||
| 890 | key_data_t device_cert = { NULL, 0 }; | 892 | key_data_t device_cert = { NULL, 0 }; |
| 891 | key_data_t host_cert = { NULL, 0 }; | 893 | key_data_t host_cert = { NULL, 0 }; |
| 892 | key_data_t root_cert = { NULL, 0 }; | 894 | key_data_t root_cert = { NULL, 0 }; |
| 893 | 895 | ||
| 894 | userpref_error_t uret = userpref_device_record_get_certs_as_pem(udid, &root_cert, &host_cert, &device_cert); | 896 | /* load certificates if a pairing exists */ |
| 897 | userpref_error_t uret = userpref_device_record_get_certs_as_pem(client->udid, &root_cert, &host_cert, &device_cert); | ||
| 895 | if ((uret == USERPREF_E_SUCCESS) && (root_cert.size > 0) && (host_cert.size > 0) && (device_cert.size > 0)) { | 898 | if ((uret == USERPREF_E_SUCCESS) && (root_cert.size > 0) && (host_cert.size > 0) && (device_cert.size > 0)) { |
| 896 | ret = LOCKDOWN_E_SUCCESS; | 899 | ret = LOCKDOWN_E_SUCCESS; |
| 897 | } | 900 | } |
| 898 | 901 | ||
| 899 | if (ret != LOCKDOWN_E_SUCCESS) | 902 | /* get systembuid and host id */ |
| 900 | ret = lockdownd_gen_pair_cert_for_udid(udid, public_key, &device_cert, &host_cert, &root_cert); | 903 | userpref_get_system_buid(&system_buid); |
| 904 | userpref_device_record_get_host_id(client->udid, &host_id); | ||
| 905 | |||
| 906 | /* generate new certificates if needed */ | ||
| 901 | if (ret != LOCKDOWN_E_SUCCESS) { | 907 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 908 | ret = lockdownd_get_device_public_key(client, &public_key); | ||
| 909 | if (ret != LOCKDOWN_E_SUCCESS) { | ||
| 910 | if (public_key.data) | ||
| 911 | free(public_key.data); | ||
| 912 | if (host_id) | ||
| 913 | free(host_id); | ||
| 914 | if (system_buid) | ||
| 915 | free(system_buid); | ||
| 916 | debug_info("device refused to send public key."); | ||
| 917 | return ret; | ||
| 918 | } | ||
| 919 | debug_info("device public key follows:\n%.*s", public_key.size, public_key.data); | ||
| 920 | |||
| 921 | userpref_device_record_set_value(client->udid, USERPREF_SYSTEM_BUID_KEY, plist_new_string(system_buid)); | ||
| 922 | |||
| 923 | ret = lockdownd_gen_pair_cert_for_udid(client->udid, public_key, &device_cert, &host_cert, &root_cert); | ||
| 924 | |||
| 925 | if (public_key.data) | ||
| 926 | free(public_key.data); | ||
| 927 | } | ||
| 928 | |||
| 929 | if (ret != LOCKDOWN_E_SUCCESS) { | ||
| 930 | if (host_id) | ||
| 931 | free(host_id); | ||
| 932 | if (system_buid) | ||
| 933 | free(system_buid); | ||
| 902 | return ret; | 934 | return ret; |
| 903 | } | 935 | } |
| 904 | 936 | ||
| @@ -910,6 +942,10 @@ static lockdownd_error_t generate_pair_record_plist(const char *udid, char* syst | |||
| 910 | plist_dict_insert_item(*pair_record_plist, "RootCertificate", plist_new_data((const char*)root_cert.data, root_cert.size)); | 942 | plist_dict_insert_item(*pair_record_plist, "RootCertificate", plist_new_data((const char*)root_cert.data, root_cert.size)); |
| 911 | plist_dict_insert_item(*pair_record_plist, "SystemBUID", plist_new_string(system_buid)); | 943 | plist_dict_insert_item(*pair_record_plist, "SystemBUID", plist_new_string(system_buid)); |
| 912 | 944 | ||
| 945 | if (host_id) | ||
| 946 | free(host_id); | ||
| 947 | if (system_buid) | ||
| 948 | free(system_buid); | ||
| 913 | if (device_cert.data) | 949 | if (device_cert.data) |
| 914 | free(device_cert.data); | 950 | free(device_cert.data); |
| 915 | if (host_cert.data) | 951 | if (host_cert.data) |
| @@ -943,10 +979,7 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_ | |||
| 943 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; | 979 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 944 | plist_t dict = NULL; | 980 | plist_t dict = NULL; |
| 945 | plist_t dict_record = NULL; | 981 | plist_t dict_record = NULL; |
| 946 | key_data_t public_key = { NULL, 0 }; | ||
| 947 | int pairing_mode = 0; /* 0 = libimobiledevice, 1 = external */ | 982 | int pairing_mode = 0; /* 0 = libimobiledevice, 1 = external */ |
| 948 | char* host_id = NULL; | ||
| 949 | char* system_buid = NULL; | ||
| 950 | 983 | ||
| 951 | if (pair_record && pair_record->system_buid && pair_record->host_id) { | 984 | if (pair_record && pair_record->system_buid && pair_record->host_id) { |
| 952 | /* valid pair_record passed? */ | 985 | /* valid pair_record passed? */ |
| @@ -959,30 +992,9 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_ | |||
| 959 | 992 | ||
| 960 | pairing_mode = 1; | 993 | pairing_mode = 1; |
| 961 | } else { | 994 | } else { |
| 962 | ret = lockdownd_get_device_public_key(client, &public_key); | 995 | ret = generate_pair_record_plist(client, &dict_record); |
| 963 | if (ret != LOCKDOWN_E_SUCCESS) { | ||
| 964 | if (public_key.data) | ||
| 965 | free(public_key.data); | ||
| 966 | debug_info("device refused to send public key."); | ||
| 967 | return ret; | ||
| 968 | } | ||
| 969 | debug_info("device public key follows:\n%.*s", public_key.size, public_key.data); | ||
| 970 | |||
| 971 | /* get libimobiledevice pair_record */ | ||
| 972 | userpref_get_system_buid(&system_buid); | ||
| 973 | userpref_device_record_get_host_id(client->udid, &host_id); | ||
| 974 | userpref_device_record_set_value(client->udid, USERPREF_SYSTEM_BUID_KEY, plist_new_string(system_buid)); | ||
| 975 | |||
| 976 | ret = generate_pair_record_plist(client->udid, system_buid, host_id, public_key, &dict_record); | ||
| 977 | |||
| 978 | if (host_id) | ||
| 979 | free(host_id); | ||
| 980 | if (system_buid) | ||
| 981 | free(system_buid); | ||
| 982 | 996 | ||
| 983 | if (ret != LOCKDOWN_E_SUCCESS) { | 997 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 984 | if (public_key.data) | ||
| 985 | free(public_key.data); | ||
| 986 | if (dict_record) | 998 | if (dict_record) |
| 987 | plist_free(dict_record); | 999 | plist_free(dict_record); |
| 988 | return ret; | 1000 | return ret; |
| @@ -1019,8 +1031,6 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_ | |||
| 1019 | dict = NULL; | 1031 | dict = NULL; |
| 1020 | 1032 | ||
| 1021 | if (ret != LOCKDOWN_E_SUCCESS) { | 1033 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 1022 | if (public_key.data) | ||
| 1023 | free(public_key.data); | ||
| 1024 | plist_free(dict_record); | 1034 | plist_free(dict_record); |
| 1025 | return ret; | 1035 | return ret; |
| 1026 | } | 1036 | } |
| @@ -1029,8 +1039,6 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_ | |||
| 1029 | ret = lockdownd_receive(client, &dict); | 1039 | ret = lockdownd_receive(client, &dict); |
| 1030 | 1040 | ||
| 1031 | if (ret != LOCKDOWN_E_SUCCESS) { | 1041 | if (ret != LOCKDOWN_E_SUCCESS) { |
| 1032 | if (public_key.data) | ||
| 1033 | free(public_key.data); | ||
| 1034 | plist_free(dict_record); | 1042 | plist_free(dict_record); |
| 1035 | return ret; | 1043 | return ret; |
| 1036 | } | 1044 | } |
| @@ -1112,9 +1120,6 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_ | |||
| 1112 | plist_free(dict); | 1120 | plist_free(dict); |
| 1113 | dict = NULL; | 1121 | dict = NULL; |
| 1114 | 1122 | ||
| 1115 | if (public_key.data) | ||
| 1116 | free(public_key.data); | ||
| 1117 | |||
| 1118 | return ret; | 1123 | return ret; |
| 1119 | } | 1124 | } |
| 1120 | 1125 | ||
