From b7feed9f5a62833c1df3f503fd3693e2ed2e4738 Mon Sep 17 00:00:00 2001 From: Nikias Bassen Date: Thu, 7 Dec 2017 16:48:36 +0700 Subject: mobileactivation: Allow passing activation response headers as required for iOS 11.2+ When activating in session mode - which is required for newer iOS versions - we can now pass the activation response headers with the activation command. For iOS 11.2+ this is mandatory or the activation will fail. --- include/libimobiledevice/mobileactivation.h | 8 ++-- src/mobileactivation.c | 60 +++++++++++++++++++++-------- 2 files changed, 50 insertions(+), 18 deletions(-) diff --git a/include/libimobiledevice/mobileactivation.h b/include/libimobiledevice/mobileactivation.h index bb1f3f4..b7f8064 100644 --- a/include/libimobiledevice/mobileactivation.h +++ b/include/libimobiledevice/mobileactivation.h @@ -164,16 +164,18 @@ mobileactivation_error_t mobileactivation_activate(mobileactivation_client_t cli /** * Activates the device with the given activation record in 'session' mode. - * The activation record plist dictionary must be obtained using the + * The activation record plist must be obtained using the * activation protocol requesting from Apple's https webservice. * * @param client The mobileactivation client - * @param activation_record The activation record plist dictionary + * @param activation_record The activation record in plist format + * @param headers A plist dictionary with the activation response headers + * as returned from Apple's https webservice with the activation record * * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_* * error code otherwise. */ -mobileactivation_error_t mobileactivation_activate_with_session(mobileactivation_client_t client, plist_t activation_record); +mobileactivation_error_t mobileactivation_activate_with_session(mobileactivation_client_t client, plist_t activation_record, plist_t headers); /** * Deactivates the device. diff --git a/src/mobileactivation.c b/src/mobileactivation.c index 433497a..010484e 100644 --- a/src/mobileactivation.c +++ b/src/mobileactivation.c @@ -124,6 +124,38 @@ static mobileactivation_error_t mobileactivation_check_result(plist_t dict, cons return ret; } +static mobileactivation_error_t mobileactivation_send_command_plist(mobileactivation_client_t client, plist_t command, plist_t *result) +{ + if (!client || !command) + return MOBILEACTIVATION_E_INVALID_ARG; + + plist_t cmd = plist_dict_get_item(command, "Command"); + char* command_str = NULL; + if (cmd) { + plist_get_string_val(cmd, &command_str); + } + if (!command_str) + return MOBILEACTIVATION_E_INVALID_ARG; + + mobileactivation_error_t ret = MOBILEACTIVATION_E_UNKNOWN_ERROR; + *result = NULL; + + ret = mobileactivation_error(property_list_service_send_binary_plist(client->parent, command)); + + plist_t dict = NULL; + ret = mobileactivation_error(property_list_service_receive_plist(client->parent, &dict)); + if (!dict) { + debug_info("ERROR: Did not get reply for %s command", command_str); + free(command_str); + return MOBILEACTIVATION_E_PLIST_ERROR; + } + + *result = dict; + ret = mobileactivation_check_result(dict, command_str); + free(command_str); + return ret; +} + static mobileactivation_error_t mobileactivation_send_command(mobileactivation_client_t client, const char* command, plist_t value, plist_t *result) { if (!client || !command || !result) @@ -138,18 +170,9 @@ static mobileactivation_error_t mobileactivation_send_command(mobileactivation_c plist_dict_set_item(dict, "Value", plist_copy(value)); } - ret = mobileactivation_error(property_list_service_send_binary_plist(client->parent, dict)); + ret = mobileactivation_send_command_plist(client, dict, result); plist_free(dict); - dict = NULL; - - ret = mobileactivation_error(property_list_service_receive_plist(client->parent, &dict)); - if (!dict) { - debug_info("ERROR: Did not get reply for %s command", command); - return MOBILEACTIVATION_E_PLIST_ERROR; - } - - *result = dict; - return mobileactivation_check_result(dict, command); + return ret; } LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_get_activation_state(mobileactivation_client_t client, plist_t *state) @@ -253,15 +276,22 @@ LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_activate(mobileac return ret; } -LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_activate_with_session(mobileactivation_client_t client, plist_t activation_record) +LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_activate_with_session(mobileactivation_client_t client, plist_t activation_record, plist_t headers) { if (!client || !activation_record) return MOBILEACTIVATION_E_INVALID_ARG; plist_t result = NULL; - plist_t data = plist_data_from_plist(activation_record); - mobileactivation_error_t ret = mobileactivation_send_command(client, "HandleActivationInfoWithSessionRequest", data, &result); - plist_free(data); + + plist_t dict = plist_new_dict(); + plist_dict_set_item(dict, "Command", plist_new_string("HandleActivationInfoWithSessionRequest")); + plist_dict_set_item(dict, "Value", plist_data_from_plist(activation_record)); + if (headers) { + plist_dict_set_item(dict, "ActivationResponseHeaders", plist_copy(headers)); + } + + mobileactivation_error_t ret = mobileactivation_send_command_plist(client, dict, &result); + plist_free(dict); plist_free(result); result = NULL; -- cgit v1.1-32-gdbae