~ubuntu-branches/ubuntu/trusty/libimobiledevice/trusty-proposed

« back to all changes in this revision

Viewing changes to src/lockdown.c

  • Committer: Package Import Robot
  • Author(s): Timo Jyrinki, Matthias Niess, Timo Jyrinki
  • Date: 2014-03-14 08:44:15 UTC
  • mfrom: (1.1.10)
  • Revision ID: package-import@ubuntu.com-20140314084415-twglhjx6bqzmir8v
Tags: 1.1.5+git20140313.bafe6a9e-0ubuntu1
[ Matthias Niess ]
* Replace a duplicate 'backup' util man page with the one for 'crashreport'

[ Timo Jyrinki ]
* New upstream snapshot. (LP: #1207812)
* Drop patches include in the upstream snapshot:
  - debian/patches/CVE-2013-2142.patch
  - debian/patches/git_explicitly_cast_ssl_enabled.patch
* Drop the python patch, new upstream method seems to work:
  - debian/patches/09_use_python_config.patch
* Refreshed remaining patches:
  - debian/patches/01-libs.private.patch
  - debian/patches/02-fix-link-errors.patch
* Drop libimobiledevice-doc, the git does not include html documentation
* Updated libimobiledevice4.symbols 
* Add missing man page for the 'idevicename' util

Show diffs side-by-side

added added

removed removed

Lines of Context:
30
30
#define __USE_GNU 1
31
31
#include <stdio.h>
32
32
#include <ctype.h>
 
33
#include <unistd.h>
33
34
#ifdef HAVE_OPENSSL
34
35
#include <openssl/pem.h>
35
36
#include <openssl/x509.h>
37
38
#else
38
39
#include <libtasn1.h>
39
40
#include <gnutls/x509.h>
 
41
#include <gnutls/crypto.h>
40
42
#endif
41
43
#include <plist/plist.h>
42
44
 
43
45
#include "property_list_service.h"
44
46
#include "lockdown.h"
45
47
#include "idevice.h"
46
 
#include "debug.h"
47
 
#include "userpref.h"
 
48
#include "common/debug.h"
 
49
#include "common/userpref.h"
48
50
#include "asprintf.h"
49
51
 
 
52
#ifdef WIN32
 
53
#include <windows.h>
 
54
#define sleep(x) Sleep(x*1000)
 
55
#endif
 
56
 
50
57
#define RESULT_SUCCESS 0
51
58
#define RESULT_FAILURE 1
52
59
 
201
208
                debug_info("success");
202
209
                ret = LOCKDOWN_E_SUCCESS;
203
210
        }
 
211
 
204
212
        plist_free(dict);
205
213
        dict = NULL;
 
214
 
 
215
        if (client->session_id) {
 
216
                free(client->session_id);
 
217
                client->session_id = NULL;
 
218
        }
 
219
 
206
220
        if (client->ssl_enabled) {
207
221
                property_list_service_disable_ssl(client->parent);
 
222
                client->ssl_enabled = 0;
208
223
        }
 
224
 
209
225
        return ret;
210
226
}
211
227
 
212
 
/**
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
 
 */
220
 
lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
 
228
static lockdownd_error_t lockdownd_client_free_simple(lockdownd_client_t client)
221
229
{
222
230
        if (!client)
223
231
                return LOCKDOWN_E_INVALID_ARG;
 
232
 
224
233
        lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
225
234
 
226
 
        if (client->session_id) {
227
 
                lockdownd_stop_session(client, client->session_id);
228
 
                free(client->session_id);
229
 
        }
230
 
 
231
235
        if (client->parent) {
232
 
                lockdownd_goodbye(client);
233
 
 
234
236
                if (property_list_service_client_free(client->parent) == PROPERTY_LIST_SERVICE_E_SUCCESS) {
235
237
                        ret = LOCKDOWN_E_SUCCESS;
236
238
                }
237
239
        }
238
240
 
 
241
        if (client->session_id) {
 
242
                free(client->session_id);
 
243
                client->session_id = NULL;
 
244
        }
239
245
        if (client->udid) {
240
246
                free(client->udid);
241
247
        }
244
250
        }
245
251
 
246
252
        free(client);
 
