diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile.am | 2 | ||||
-rw-r--r-- | src/activate.c | 254 | ||||
-rw-r--r-- | src/activate.h | 30 | ||||
-rw-r--r-- | src/idevicerestore.c | 2 |
4 files changed, 286 insertions, 2 deletions
diff --git a/src/Makefile.am b/src/Makefile.am index 6840a0c..b641d00 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -18,6 +18,6 @@ AM_LDFLAGS =\ bin_PROGRAMS = idevicerestore -idevicerestore_SOURCES = idevicerestore.c dfu.c tss.c img3.c ipsw.c normal.c restore.c recovery.c +idevicerestore_SOURCES = idevicerestore.c dfu.c tss.c img3.c ipsw.c normal.c restore.c recovery.c activate.c idevicerestore_CFLAGS = $(AM_CFLAGS) idevicerestore_LDFLAGS = $(AM_LDFLAGS)
\ No newline at end of file diff --git a/src/activate.c b/src/activate.c new file mode 100644 index 0000000..2cb4452 --- /dev/null +++ b/src/activate.c @@ -0,0 +1,254 @@ +/* + * activate.c + * Functions to fetch activation records from Apple's servers + * + * Copyright (c) 2010 Joshua Hill. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <curl/curl.h> +#include <plist/plist.h> +#include <libimobiledevice/lockdown.h> + +typedef struct { + int length; + char* content; +} activate_response; + +size_t activate_write_callback(char* data, size_t size, size_t nmemb, activate_response* response) { + size_t total = size * nmemb; + if (total != 0) { + response->content = realloc(response->content, response->length + total + 1); + memcpy(response->content + response->length, data, total); + response->content[response->length + total] = '\0'; + response->length += total; + } + //printf("%s", data); + return total; +} + +int activate_fetch_record(lockdownd_client_t client, plist_t* record) { + int size = 0; + char* request = NULL; + struct curl_httppost* post = NULL; + struct curl_httppost* last = NULL; + activate_response* response = NULL; + + char* imei = NULL; + char* imsi = NULL; + char* iccid = NULL; + char* serial_number = NULL; + char* activation_info = NULL; + + plist_t imei_node = NULL; + plist_t imsi_node = NULL; + plist_t iccid_node = NULL; + plist_t serial_number_node = NULL; + plist_t activation_info_node = NULL; + + char* device_class = NULL; + plist_t device_class_node = NULL; + lockdownd_get_value(client, NULL, "DeviceClass", &device_class_node); + if (!device_class_node || plist_get_node_type(device_class_node) != PLIST_STRING) { + fprintf(stderr, "Unable to get DeviceClass from lockdownd\n"); + return -1; + } + plist_get_string_val(device_class_node, &device_class); + plist_free(device_class_node); + + if (!strcmp(device_class, "iPhone")) { + lockdownd_get_value(client, NULL, "IntegratedCircuitCardIdentity", &iccid_node); + if (!iccid_node || plist_get_node_type(iccid_node) != PLIST_STRING) { + fprintf(stderr, "Unable to get ICCID from lockdownd\n"); + return -1; + } + plist_get_string_val(iccid_node, &iccid); + plist_free(iccid_node); + + lockdownd_get_value(client, NULL, "InternationalMobileEquipmentIdentity", &imei_node); + if (!imei_node || plist_get_node_type(imei_node) != PLIST_STRING) { + fprintf(stderr, "Unable to get IMEI from lockdownd\n"); + return -1; + } + plist_get_string_val(imei_node, &imei); + plist_free(imei_node); + + lockdownd_get_value(client, NULL, "InternationalMobileSubscriberIdentity", &imsi_node); + if (!imsi_node || plist_get_node_type(imsi_node) != PLIST_STRING) { + fprintf(stderr, "Unable to get IMSI from lockdownd\n"); + return -1; + } + plist_get_string_val(imsi_node, &imsi); + plist_free(imsi_node); + } + + lockdownd_get_value(client, NULL, "SerialNumber", &serial_number_node); + if (!serial_number_node || plist_get_node_type(serial_number_node) != PLIST_STRING) { + fprintf(stderr, "Unable to get SerialNumber from lockdownd\n"); + return -1; + } + plist_get_string_val(serial_number_node, &serial_number); + plist_free(serial_number_node); + + lockdownd_get_value(client, NULL, "ActivationInfo", &activation_info_node); + int type = plist_get_node_type(activation_info_node); + if (!activation_info_node || plist_get_node_type(activation_info_node) != PLIST_DICT) { + fprintf(stderr, "Unable to get ActivationInfo from lockdownd\n"); + return -1; + } + //plist_get_string_val(activation_info_node, &activation_info); + + uint32_t activation_info_size = 0; + char* activation_info_data = NULL; + plist_to_xml(activation_info_node, &activation_info_data, &activation_info_size); + plist_free(activation_info_node); + //printf("%s\n\n", activation_info_data); + + char* activation_info_start = strstr(activation_info_data, "<dict>"); + if (activation_info_start == NULL) { + fprintf(stderr, "Unable to locate beginning of ActivationInfo\n"); + return -1; + } + + char* activation_info_stop = strstr(activation_info_data, "</dict>"); + if (activation_info_stop == NULL) { + fprintf(stderr, "Unable to locate end of ActivationInfo\n"); + return -1; + } + + activation_info_stop += strlen("</dict>"); + activation_info_size = activation_info_stop - activation_info_start; + activation_info = malloc(activation_info_size + 1); + memset(activation_info, '\0', activation_info_size + 1); + memcpy(activation_info, activation_info_start, activation_info_size); + free(activation_info_data); + + curl_global_init(CURL_GLOBAL_ALL); + CURL* handle = curl_easy_init(); + if (handle == NULL) { + fprintf(stderr, "Unable to initialize libcurl\n"); + curl_global_cleanup(); + return -1; + } + + curl_formadd(&post, &last, CURLFORM_COPYNAME, "machineName", CURLFORM_COPYCONTENTS, "linux", CURLFORM_END); + curl_formadd(&post, &last, CURLFORM_COPYNAME, "InStoreActivation", CURLFORM_COPYCONTENTS, "false", CURLFORM_END); + if (imei != NULL) { + curl_formadd(&post, &last, CURLFORM_COPYNAME, "IMEI", CURLFORM_COPYCONTENTS, imei, CURLFORM_END); + free(imei); + } + + if (imsi != NULL) { + curl_formadd(&post, &last, CURLFORM_COPYNAME, "IMSI", CURLFORM_COPYCONTENTS, imsi, CURLFORM_END); + free(imsi); + } + + if (iccid != NULL) { + curl_formadd(&post, &last, CURLFORM_COPYNAME, "ICCID", CURLFORM_COPYCONTENTS, iccid, CURLFORM_END); + free(iccid); + } + + if (serial_number != NULL) { + curl_formadd(&post, &last, CURLFORM_COPYNAME, "AppleSerialNumber", CURLFORM_COPYCONTENTS, serial_number, CURLFORM_END); + free(serial_number); + } + + if (activation_info != NULL) { + curl_formadd(&post, &last, CURLFORM_COPYNAME, "activation-info", CURLFORM_COPYCONTENTS, activation_info, CURLFORM_END); + free(activation_info); + } + + struct curl_slist* header = NULL; + header = curl_slist_append(header, "X-Apple-Tz: -14400"); + header = curl_slist_append(header, "X-Apple-Store-Front: 143441-1"); + + response = malloc(sizeof(activate_response)); + if (response == NULL) { + fprintf(stderr, "Unable to allocate sufficent memory\n"); + return -1; + } + + response->length = 0; + response->content = malloc(1); + + curl_easy_setopt(handle, CURLOPT_HTTPPOST, post); + curl_easy_setopt(handle, CURLOPT_HTTPHEADER, header); + curl_easy_setopt(handle, CURLOPT_WRITEDATA, response); + curl_easy_setopt(handle, CURLOPT_WRITEFUNCTION, &activate_write_callback); + curl_easy_setopt(handle, CURLOPT_USERAGENT, "iTunes/9.1 (Macintosh; U; Intel Mac OS X 10.5.6)"); + curl_easy_setopt(handle, CURLOPT_URL, "https://albert.apple.com/WebObjects/ALUnbrick.woa/wa/deviceActivation"); + + curl_easy_perform(handle); + curl_slist_free_all(header); + curl_easy_cleanup(handle); + curl_global_cleanup(); + + uint32_t ticket_size = response->length; + char* ticket_data = response->content; + + char* ticket_start = strstr(ticket_data, "<plist"); + if (ticket_start == NULL) { + fprintf(stderr, "Unable to locate beginning of ActivationInfo\n"); + return -1; + } + + char* ticket_stop = strstr(ticket_data, "</plist>"); + if (ticket_stop == NULL) { + fprintf(stderr, "Unable to locate end of ActivationInfo\n"); + return -1; + } + + ticket_stop += strlen("</plist>"); + ticket_size = ticket_stop - ticket_start; + char* ticket = malloc(ticket_size + 1); + memset(ticket, '\0', ticket_size + 1); + memcpy(ticket, ticket_start, ticket_size); + //free(ticket_data); + + //printf("%s\n\n", ticket); + + plist_t ticket_dict = NULL; + plist_from_xml(ticket, ticket_size, &ticket_dict); + if (ticket_dict == NULL) { + printf("Unable to convert activation ticket into plist\n"); + return -1; + } + + plist_t iphone_activation_node = plist_dict_get_item(ticket_dict, "iphone-activation"); + if (!iphone_activation_node) { + iphone_activation_node = plist_dict_get_item(ticket_dict, "device-activation"); + if (!iphone_activation_node) { + printf("Unable to find device activation node\n"); + return -1; + } + } + + plist_t activation_record = plist_dict_get_item(iphone_activation_node, "activation-record"); + if (!activation_record) { + printf("Unable to find activation record node"); + return -1; + } + + *record = plist_copy(activation_record); + + //free(response->content); + //free(response); + //free(request); + return 0; +} diff --git a/src/activate.h b/src/activate.h new file mode 100644 index 0000000..1feb11e --- /dev/null +++ b/src/activate.h @@ -0,0 +1,30 @@ +/* + * activate.h + * Functions to fetch activation records from Apple's servers + * + * Copyright (c) 2010 Joshua Hill. All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ACTIVATE_H +#define ACTIVATE_H + +#include <plist/plist.h> +#include <libimobiledevice/lockdown.h> + +int activate_fetch_record(lockdownd_client_t lockdown, plist_t* record); + +#endif diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 7d382eb..4494f04 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -302,7 +302,7 @@ plist_t get_build_identity(plist_t buildmanifest, uint32_t identity) { return NULL; } - return plist_copy(build_identity); + return build_identity; } int extract_filesystem(const char* ipsw, plist_t build_identity, char** filesystem) { |