diff options
Diffstat (limited to 'src/lockdown.c')
| -rw-r--r-- | src/lockdown.c | 191 |
1 files changed, 179 insertions, 12 deletions
diff --git a/src/lockdown.c b/src/lockdown.c index 2532999..24dd4a1 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -108,6 +108,21 @@ static int lockdown_check_result(plist_t dict, const char *query_match) | |||
| 108 | } | 108 | } |
| 109 | 109 | ||
| 110 | /** | 110 | /** |
| 111 | * Adds a label key with the passed value to a plist dict node. | ||
| 112 | * | ||
| 113 | * @param plist The plist to add the key to | ||
| 114 | * @param label The value for the label key | ||
| 115 | * | ||
| 116 | */ | ||
| 117 | static void plist_dict_add_label(plist_t plist, const char *label) | ||
| 118 | { | ||
| 119 | if (plist && label) { | ||
| 120 | if (plist_get_node_type(plist) == PLIST_DICT) | ||
| 121 | plist_dict_insert_item(plist, "Label", plist_new_string(label)); | ||
| 122 | } | ||
| 123 | } | ||
| 124 | |||
| 125 | /** | ||
| 111 | * Closes the lockdownd communication session, by sending | 126 | * Closes the lockdownd communication session, by sending |
| 112 | * the StopSession Request to the device. | 127 | * the StopSession Request to the device. |
| 113 | * | 128 | * |
| @@ -128,6 +143,7 @@ lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client) | |||
| 128 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; | 143 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 129 | 144 | ||
| 130 | plist_t dict = plist_new_dict(); | 145 | plist_t dict = plist_new_dict(); |
| 146 | plist_dict_add_label(dict, client->label); | ||
| 131 | plist_dict_insert_item(dict,"Request", plist_new_string("StopSession")); | 147 | plist_dict_insert_item(dict,"Request", plist_new_string("StopSession")); |
| 132 | plist_dict_insert_item(dict,"SessionID", plist_new_string(client->session_id)); | 148 | plist_dict_insert_item(dict,"SessionID", plist_new_string(client->session_id)); |
| 133 | 149 | ||
| @@ -223,11 +239,27 @@ lockdownd_error_t lockdownd_client_free(lockdownd_client_t client) | |||
| 223 | if (client->uuid) { | 239 | if (client->uuid) { |
| 224 | free(client->uuid); | 240 | free(client->uuid); |
| 225 | } | 241 | } |
| 242 | if (client->label) { | ||
| 243 | free(client->label); | ||
| 244 | } | ||
| 226 | 245 | ||
| 227 | free(client); | 246 | free(client); |
| 228 | return ret; | 247 | return ret; |
| 229 | } | 248 | } |
| 230 | 249 | ||
| 250 | /** | ||
| 251 | * Sets the label to send for requests to lockdownd. | ||
| 252 | * | ||
| 253 | * @param client The lockdown client | ||
| 254 | * @param label The label to set or NULL to disable | ||
| 255 | * | ||
| 256 | */ | ||
| 257 | void lockdownd_client_set_label(lockdownd_client_t client, const char *label) | ||
| 258 | { | ||
| 259 | if (client) | ||
| 260 | client->label = strdup(label); | ||
| 261 | } | ||
| 262 | |||
| 231 | /** Polls the iPhone for lockdownd data. | 263 | /** Polls the iPhone for lockdownd data. |
| 232 | * | 264 | * |
| 233 | * @param control The lockdownd client | 265 | * @param control The lockdownd client |
| @@ -306,6 +338,7 @@ lockdownd_error_t lockdownd_query_type(lockdownd_client_t client) | |||
| 306 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; | 338 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 307 | 339 | ||
| 308 | plist_t dict = plist_new_dict(); | 340 | plist_t dict = plist_new_dict(); |
| 341 | plist_dict_add_label(dict, client->label); | ||
| 309 | plist_dict_insert_item(dict,"Request", plist_new_string("QueryType")); | 342 | plist_dict_insert_item(dict,"Request", plist_new_string("QueryType")); |
| 310 | 343 | ||
| 311 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); | 344 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); |
| @@ -349,6 +382,7 @@ lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *dom | |||
| 349 | 382 | ||
| 350 | /* setup request plist */ | 383 | /* setup request plist */ |
| 351 | dict = plist_new_dict(); | 384 | dict = plist_new_dict(); |
| 385 | plist_dict_add_label(dict, client->label); | ||
| 352 | if (domain) { | 386 | if (domain) { |
| 353 | plist_dict_insert_item(dict,"Domain", plist_new_string(domain)); | 387 | plist_dict_insert_item(dict,"Domain", plist_new_string(domain)); |
| 354 | } | 388 | } |
| @@ -410,6 +444,7 @@ lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *dom | |||
| 410 | 444 | ||
| 411 | /* setup request plist */ | 445 | /* setup request plist */ |
| 412 | dict = plist_new_dict(); | 446 | dict = plist_new_dict(); |
| 447 | plist_dict_add_label(dict, client->label); | ||
| 413 | if (domain) { | 448 | if (domain) { |
| 414 | plist_dict_insert_item(dict,"Domain", plist_new_string(domain)); | 449 | plist_dict_insert_item(dict,"Domain", plist_new_string(domain)); |
| 415 | } | 450 | } |
| @@ -467,6 +502,7 @@ lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char * | |||
| 467 | 502 | ||
| 468 | /* setup request plist */ | 503 | /* setup request plist */ |
| 469 | dict = plist_new_dict(); | 504 | dict = plist_new_dict(); |
| 505 | plist_dict_add_label(dict, client->label); | ||
| 470 | if (domain) { | 506 | if (domain) { |
| 471 | plist_dict_insert_item(dict,"Domain", plist_new_string(domain)); | 507 | plist_dict_insert_item(dict,"Domain", plist_new_string(domain)); |
| 472 | } | 508 | } |
| @@ -576,10 +612,11 @@ lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **de | |||
| 576 | * | 612 | * |
| 577 | * @param phone The iPhone to create a lockdownd client for | 613 | * @param phone The iPhone to create a lockdownd client for |
| 578 | * @param client The pointer to the location of the new lockdownd_client | 614 | * @param client The pointer to the location of the new lockdownd_client |
| 615 | * @param label The label to use for communication. Usually the program name | ||
| 579 | * | 616 | * |
| 580 | * @return an error code (LOCKDOWN_E_SUCCESS on success) | 617 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 581 | */ | 618 | */ |
| 582 | lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client) | 619 | lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_t *client, const char *label) |
| 583 | { | 620 | { |
| 584 | if (!client) | 621 | if (!client) |
| 585 | return LOCKDOWN_E_INVALID_ARG; | 622 | return LOCKDOWN_E_INVALID_ARG; |
| @@ -599,6 +636,7 @@ lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_ | |||
| 599 | client_loc->in_SSL = 0; | 636 | client_loc->in_SSL = 0; |
| 600 | client_loc->session_id = NULL; | 637 | client_loc->session_id = NULL; |
| 601 | client_loc->uuid = NULL; | 638 | client_loc->uuid = NULL; |
| 639 | client_loc->label = strdup(label); | ||
| 602 | 640 | ||
| 603 | if (LOCKDOWN_E_SUCCESS != lockdownd_query_type(client_loc)) { | 641 | if (LOCKDOWN_E_SUCCESS != lockdownd_query_type(client_loc)) { |
| 604 | log_debug_msg("%s: QueryType failed in the lockdownd client.\n", __func__); | 642 | log_debug_msg("%s: QueryType failed in the lockdownd client.\n", __func__); |
| @@ -681,6 +719,7 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, char *host | |||
| 681 | /* Setup Pair request plist */ | 719 | /* Setup Pair request plist */ |
| 682 | dict = plist_new_dict(); | 720 | dict = plist_new_dict(); |
| 683 | dict_record = plist_new_dict(); | 721 | dict_record = plist_new_dict(); |
| 722 | plist_dict_add_label(dict, client->label); | ||
| 684 | plist_dict_insert_item(dict,"PairRecord", dict_record); | 723 | plist_dict_insert_item(dict,"PairRecord", dict_record); |
| 685 | 724 | ||
| 686 | plist_dict_insert_item(dict_record, "DeviceCertificate", plist_new_data((const char*)device_cert.data, device_cert.size)); | 725 | plist_dict_insert_item(dict_record, "DeviceCertificate", plist_new_data((const char*)device_cert.data, device_cert.size)); |
| @@ -711,16 +750,36 @@ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, char *host | |||
| 711 | if (lockdown_check_result(dict, verb) != RESULT_SUCCESS) { | 750 | if (lockdown_check_result(dict, verb) != RESULT_SUCCESS) { |
| 712 | ret = LOCKDOWN_E_PAIRING_FAILED; | 751 | ret = LOCKDOWN_E_PAIRING_FAILED; |
| 713 | } | 752 | } |
| 714 | plist_free(dict); | ||
| 715 | dict = NULL; | ||
| 716 | 753 | ||
| 717 | /* store public key in config if pairing succeeded */ | 754 | /* if pairing succeeded */ |
| 718 | if (ret == LOCKDOWN_E_SUCCESS) { | 755 | if (ret == LOCKDOWN_E_SUCCESS) { |
| 719 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: %s success\n", __func__, verb); | 756 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: %s success\n", __func__, verb); |
| 720 | userpref_set_device_public_key(client->uuid, public_key); | 757 | if (!strcmp("Unpair", verb)) { |
| 758 | /* remove public key from config */ | ||
| 759 | userpref_remove_device_public_key(client->uuid); | ||
| 760 | } else { | ||
| 761 | /* store public key in config */ | ||
| 762 | userpref_set_device_public_key(client->uuid, public_key); | ||
| 763 | } | ||
| 721 | } else { | 764 | } else { |
| 722 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: %s failure\n", __func__, verb); | 765 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: %s failure\n", __func__, verb); |
| 766 | plist_t error_node = NULL; | ||
| 767 | /* verify error condition */ | ||
| 768 | error_node = plist_dict_get_item(dict, "Error"); | ||
| 769 | if (error_node) { | ||
| 770 | char *value = NULL; | ||
| 771 | plist_get_string_val(error_node, &value); | ||
| 772 | /* the first pairing fails if the device is password protected */ | ||
| 773 | if (value && !strcmp(value, "PasswordProtected")) { | ||
| 774 | ret = LOCKDOWN_E_PASSWORD_PROTECTED; | ||
| 775 | free(value); | ||
| 776 | } | ||
| 777 | plist_free(error_node); | ||
| 778 | error_node = NULL; | ||
| 779 | } | ||
| 723 | } | 780 | } |
| 781 | plist_free(dict); | ||
| 782 | dict = NULL; | ||
| 724 | free(public_key.data); | 783 | free(public_key.data); |
| 725 | return ret; | 784 | return ret; |
| 726 | } | 785 | } |
| @@ -758,6 +817,21 @@ lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, char *host_ | |||
| 758 | return lockdownd_do_pair(client, host_id, "ValidatePair"); | 817 | return lockdownd_do_pair(client, host_id, "ValidatePair"); |
| 759 | } | 818 | } |
| 760 | 819 | ||
| 820 | /** | ||
| 821 | * Unpairs the device with the given HostID and removes the pairing records | ||
| 822 | * from the device and host. | ||
| 823 | * | ||
| 824 | * @param client The lockdown client to pair with. | ||
| 825 | * @param host_id The HostID to use for unpairing. If NULL is passed, then | ||
| 826 | * the HostID of the current machine is used. | ||
| 827 | * | ||
| 828 | * @return an error code (LOCKDOWN_E_SUCCESS on success) | ||
| 829 | */ | ||
| 830 | lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, char *host_id) | ||
| 831 | { | ||
| 832 | return lockdownd_do_pair(client, host_id, "Unpair"); | ||
| 833 | } | ||
| 834 | |||
| 761 | /** | 835 | /** |
| 762 | * Tells the device to immediately enter recovery mode. | 836 | * Tells the device to immediately enter recovery mode. |
| 763 | * | 837 | * |
| @@ -773,6 +847,7 @@ lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client) | |||
| 773 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; | 847 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 774 | 848 | ||
| 775 | plist_t dict = plist_new_dict(); | 849 | plist_t dict = plist_new_dict(); |
| 850 | plist_dict_add_label(dict, client->label); | ||
| 776 | plist_dict_insert_item(dict,"Request", plist_new_string("EnterRecovery")); | 851 | plist_dict_insert_item(dict,"Request", plist_new_string("EnterRecovery")); |
| 777 | 852 | ||
| 778 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: telling device to enter recovery mode\n", __func__); | 853 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: telling device to enter recovery mode\n", __func__); |
| @@ -808,6 +883,7 @@ lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client) | |||
| 808 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; | 883 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 809 | 884 | ||
| 810 | plist_t dict = plist_new_dict(); | 885 | plist_t dict = plist_new_dict(); |
| 886 | plist_dict_add_label(dict, client->label); | ||
| 811 | plist_dict_insert_item(dict,"Request", plist_new_string("Goodbye")); | 887 | plist_dict_insert_item(dict,"Request", plist_new_string("Goodbye")); |
| 812 | 888 | ||
| 813 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); | 889 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: called\n", __func__); |
| @@ -977,7 +1053,7 @@ lockdownd_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datu | |||
| 977 | * | 1053 | * |
| 978 | * @return an error code (LOCKDOWN_E_SUCCESS on success) | 1054 | * @return an error code (LOCKDOWN_E_SUCCESS on success) |
| 979 | */ | 1055 | */ |
| 980 | lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *HostID) | 1056 | lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char *host_id) |
| 981 | { | 1057 | { |
| 982 | plist_t dict = NULL; | 1058 | plist_t dict = NULL; |
| 983 | uint32_t return_me = 0; | 1059 | uint32_t return_me = 0; |
| @@ -990,7 +1066,8 @@ lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const c | |||
| 990 | 1066 | ||
| 991 | /* Setup DevicePublicKey request plist */ | 1067 | /* Setup DevicePublicKey request plist */ |
| 992 | dict = plist_new_dict(); | 1068 | dict = plist_new_dict(); |
| 993 | plist_dict_insert_item(dict,"HostID", plist_new_string(HostID)); | 1069 | plist_dict_add_label(dict, client->label); |
| 1070 | plist_dict_insert_item(dict,"HostID", plist_new_string(host_id)); | ||
| 994 | plist_dict_insert_item(dict,"Request", plist_new_string("StartSession")); | 1071 | plist_dict_insert_item(dict,"Request", plist_new_string("StartSession")); |
| 995 | 1072 | ||
| 996 | ret = lockdownd_send(client, dict); | 1073 | ret = lockdownd_send(client, dict); |
| @@ -1013,14 +1090,15 @@ lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const c | |||
| 1013 | 1090 | ||
| 1014 | if (!strcmp(error, "InvalidHostID")) { | 1091 | if (!strcmp(error, "InvalidHostID")) { |
| 1015 | /* hostid is unknown. Pair and try again */ | 1092 | /* hostid is unknown. Pair and try again */ |
| 1016 | char *host_id = NULL; | 1093 | char *host_id_new = NULL; |
| 1017 | userpref_get_host_id(&host_id); | 1094 | userpref_get_host_id(&host_id_new); |
| 1018 | 1095 | ||
| 1019 | if (LOCKDOWN_E_SUCCESS == lockdownd_pair(client, host_id) ) { | 1096 | if (LOCKDOWN_E_SUCCESS == lockdownd_pair(client, host_id_new) ) { |
| 1020 | /* start session again */ | 1097 | /* start session again */ |
| 1021 | plist_free(dict); | 1098 | plist_free(dict); |
| 1022 | dict = plist_new_dict(); | 1099 | dict = plist_new_dict(); |
| 1023 | plist_dict_insert_item(dict,"HostID", plist_new_string(HostID)); | 1100 | plist_dict_add_label(dict, client->label); |
| 1101 | plist_dict_insert_item(dict,"HostID", plist_new_string(host_id_new)); | ||
| 1024 | plist_dict_insert_item(dict,"Request", plist_new_string("StartSession")); | 1102 | plist_dict_insert_item(dict,"Request", plist_new_string("StartSession")); |
| 1025 | 1103 | ||
| 1026 | ret = lockdownd_send(client, dict); | 1104 | ret = lockdownd_send(client, dict); |
| @@ -1029,7 +1107,7 @@ lockdownd_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const c | |||
| 1029 | 1107 | ||
| 1030 | ret = lockdownd_recv(client, &dict); | 1108 | ret = lockdownd_recv(client, &dict); |
| 1031 | } | 1109 | } |
| 1032 | free(host_id); | 1110 | free(host_id_new); |
| 1033 | } | 1111 | } |
| 1034 | free(error); | 1112 | free(error); |
| 1035 | } | 1113 | } |
| @@ -1217,6 +1295,7 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char | |||
| 1217 | host_id = NULL; | 1295 | host_id = NULL; |
| 1218 | 1296 | ||
| 1219 | dict = plist_new_dict(); | 1297 | dict = plist_new_dict(); |
| 1298 | plist_dict_add_label(dict, client->label); | ||
| 1220 | plist_dict_insert_item(dict,"Request", plist_new_string("StartService")); | 1299 | plist_dict_insert_item(dict,"Request", plist_new_string("StartService")); |
| 1221 | plist_dict_insert_item(dict,"Service", plist_new_string(service)); | 1300 | plist_dict_insert_item(dict,"Service", plist_new_string(service)); |
| 1222 | 1301 | ||
| @@ -1260,3 +1339,91 @@ lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char | |||
| 1260 | return ret; | 1339 | return ret; |
| 1261 | } | 1340 | } |
| 1262 | 1341 | ||
| 1342 | /** | ||
| 1343 | * Activates the device. Only works within an open session. | ||
| 1344 | * The ActivationRecord plist dictionary must be obtained using the | ||
| 1345 | * activation protocol requesting from Apple's https webservice. | ||
| 1346 | * | ||
| 1347 | * @see http://iphone-docs.org/doku.php?id=docs:protocols:activation | ||
| 1348 | * | ||
| 1349 | * @param control The lockdown client | ||
| 1350 | * @param activation_record The activation record plist dictionary | ||
| 1351 | * | ||
| 1352 | * @return an error code (LOCKDOWN_E_SUCCESS on success) | ||
| 1353 | */ | ||
| 1354 | lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record) | ||
| 1355 | { | ||
| 1356 | if (!client) | ||
| 1357 | return LOCKDOWN_E_INVALID_ARG; | ||
| 1358 | |||
| 1359 | if (!activation_record) | ||
| 1360 | return LOCKDOWN_E_INVALID_ARG; | ||
| 1361 | |||
| 1362 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; | ||
| 1363 | |||
| 1364 | plist_t dict = plist_new_dict(); | ||
| 1365 | plist_dict_add_label(dict, client->label); | ||
| 1366 | plist_dict_insert_item(dict,"Request", plist_new_string("Activate")); | ||
| 1367 | plist_dict_insert_item(dict,"ActivationRecord", activation_record); | ||
| 1368 | |||
| 1369 | ret = lockdownd_send(client, dict); | ||
| 1370 | plist_free(dict); | ||
| 1371 | dict = NULL; | ||
| 1372 | |||
| 1373 | ret = lockdownd_recv(client, &dict); | ||
| 1374 | if (!dict) { | ||
| 1375 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: LOCKDOWN_E_PLIST_ERROR\n", __func__); | ||
| 1376 | return LOCKDOWN_E_PLIST_ERROR; | ||
| 1377 | } | ||
| 1378 | |||
| 1379 | ret = LOCKDOWN_E_ACTIVATION_FAILED; | ||
| 1380 | if (lockdown_check_result(dict, "Activate") == RESULT_SUCCESS) { | ||
| 1381 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); | ||
| 1382 | ret = LOCKDOWN_E_SUCCESS; | ||
| 1383 | } | ||
| 1384 | plist_free(dict); | ||
| 1385 | dict = NULL; | ||
| 1386 | |||
| 1387 | return ret; | ||
| 1388 | } | ||
| 1389 | |||
| 1390 | /** | ||
| 1391 | * Deactivates the device, returning it to the locked | ||
| 1392 | * “Activate with iTunes” screen. | ||
| 1393 | * | ||
| 1394 | * @param control The lockdown client | ||
| 1395 | * | ||
| 1396 | * @return an error code (LOCKDOWN_E_SUCCESS on success) | ||
| 1397 | */ | ||
| 1398 | lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client) | ||
| 1399 | { | ||
| 1400 | if (!client) | ||
| 1401 | return LOCKDOWN_E_INVALID_ARG; | ||
| 1402 | |||
| 1403 | lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; | ||
| 1404 | |||
| 1405 | plist_t dict = plist_new_dict(); | ||
| 1406 | plist_dict_add_label(dict, client->label); | ||
| 1407 | plist_dict_insert_item(dict,"Request", plist_new_string("Deactivate")); | ||
| 1408 | |||
| 1409 | ret = lockdownd_send(client, dict); | ||
| 1410 | plist_free(dict); | ||
| 1411 | dict = NULL; | ||
| 1412 | |||
| 1413 | ret = lockdownd_recv(client, &dict); | ||
| 1414 | if (!dict) { | ||
| 1415 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: LOCKDOWN_E_PLIST_ERROR\n", __func__); | ||
| 1416 | return LOCKDOWN_E_PLIST_ERROR; | ||
| 1417 | } | ||
| 1418 | |||
| 1419 | ret = LOCKDOWN_E_UNKNOWN_ERROR; | ||
| 1420 | if (lockdown_check_result(dict, "Deactivate") == RESULT_SUCCESS) { | ||
| 1421 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); | ||
| 1422 | ret = LOCKDOWN_E_SUCCESS; | ||
| 1423 | } | ||
| 1424 | plist_free(dict); | ||
| 1425 | dict = NULL; | ||
| 1426 | |||
| 1427 | return ret; | ||
| 1428 | } | ||
| 1429 | |||