253
        client = NULL;
 
254
 
 
255
        return ret;
 
256
}
 
257
 
 
258
/**
 
259
 * Closes the lockdownd client session if one is running and frees up the
 
260
 * lockdownd_client struct.
 
261
 *
 
262
 * @param client The lockdown client
 
263
 *
 
264
 * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
 
265
 */
 
266
lockdownd_error_t lockdownd_client_free(lockdownd_client_t client)
 
267
{
 
268
        if (!client)
 
269
                return LOCKDOWN_E_INVALID_ARG;
 
270
 
 
271
        lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
 
272
 
 
273
        if (client->session_id) {
 
274
                lockdownd_stop_session(client, client->session_id);
 
275
        }
 
276
 
 
277
        ret = lockdownd_client_free_simple(client);
 
278
 
247
279
        return ret;
248
280
}
249
281
 
350
382
                return ret;
351
383
 
352
384
        ret = LOCKDOWN_E_UNKNOWN_ERROR;
353
 
        if (lockdown_check_result(dict, "QueryType") == RESULT_SUCCESS) {
 
385
        plist_t type_node = plist_dict_get_item(dict, "Type");
 
386
        if (type_node && (plist_get_node_type(type_node) == PLIST_STRING)) {
 
387
                char* typestr = NULL;
 
388
                plist_get_string_val(type_node, &typestr);
 
389
                debug_info("success with type %s", typestr);
354
390
                /* return the type if requested */
355
391
                if (type != NULL) {
356
 
                        plist_t type_node = plist_dict_get_item(dict, "Type");
357
 
                        plist_get_string_val(type_node, type);
 
392
                        *type = typestr;
 
393
                } else {
 
394
                        free(typestr);
358
395
                }
359
 
                debug_info("success with type %s", *type);
360
396
                ret = LOCKDOWN_E_SUCCESS;
 
397
        } else {
 
398
                debug_info("hmm. QueryType response does not contain a type?!");
 
399
                debug_plist(dict);
361
400
        }
362
401
        plist_free(dict);
363
402
        dict = NULL;
719
758
                        free(type);
720
759
        }
721
760
 
722
 
        userpref_get_host_id(&host_id);
 
761
        userpref_device_record_get_host_id(client_loc->udid, &host_id);
723
762
        if (LOCKDOWN_E_SUCCESS == ret && !host_id) {
724
763
                ret = LOCKDOWN_E_INVALID_CONF;
725
764
        }
726
765
 
727
 
        if (LOCKDOWN_E_SUCCESS == ret && !userpref_has_device_public_key(client_loc->udid))
 
766
        if (LOCKDOWN_E_SUCCESS == ret && !userpref_has_device_record(client_loc->udid)) {
 
767
                /* attempt pairing */
728
768
                ret = lockdownd_pair(client_loc, NULL);
 
769
        }
729
770
 
730
771
        /* in any case, we need to validate pairing to receive trusted host status */
731
772
        ret = lockdownd_validate_pair(client_loc, NULL);
733
774
        /* if not paired yet, let's do it now */
734
775
        if (LOCKDOWN_E_INVALID_HOST_ID == ret) {
735
776
                ret = lockdownd_pair(client_loc, NULL);
 
777
 
736
778
                if (LOCKDOWN_E_SUCCESS == ret) {
737
779
                        ret = lockdownd_validate_pair(client_loc, NULL);
 
780
                } else if (LOCKDOWN_E_PAIRING_DIALOG_PENDING == ret) {
 
781
                        debug_info("Device shows the pairing dialog.");
738
782
                }
739
783
        }
740
784
 
772
816
        if (!pair_record)
773
817
                return NULL;
774
818
 
775
 
        char *host_id_loc = pair_record->host_id;
776
 
 
777
819
        /* setup request plist */
778
820
        plist_t dict = plist_new_dict();
779
821
        plist_dict_insert_item(dict, "DeviceCertificate", plist_new_data(pair_record->device_certificate, strlen(pair_record->device_certificate)));
780
822
        plist_dict_insert_item(dict, "HostCertificate", plist_new_data(pair_record->host_certificate, strlen(pair_record->host_certificate)));
