diff options
| author | 2009-07-15 16:16:40 +0200 | |
|---|---|---|
| committer | 2009-07-18 10:40:07 -0700 | |
| commit | 0be7debdc3b08e07b7f8bc2e32fed6aed587e09d (patch) | |
| tree | ec6171781ba3525205a58c30a4225d3b52220f28 /src | |
| parent | 484ff2166a2de58dd185a05fefea47a3f8165033 (diff) | |
| download | libimobiledevice-0be7debdc3b08e07b7f8bc2e32fed6aed587e09d.tar.gz libimobiledevice-0be7debdc3b08e07b7f8bc2e32fed6aed587e09d.tar.bz2 | |
Implement lockdown set_value, remove_value and enter_recovery request API
[#46 state:resolved]
Signed-off-by: Matt Colyer <matt@colyer.name>
Diffstat (limited to 'src')
| -rw-r--r-- | src/lockdown.c | 163 |
1 files changed, 159 insertions, 4 deletions
diff --git a/src/lockdown.c b/src/lockdown.c index 24283cb..1a434aa 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -387,11 +387,11 @@ iphone_error_t lockdownd_query_type(lockdownd_client_t client) | |||
| 387 | * @param client an initialized lockdownd client. | 387 | * @param client an initialized lockdownd client. |
| 388 | * @param domain the domain to query on or NULL for global domain | 388 | * @param domain the domain to query on or NULL for global domain |
| 389 | * @param key the key name to request or NULL to query for all keys | 389 | * @param key the key name to request or NULL to query for all keys |
| 390 | * @param value_node a plist node representing the result value node | 390 | * @param value a plist node representing the result value node |
| 391 | * | 391 | * |
| 392 | * @return an error code (IPHONE_E_SUCCESS on success) | 392 | * @return an error code (IPHONE_E_SUCCESS on success) |
| 393 | */ | 393 | */ |
| 394 | iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value_node) | 394 | iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value) |
| 395 | { | 395 | { |
| 396 | if (!client) | 396 | if (!client) |
| 397 | return IPHONE_E_INVALID_ARG; | 397 | return IPHONE_E_INVALID_ARG; |
| @@ -427,7 +427,7 @@ iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain | |||
| 427 | return ret; | 427 | return ret; |
| 428 | 428 | ||
| 429 | if (lockdown_check_result(dict, "GetValue") == RESULT_SUCCESS) { | 429 | if (lockdown_check_result(dict, "GetValue") == RESULT_SUCCESS) { |
| 430 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_get_value(): success\n"); | 430 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); |
| 431 | ret = IPHONE_E_SUCCESS; | 431 | ret = IPHONE_E_SUCCESS; |
| 432 | } | 432 | } |
| 433 | if (ret != IPHONE_E_SUCCESS) { | 433 | if (ret != IPHONE_E_SUCCESS) { |
| @@ -446,7 +446,7 @@ iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain | |||
| 446 | 446 | ||
| 447 | if (!strcmp(result_key, "Value")) { | 447 | if (!strcmp(result_key, "Value")) { |
| 448 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_get_value(): has a value\n"); | 448 | log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_get_value(): has a value\n"); |
| 449 | *value_node = plist_copy(value_value_node); | 449 | *value = plist_copy(value_value_node); |
| 450 | } | 450 | } |
| 451 | free(result_key); | 451 | free(result_key); |
| 452 | } | 452 | } |
| @@ -455,6 +455,126 @@ iphone_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain | |||
| 455 | return ret; | 455 | return ret; |
| 456 | } | 456 | } |
| 457 | 457 | ||
| 458 | /** Sets a preferences value using a plist and optional domain and/or key name. | ||
| 459 | * | ||
| 460 | * @param client an initialized lockdownd client. | ||
| 461 | * @param domain the domain to query on or NULL for global domain | ||
| 462 | * @param key the key name to set the value or NULL to set a value dict plist | ||
| 463 | * @param value a plist node of any node type representing the value to set | ||
| 464 | * | ||
| 465 | * @return an error code (IPHONE_E_SUCCESS on success) | ||
| 466 | */ | ||
| 467 | iphone_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value) | ||
| 468 | { | ||
| 469 | if (!client || !value) | ||
| 470 | return IPHONE_E_INVALID_ARG; | ||
| 471 | |||
| 472 | plist_t dict = NULL; | ||
| 473 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | ||
| 474 | |||
| 475 | /* setup request plist */ | ||
| 476 | dict = plist_new_dict(); | ||
| 477 | if (domain) { | ||
| 478 | plist_add_sub_key_el(dict, "Domain"); | ||
| 479 | plist_add_sub_string_el(dict, domain); | ||
| 480 | } | ||
| 481 | if (key) { | ||
| 482 | plist_add_sub_key_el(dict, "Key"); | ||
| 483 | plist_add_sub_string_el(dict, key); | ||
| 484 | } | ||
| 485 | plist_add_sub_key_el(dict, "Request"); | ||
| 486 | plist_add_sub_string_el(dict, "SetValue"); | ||
| 487 | |||
| 488 | plist_add_sub_key_el(dict, "Value"); | ||
| 489 | plist_add_sub_node(dict, value); | ||
| 490 | |||
| 491 | /* send to device */ | ||
| 492 | ret = lockdownd_send(client, dict); | ||
| 493 | |||
| 494 | plist_free(dict); | ||
| 495 | dict = NULL; | ||
| 496 | |||
| 497 | if (ret != IPHONE_E_SUCCESS) | ||
| 498 | return ret; | ||
| 499 | |||
| 500 | /* Now get device's answer */ | ||
| 501 | ret = lockdownd_recv(client, &dict); | ||
| 502 | if (ret != IPHONE_E_SUCCESS) | ||
| 503 | return ret; | ||
| 504 | |||
| 505 | if (lockdown_check_result(dict, "SetValue") == RESULT_SUCCESS) { | ||
| 506 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); | ||
| 507 | ret = IPHONE_E_SUCCESS; | ||
| 508 | } | ||
| 509 | |||
| 510 | if (ret != IPHONE_E_SUCCESS) { | ||
| 511 | plist_free(dict); | ||
| 512 | return ret; | ||
| 513 | } | ||
| 514 | |||
| 515 | plist_free(dict); | ||
| 516 | return ret; | ||
| 517 | } | ||
| 518 | |||
| 519 | /** Removes a preference node on the device by domain and/or key name | ||
| 520 | * | ||
| 521 | * @note: Use with caution as this could remove vital information on the device | ||
| 522 | * | ||
| 523 | * @param client an initialized lockdownd client. | ||
| 524 | * @param domain the domain to query on or NULL for global domain | ||
| 525 | * @param key the key name to remove or NULL remove all keys for the current domain | ||
| 526 | * | ||
| 527 | * @return an error code (IPHONE_E_SUCCESS on success) | ||
| 528 | */ | ||
| 529 | iphone_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key) | ||
| 530 | { | ||
| 531 | if (!client) | ||
| 532 | return IPHONE_E_INVALID_ARG; | ||
| 533 | |||
| 534 | plist_t dict = NULL; | ||
| 535 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | ||
| 536 | |||
| 537 | /* setup request plist */ | ||
| 538 | dict = plist_new_dict(); | ||
| 539 | if (domain) { | ||
| 540 | plist_add_sub_key_el(dict, "Domain"); | ||
| 541 | plist_add_sub_string_el(dict, domain); | ||
| 542 | } | ||
| 543 | if (key) { | ||
| 544 | plist_add_sub_key_el(dict, "Key"); | ||
| 545 | plist_add_sub_string_el(dict, key); | ||
| 546 | } | ||
| 547 | plist_add_sub_key_el(dict, "Request"); | ||
| 548 | plist_add_sub_string_el(dict, "RemoveValue"); | ||
| 549 | |||
| 550 | /* send to device */ | ||
| 551 | ret = lockdownd_send(client, dict); | ||
| 552 | |||
| 553 | plist_free(dict); | ||
| 554 | dict = NULL; | ||
| 555 | |||
| 556 | if (ret != IPHONE_E_SUCCESS) | ||
| 557 | return ret; | ||
| 558 | |||
| 559 | /* Now get device's answer */ | ||
| 560 | ret = lockdownd_recv(client, &dict); | ||
| 561 | if (ret != IPHONE_E_SUCCESS) | ||
| 562 | return ret; | ||
| 563 | |||
| 564 | if (lockdown_check_result(dict, "RemoveValue") == RESULT_SUCCESS) { | ||
| 565 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); | ||
| 566 | ret = IPHONE_E_SUCCESS; | ||
| 567 | } | ||
| 568 | |||
| 569 | if (ret != IPHONE_E_SUCCESS) { | ||
| 570 | plist_free(dict); | ||
| 571 | return ret; | ||
| 572 | } | ||
| 573 | |||
| 574 | plist_free(dict); | ||
| 575 | return ret; | ||
| 576 | } | ||
| 577 | |||
| 458 | /** Asks for the device's unique id. Part of the lockdownd handshake. | 578 | /** Asks for the device's unique id. Part of the lockdownd handshake. |
| 459 | * | 579 | * |
| 460 | * @return an error code (IPHONE_E_SUCCESS on success) | 580 | * @return an error code (IPHONE_E_SUCCESS on success) |
| @@ -672,6 +792,41 @@ iphone_error_t lockdownd_pair(lockdownd_client_t client, char *uid, char *host_i | |||
| 672 | } | 792 | } |
| 673 | 793 | ||
| 674 | /** | 794 | /** |
| 795 | * Tells the device to immediately enter recovery mode. | ||
| 796 | * | ||
| 797 | * @param client The lockdown client | ||
| 798 | * | ||
| 799 | * @return an error code (IPHONE_E_SUCCESS on success) | ||
| 800 | */ | ||
| 801 | iphone_error_t lockdownd_enter_recovery(lockdownd_client_t client) | ||
| 802 | { | ||
| 803 | if (!client) | ||
| 804 | return IPHONE_E_INVALID_ARG; | ||
| 805 | |||
| 806 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | ||
| 807 | |||
| 808 | plist_t dict = plist_new_dict(); | ||
| 809 | plist_add_sub_key_el(dict, "Request"); | ||
| 810 | plist_add_sub_string_el(dict, "EnterRecovery"); | ||
| 811 | |||
| 812 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: Telling device to enter recovery mode\n", __func__); | ||
| 813 | |||
| 814 | ret = lockdownd_send(client, dict); | ||
| 815 | plist_free(dict); | ||
| 816 | dict = NULL; | ||
| 817 | |||
| 818 | ret = lockdownd_recv(client, &dict); | ||
| 819 | |||
| 820 | if (lockdown_check_result(dict, "EnterRecovery") == RESULT_SUCCESS) { | ||
| 821 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: success\n", __func__); | ||
| 822 | ret = IPHONE_E_SUCCESS; | ||
| 823 | } | ||
| 824 | plist_free(dict); | ||
| 825 | dict = NULL; | ||
| 826 | return ret; | ||
| 827 | } | ||
| 828 | |||
| 829 | /** | ||
| 675 | * Performs the Goodbye Request to tell the device the communication | 830 | * Performs the Goodbye Request to tell the device the communication |
| 676 | * session is now closed. | 831 | * session is now closed. |
| 677 | * | 832 | * |