781
 
        if (!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));
 
823
        plist_dict_insert_item(dict, "HostID", plist_new_string(pair_record->host_id));
784
824
        plist_dict_insert_item(dict, "RootCertificate", plist_new_data(pair_record->root_certificate, strlen(pair_record->root_certificate)));
785
 
 
786
 
        if (!pair_record->host_id)
787
 
                free(host_id_loc);
 
825
        plist_dict_insert_item(dict, "SystemBUID", plist_new_string(pair_record->system_buid));
788
826
 
789
827
        return dict;
790
828
}
791
829
 
792
830
/**
793
 
 * Generates a new pairing record plist and required certificates for the 
794
 
 * supplied public key of the device and the host_id of the caller's host
795
 
 * computer.
 
831
 * Generates a pair record plist with required certificates for a specific
 
832
 * device. If a pairing exists, it is loaded from the computer instead of being
 
833
 * generated.
796
834
 *
797
 
 * @param public_key The public key of the device.
798
 
 * @param host_id The HostID to use for the pair record plist.
799
 
 * @param pair_record_plist Holds the generated pair record.
 
835
 * @param pair_record_plist Holds the pair record.
800
836
 *
801
837
 * @return LOCKDOWN_E_SUCCESS on success
802
838
 */
803
 
static lockdownd_error_t generate_pair_record_plist(key_data_t public_key, char *host_id, plist_t *pair_record_plist)
 
839
static lockdownd_error_t generate_pair_record_plist(lockdownd_client_t client, plist_t *pair_record_plist)
804
840
{
805
841
        lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
806
842
 
 
843
        char* host_id = NULL;
 
844
        char* system_buid = NULL;
 
845
 
 
846
        key_data_t public_key = { NULL, 0 };
807
847
        key_data_t device_cert = { NULL, 0 };
808
848
        key_data_t host_cert = { NULL, 0 };
809
849
        key_data_t root_cert = { NULL, 0 };
810
850
 
811
 
        ret = lockdownd_gen_pair_cert(public_key, &device_cert, &host_cert, &root_cert);
812
 
        if (ret != LOCKDOWN_E_SUCCESS) {
813
 
                return ret;
814
 
        }
815
 
 
816
 
        char *host_id_loc = host_id;
817
 
 
818
 
        if (!host_id)
819
 
                userpref_get_host_id(&host_id_loc);
 
851
        /* load certificates if a pairing exists */
 
852
        userpref_error_t uret = userpref_device_record_get_certs_as_pem(client->udid, &root_cert, &host_cert, &device_cert);
 
853
        if ((uret == USERPREF_E_SUCCESS) && (root_cert.size > 0) && (host_cert.size > 0) && (device_cert.size > 0)) {
 
854
                ret = LOCKDOWN_E_SUCCESS;
 
855
        }
 
856
 
 
857
        /* get systembuid and host id */
 
858
        userpref_get_system_buid(&system_buid);
 
859
        userpref_device_record_get_host_id(client->udid, &host_id);
 
860
 
 
861
        /* generate new certificates if needed */
 
862
        if (ret != LOCKDOWN_E_SUCCESS) {
 
863
                ret = lockdownd_get_device_public_key(client, &public_key);
 
864
                if (ret != LOCKDOWN_E_SUCCESS) {
 
865
                        debug_info("device refused to send public key.");
 
866
                        goto leave;
 
867
                }
 
868
                debug_info("device public key follows:\n%.*s", public_key.size, public_key.data);
 
869
 
 
870
                userpref_device_record_set_value(client->udid, USERPREF_SYSTEM_BUID_KEY, plist_new_string(system_buid));
 
871
 
 
872
                ret = lockdownd_gen_pair_cert_for_udid(client->udid, public_key, &device_cert, &host_cert, &root_cert);
 
873
        }
 
874
 
 
875
        if (ret != LOCKDOWN_E_SUCCESS) {
 
876
                goto leave;
 
877
        }
820
878
 
821
879
        /* setup request plist */
822
880
        *pair_record_plist = plist_new_dict();
823
881
        plist_dict_insert_item(*pair_record_plist, "DeviceCertificate", plist_new_data((const char*)device_cert.data, device_cert.size));
824
882
        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));
 
883
        plist_dict_insert_item(*pair_record_plist, "HostID", plist_new_string(host_id));
826
884
        plist_dict_insert_item(*pair_record_plist, "RootCertificate", plist_new_data((const char*)root_cert.data, root_cert.size));
827
 
 
828
 
        if (!host_id)
829
 
                free(host_id_loc);
830
 
 
 
885
        plist_dict_insert_item(*pair_record_plist, "SystemBUID", plist_new_string(system_buid));
 
886
 
 
887
leave:
 
888
        if (host_id)
 
889
                free(host_id);
 
890
        if (system_buid)
 
891
                free(system_buid);
 
892
        if (public_key.data)
 
893
                free(public_key.data);
831
894
        if (device_cert.data)
832
895
                free(device_cert.data);
833
896
        if (host_cert.data)
861
924
        lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
862
925
        plist_t dict = NULL;
863
926
        plist_t dict_record = NULL;
864
 
        key_data_t public_key = { NULL, 0 };
865
927
        int pairing_mode = 0; /* 0 = libimobiledevice, 1 = external */
866
928
 
867
 
        if (pair_record && pair_record->host_id) {
 
929
        if (pair_record && pair_record->system_buid && pair_record->host_id) {
868
930
                /* valid pair_record passed? */
869
931
                if (!pair_record->device_certificate || !pair_record->host_certificate || !pair_record->root_certificate) {
870
932
                        return LOCKDOWN_E_PLIST_ERROR;
875
937
 
876
938
                pairing_mode = 1;
877
939
        } else {
878
 
                ret = lockdownd_get_device_public_key(client, &public_key);
879
 
                if (ret != LOCKDOWN_E_SUCCESS) {
880
 
                        if (public_key.data)
881
 
                                free(public_key.data);
882
 
                        debug_info("device refused to send public key.");
883
 
                        return ret;
884
 
                }
885
 
                debug_info("device public key follows:\n%.*s", public_key.size, public_key.data);
886
 
                /* get libimobiledevice pair_record */
887
 
                ret = generate_pair_record_plist(public_key, NULL, &dict_record);
 
940
                ret = generate_pair_record_plist(client, &dict_record);
 
941
 
888
942
                if (ret != LOCKDOWN_E_SUCCESS) {
889
943
                        if (dict_record)
890
944
                                plist_free(dict_record);
892
946
                }
893
947
        }
894
948
 
895
 
        /* Setup Pair request plist */
 
949
        if (!strcmp("Pair", verb)) {
 
950
                /* get wifi mac */
 
951
                plist_t wifi_mac_node = NULL;
 
952
                lockdownd_get_value(client, NULL, "WiFiAddress", &wifi_mac_node);
 
953
 
 
954
                /* save wifi mac address in config */
 
955
                if (wifi_mac_node) {
 
956
                        userpref_device_record_set_value(client->udid, USERPREF_WIFI_MAC_ADDRESS_KEY, plist_copy(wifi_mac_node));
 
957
                        plist_free(wifi_mac_node);
 
958
                        wifi_mac_node = NULL;
 
959
                }
 
960
        }
 
961
 
 
962
        /* setup pair request plist */
896
963
        dict = plist_new_dict();
897
964
        plist_dict_add_label(dict, client->label);
898
 
        plist_dict_insert_item(dict,"PairRecord", dict_record);
 
965
        plist_dict_insert_item(dict, "PairRecord", plist_copy(dict_record));
899
966
        plist_dict_insert_item(dict, "Request", plist_new_string(verb));
 
967
        plist_dict_insert_item(dict, "ProtocolVersion", plist_new_string(LOCKDOWN_PROTOCOL_VERSION));
 
968
 
 
969
        plist_t options = plist_new_dict();
 
970
        plist_dict_insert_item(options, "ExtendedPairingErrors", plist_new_bool(1));
 
971
        plist_dict_insert_item(dict, "PairingOptions", options);
900
972
 
901
973
        /* send to device */
902
974
        ret = lockdownd_send(client, dict);
903
975
        plist_free(dict);
904
976
        dict = NULL;
905
977
 
906
 
        if (ret != LOCKDOWN_E_SUCCESS)
 
978
        if (ret != LOCKDOWN_E_SUCCESS) {
 
979
                plist_free(dict_record);
907
980
                return ret;
 
981
        }
908
982
 
909
983
        /* Now get device's answer */
910
984
        ret = lockdownd_receive(client, &dict);
911
985
 
912
 
        if (ret != LOCKDOWN_E_SUCCESS)
 
986
        if (ret != LOCKDOWN_E_SUCCESS) {
 
987
                plist_free(dict_record);
913
988
                return ret;
 
989
        }
914
990
 
915
991
        if (strcmp(verb, "Unpair") == 0) {
916
992
                /* workaround for Unpair giving back ValidatePair,
928
1004
        if (ret == LOCKDOWN_E_SUCCESS) {
929
1005
                debug_info("%s success", verb);
930
1006
                if (!pairing_mode) {
 
1007
                        debug_info("internal pairing mode");
931
1008
                        if (!strcmp("Unpair", verb)) {
932
1009
                                /* remove public key from config */
933
 
                                userpref_remove_device_public_key(client->udid);
 
1010
                                userpref_remove_device_record(client->udid);
934
1011
                        } else {
935
 
                                /* store public key in config */
936
 
                                userpref_set_device_public_key(client->udid, public_key);
 
1012
                                if (!strcmp("Pair", verb)) {
 
1013
                                        debug_info("getting EscrowBag from response");
 
1014
 
 
1015
                                        /* add returned escrow bag if available */
 
1016
                                        plist_t escrow_bag = plist_dict_get_item(dict, "EscrowBag");
 
1017
                                        if (escrow_bag && plist_get_node_type(escrow_bag) == PLIST_DATA) {
 
1018
                                                userpref_device_record_set_value(client->udid, USERPREF_ESCROW_BAG_KEY, plist_copy(escrow_bag));
 
1019
                                                plist_free(escrow_bag);
 
1020
                                                escrow_bag = NULL;
 
1021
                                        }
 
1022
 
 
1023
                                        /* store DeviceCertificate upon successful pairing */
 
1024
                                        plist_t devcrt = plist_dict_get_item(dict_record, USERPREF_DEVICE_CERTIFICATE_KEY);
 
1025
                                        if (devcrt && plist_get_node_type(devcrt) == PLIST_DATA) {
 
1026
                                                userpref_device_record_set_value(client->udid, USERPREF_DEVICE_CERTIFICATE_KEY, plist_copy(devcrt));
 
1027
                                        }
 
1028
                                }
937
1029
                        }
 
1030
                } else {
 
1031
                        debug_info("external pairing mode");
938
1032
                }
939
1033
        } else {
940
1034
                debug_info("%s failure", verb);
950
1044
                                        ret = LOCKDOWN_E_PASSWORD_PROTECTED;
951
1045
                                } else if (!strcmp(value, "InvalidHostID")) {
952
1046
                                        ret = LOCKDOWN_E_INVALID_HOST_ID;
 
1047
                                } else if (!strcmp(value, "UserDeniedPairing")) {
 
1048
                                        ret = LOCKDOWN_E_USER_DENIED_PAIRING;
 
1049
                                } else if (!strcmp(value, "PairingDialogResponsePending")) {
 
1050
                                        ret = LOCKDOWN_E_PAIRING_DIALOG_PENDING;
953
1051
                                }
954
1052
                                free(value);
955
1053
                        }
958
1056
                        error_node = NULL;
959
1057
                }
960
1058
        }
 
1059
 
 
1060
        if (dict_record) {
 
1061
                plist_free(dict_record);
 
1062
                dict_record = NULL;
 
1063
        }
 
1064
 
961
1065
        plist_free(dict);
962
1066
        dict = NULL;
963
 
        if (public_key.data)
964
 
                free(public_key.data);
 
1067
 
965
1068
        return ret;
966
1069
}
967
1070
 
1098
1201
        }
1099
1202
        plist_free(dict);
1100
1203
        dict = NULL;
 
1204
 
1101
1205
        return ret;
1102
1206
}
1103
1207
 
1115
1219
 *  system failed, LOCKDOWN_E_SSL_ERROR if the certificates could not be
1116
1220
 *  generated
1117
1221
 */
1118
 
lockdownd_error_t lockdownd_gen_pair_cert(key_data_t public_key, key_data_t * odevice_cert,
 
1222
lockdownd_error_t lockdownd_gen_pair_cert_for_udid(const char *udid, key_data_t public_key, key_data_t * odevice_cert,
1119
1223
                                                                           key_data_t * ohost_cert, key_data_t * oroot_cert)
1120
1224
{
1121
1225
        if (!public_key.data || !odevice_cert || !ohost_cert || !oroot_cert)
1122
1226
                return LOCKDOWN_E_INVALID_ARG;
 
1227
 
1123
1228
        lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;
1124
1229
        userpref_error_t uret = USERPREF_E_UNKNOWN_ERROR;
1125
1230
 
1148
1253
        host_privkey.data = NULL;
1149
1254
        host_privkey.size = 0;
1150
1255
 
1151
 
        uret = userpref_get_keys_and_certs(&root_privkey, &root_cert, &host_privkey, &host_cert);
 
1256
        uret = userpref_device_record_get_keys_and_certs(udid, &root_privkey, &root_cert, &host_privkey, &host_cert);
1152
1257
        if (USERPREF_E_SUCCESS == uret) {
1153
1258
                /* generate device certificate */
1154
1259
                ASN1_INTEGER* sn = ASN1_INTEGER_new();
1159
1264
 
1160
1265
                X509_EXTENSION* ext;
1161
1266
                if (!(ext = X509V3_EXT_conf_nid(NULL, NULL, NID_basic_constraints, (char*)"critical,CA:FALSE"))) {
1162
 
                        debug_info("ERROR: X509V3_EXT_conf_nid failed");
 
1267
                        debug_info("ERROR: X509V3_EXT_conf_nid failed for Basic Constraints");
1163
1268
                }
1164
1269
                X509_add_ext(dev_cert, ext, -1);
 
1270
                X509_EXTENSION_free(ext);
1165
1271
 
1166
1272
                ASN1_TIME* asn1time = ASN1_TIME_new();
1167
1273
                ASN1_TIME_set(asn1time, time(NULL));
1169
1275
                ASN1_TIME_set(asn1time, time(NULL) + (60 * 60 * 24 * 365 * 10));
1170
1276
                X509_set_notAfter(dev_cert, asn1time);
1171
1277
                ASN1_TIME_free(asn1time);
1172
 
        
 
1278
 
1173
1279
                BIO* membp;
1174
1280
 
1175
1281
                X509* rootCert = NULL;
1187
1293
                        X509_free(rootCert);
1188
1294
                }
1189
1295
 
 
1296
                X509V3_CTX ctx;
 
1297
                X509V3_set_ctx_nodb(&ctx);
 
1298
                X509V3_set_ctx(&ctx, NULL, dev_cert, NULL, NULL, 0);
 
1299
 
 
1300
                if (!(ext = X509V3_EXT_conf_nid(NULL, &ctx, NID_subject_key_identifier, (char*)"hash"))) {
 
1301
                        debug_info("ERROR: X509V3_EXT_conf_nid failed for Subject Key identifier");
 
1302
                }
 
1303
                X509_add_ext(dev_cert, ext, -1);
 
1304
                X509_EXTENSION_free(ext);
 
1305
 
 
1306
                if (!(ext = X509V3_EXT_conf_nid(NULL, NULL, NID_key_usage, (char*)"critical,digitalSignature,keyEncipherment"))) {
 
1307
                        debug_info("ERROR: X509V3_EXT_conf_nid failed for Key Usage");
 
1308
                }
 
1309
                X509_add_ext(dev_cert, ext, -1);
 
1310
                X509_EXTENSION_free(ext);
 
1311
 
1190
1312
                EVP_PKEY* rootPriv = NULL;
1191
1313
                membp = BIO_new_mem_buf(root_privkey.data, root_privkey.size);
1192
1314
                PEM_read_bio_PrivateKey(membp, &rootPriv, NULL, NULL);
1208
1330
                        key_data_t pem_root_cert = { NULL, 0 };
1209
1331
                        key_data_t pem_host_cert = { NULL, 0 };
1210
1332
 
1211
 
                        uret = userpref_get_certs_as_pem(&pem_root_cert, &pem_host_cert);
 
1333
                        uret = userpref_device_record_get_certs_as_pem(udid, &pem_root_cert, &pem_host_cert, NULL);
1212
1334
                        if (USERPREF_E_SUCCESS == uret) {
1213
1335
                                /* copy buffer for output */
1214
1336
                                membp = BIO_new(BIO_s_mem());
1215
1337
                                if (membp && PEM_write_bio_X509(membp, dev_cert) > 0) {
1216
 
                                        odevice_cert->size = BIO_get_mem_data(membp, &odevice_cert->data);
 
1338
                                        void *datap;
 
1339
                                        odevice_cert->size = BIO_get_mem_data(membp, &datap);
 
1340
                                        odevice_cert->data = malloc(odevice_cert->size);
 
1341
                                        memcpy(odevice_cert->data, datap, odevice_cert->size);
1217
1342
                                }
1218
1343
                                if (membp)
1219
 
                                        free(membp);
 
1344
                                        BIO_free(membp);
1220
1345
 
1221
1346
                                ohost_cert->data = malloc(pem_host_cert.size);
1222
1347
                                memcpy(ohost_cert->data, pem_host_cert.data, pem_host_cert.size);
1301
1426
                gnutls_x509_crt_t dev_cert, root_cert, host_cert;
1302
1427
 
1303
1428
                gnutls_x509_privkey_init(&fake_privkey);
 
1429
                gnutls_x509_privkey_init(&root_privkey);
 
1430
                gnutls_x509_privkey_init(&host_privkey);
 
1431
 
1304
1432
                gnutls_x509_crt_init(&dev_cert);
1305
1433
                gnutls_x509_crt_init(&root_cert);
1306
1434
                gnutls_x509_crt_init(&host_cert);
1309
1437
                        gnutls_x509_privkey_import_rsa_raw(fake_privkey, &modulus, &exponent, &essentially_null, &essentially_null,
1310
1438
                                                                                           &essentially_null, &essentially_null)) {
1311
1439
 
1312
 
                        gnutls_x509_privkey_init(&root_privkey);
1313
 
                        gnutls_x509_privkey_init(&host_privkey);
1314
 
 
1315
 
                        uret = userpref_get_keys_and_certs(root_privkey, root_cert, host_privkey, host_cert);
 
1440
                        uret = userpref_device_record_get_keys_and_certs(udid, root_privkey, root_cert, host_privkey, host_cert);
1316
1441
 
1317
1442
                        if (USERPREF_E_SUCCESS == uret) {
1318
1443
                                /* generate device certificate */
1322
1447
                                gnutls_x509_crt_set_ca_status(dev_cert, 0);
1323
1448
                                gnutls_x509_crt_set_activation_time(dev_cert, time(NULL));
1324
1449
                                gnutls_x509_crt_set_expiration_time(dev_cert, time(NULL) + (60 * 60 * 24 * 365 * 10));
 
1450
 
 
1451
                                /* use custom hash generation for compatibility with the "Apple ecosystem" */
 
1452
                                const gnutls_digest_algorithm_t dig_sha1 = GNUTLS_DIG_SHA1;
 
1453
                                size_t hash_size = gnutls_hash_get_len(dig_sha1);
 
1454
                                unsigned char hash[hash_size];
 
1455
                                if (gnutls_hash_fast(dig_sha1, der_pub_key.data, der_pub_key.size, (unsigned char*)&hash) < 0) {
 
1456
                                        debug_info("ERROR: Failed to generate SHA1 for public key");
 
1457
                                } else {
 
1458
                                        gnutls_x509_crt_set_subject_key_id(dev_cert, hash, hash_size);
 
1459
                                }
 
1460
 
 
1461
                                gnutls_x509_crt_set_key_usage(dev_cert, GNUTLS_KEY_DIGITAL_SIGNATURE | GNUTLS_KEY_KEY_ENCIPHERMENT);
1325
1462
                                gnutls_x509_crt_sign(dev_cert, root_cert, root_privkey);
1326
1463
 
1327
1464
                                if (LOCKDOWN_E_SUCCESS == ret) {
1336
1473
                                        gnutls_datum_t pem_root_cert = { NULL, 0 };
1337
1474
                                        gnutls_datum_t pem_host_cert = { NULL, 0 };
1338
1475
 
1339
 
                                        uret = userpref_get_certs_as_pem(&pem_root_cert, &pem_host_cert);
 
1476
                                        uret = userpref_device_record_get_certs_as_pem(udid, &pem_root_cert, &pem_host_cert, NULL);
1340
1477
 
1341
1478
                                        if (USERPREF_E_SUCCESS == uret) {
1342
1479
                                                /* copy buffer for output */
1391
1528
 
1392
1529
        gnutls_free(der_pub_key.data);
1393
1530
#endif
1394
 
 
1395
1531
        return ret;
1396
1532
}
1397
1533
 
1419
1555
        /* if we have a running session, stop current one first */
1420
1556
        if (client->session_id) {
1421
1557
                lockdownd_stop_session(client, client->session_id);
1422
 
                free(client->session_id);
1423
1558
        }
1424
1559
 
1425
1560
        /* setup request plist */
1426
1561
        dict = plist_new_dict();
1427
1562
        plist_dict_add_label(dict, client->label);
1428
 
        plist_dict_insert_item(dict,"HostID", plist_new_string(host_id));
1429
1563
        plist_dict_insert_item(dict,"Request", plist_new_string("StartSession"));
1430
1564
 
 
1565
        /* add host id */
 
1566
        if (host_id) {
 
1567
                plist_dict_insert_item(dict, "HostID", plist_new_string(host_id));
 
1568
        }
 
1569
 
 
1570
        /* add system buid */
 
1571
        char *system_buid = NULL;
 
1572
        userpref_get_system_buid(&system_buid);
 
1573
        if (system_buid) {
 
1574
                plist_dict_insert_item(dict, "SystemBUID", plist_new_string(system_buid));
 
1575
                if (system_buid) {
 
1576
                        free(system_buid);
 
1577
                        system_buid = NULL;
 
1578
                }
 
1579
        }
 
1580
 
1431
1581
        ret = lockdownd_send(client, dict);
1432
1582
        plist_free(dict);
1433
1583
        dict = NULL;
1467
1617
                if (session_node && (plist_get_node_type(session_node) == PLIST_STRING)) {
1468
1618
                        plist_get_string_val(session_node, &client->session_id);
1469
1619
                }
 
1620
 
1470
1621
                if (client->session_id) {
1471
1622
                        debug_info("SessionID: %s", client->session_id);
1472
1623
                        if (session_id != NULL)
1474
1625
                } else {
1475
1626
                        debug_info("Failed to get SessionID!");
1476
1627
                }
 
1628
 
1477
1629
                debug_info("Enable SSL Session: %s", (use_ssl?"true":"false"));
 
1630
 
1478
1631
                if (use_ssl) {
1479
1632
                        ret = property_list_service_enable_ssl(client->parent);
1480
1633
                        if (ret == PROPERTY_LIST_SERVICE_E_SUCCESS) {
1519
1672
        }
1520
1673
 
1521
1674
        char *host_id = NULL;
1522
 
        userpref_get_host_id(&host_id);
 
1675
        userpref_device_record_get_host_id(client->udid, &host_id);
1523
1676
        if (!host_id)
1524
1677
                return LOCKDOWN_E_INVALID_CONF;
1525
 
        if (!client->session_id)
1526
 
                return LOCKDOWN_E_NO_RUNNING_SESSION;
1527
1678
 
1528
1679
        plist_t dict = NULL;
1529
1680
        uint16_t port_loc = 0;
1590
1741
                        plist_get_string_val(error_node, &error);
1591
1742
                        if (!strcmp(error, "InvalidService")) {
1592
1743
                                ret = LOCKDOWN_E_INVALID_SERVICE;
 
1744
                        } else if (!strcmp(error, "NoRunningSession")) {
 
1745
                                ret = LOCKDOWN_E_NO_RUNNING_SESSION;
1593
1746
                        }
1594
1747
                        free(error);
1595
1748
                }