diff options
Diffstat (limited to 'src/asr.c')
-rw-r--r-- | src/asr.c | 104 |
1 files changed, 34 insertions, 70 deletions
@@ -30,23 +30,16 @@ #include <unistd.h> #include <errno.h> #include <libimobiledevice/libimobiledevice.h> -#ifdef HAVE_OPENSSL -#include <openssl/sha.h> -#else -#include "sha1.h" -#define SHA_CTX SHA1_CTX -#define SHA1_Init SHA1Init -#define SHA1_Update SHA1Update -#define SHA1_Final SHA1Final -#endif + +#include <libimobiledevice-glue/sha.h> #include "asr.h" #include "idevicerestore.h" #include "common.h" +#include "ipsw.h" #define ASR_VERSION 1 #define ASR_STREAM_ID 1 -#define ASR_PORT 12345 #define ASR_BUFFER_SIZE 65536 #define ASR_FEC_SLICE_STRIDE 40 #define ASR_PACKETS_PER_FEC 25 @@ -54,7 +47,7 @@ #define ASR_PAYLOAD_CHUNK_SIZE 131072 #define ASR_CHECKSUM_CHUNK_SIZE 131072 -int asr_open_with_timeout(idevice_t device, asr_client_t* asr) +int asr_open_with_timeout(idevice_t device, asr_client_t* asr, uint16_t port) { int i = 0; int attempts = 10; @@ -67,9 +60,13 @@ int asr_open_with_timeout(idevice_t device, asr_client_t* asr) return -1; } - debug("Connecting to ASR\n"); + if (port == 0) { + port = ASR_DEFAULT_PORT; + } + debug("Connecting to ASR on port %u\n", port); + for (i = 1; i <= attempts; i++) { - device_error = idevice_connect(device, ASR_PORT, &connection); + device_error = idevice_connect(device, port, &connection); if (device_error == IDEVICE_E_SUCCESS) { break; } @@ -205,9 +202,8 @@ void asr_free(asr_client_t asr) } } -int asr_perform_validation(asr_client_t asr, const char* filesystem) +int asr_perform_validation(asr_client_t asr, ipsw_file_handle_t file) { - FILE* file = NULL; uint64_t length = 0; char* command = NULL; plist_t node = NULL; @@ -216,20 +212,7 @@ int asr_perform_validation(asr_client_t asr, const char* filesystem) plist_t payload_info = NULL; int attempts = 0; - file = fopen(filesystem, "rb"); - if (file == NULL) { - return -1; - } - -#ifdef WIN32 - length = _lseeki64(fileno(file), 0, SEEK_END); - _lseeki64(fileno(file), 0, SEEK_SET); - rewind(file); -#else - fseeko(file, 0, SEEK_END); - length = ftello(file); - fseeko(file, 0, SEEK_SET); -#endif + length = ipsw_file_size(file); payload_info = plist_new_dict(); plist_dict_set_item(payload_info, "Port", plist_new_uint(1)); @@ -296,7 +279,7 @@ int asr_perform_validation(asr_client_t asr, const char* filesystem) return 0; } -int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, FILE* file) +int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, ipsw_file_handle_t file) { char* oob_data = NULL; uint64_t oob_offset = 0; @@ -324,14 +307,14 @@ int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, FILE* file) return -1; } -#ifdef WIN32 - rewind(file); - _lseeki64(fileno(file), oob_offset, SEEK_SET); -#else - fseeko(file, oob_offset, SEEK_SET); -#endif - if (fread(oob_data, 1, oob_length, file) != oob_length) { - error("ERROR: Unable to read OOB data from filesystem offset: %s\n", strerror(errno)); + if (ipsw_file_seek(file, oob_offset, SEEK_SET) < 0) { + error("ERROR: Unable to seek to OOB offset 0x%" PRIx64 "\n", oob_offset); + free(oob_data); + return -1; + } + int64_t ir = ipsw_file_read(file, oob_data, oob_length); + if (ir != oob_length) { + error("ERROR: Unable to read OOB data from filesystem offset 0x%" PRIx64 ", oob_length %" PRIu64 ", read returned %" PRIi64"\n", oob_offset, oob_length, ir); free(oob_data); return -1; } @@ -345,58 +328,40 @@ int asr_handle_oob_data_request(asr_client_t asr, plist_t packet, FILE* file) return 0; } -int asr_send_payload(asr_client_t asr, const char* filesystem) +int asr_send_payload(asr_client_t asr, ipsw_file_handle_t file) { char *data = NULL; - FILE* file = NULL; uint64_t i, length, bytes = 0; double progress = 0; - file = fopen(filesystem, "rb"); - if (file == NULL) { - error("ERROR: Unable to open filesystem image %s: %s\n", filesystem, strerror(errno)); - return -1; - } - -#ifdef WIN32 - length = _lseeki64(fileno(file), 0, SEEK_END); - _lseeki64(fileno(file), 0, SEEK_SET); - rewind(file); -#else - fseeko(file, 0, SEEK_END); - length = ftello(file); - fseeko(file, 0, SEEK_SET); -#endif + length = ipsw_file_size(file); + ipsw_file_seek(file, 0, SEEK_SET); data = (char*)malloc(ASR_PAYLOAD_CHUNK_SIZE + 20); - SHA_CTX sha1; - - if (asr->checksum_chunks) { - SHA1_Init(&sha1); - } - - int size = 0; i = length; int retry = 3; while(i > 0 && retry >= 0) { - size = ASR_PAYLOAD_CHUNK_SIZE; + uint32_t size = ASR_PAYLOAD_CHUNK_SIZE; + uint32_t sendsize = 0; + if (i < ASR_PAYLOAD_CHUNK_SIZE) { size = i; } - if (fread(data, 1, size, file) != (size_t)size) { + if (ipsw_file_read(file, data, size) != (int64_t)size) { error("Error reading filesystem\n"); retry--; continue; } + sendsize = size; if (asr->checksum_chunks) { - SHA1((unsigned char*)data, size, (unsigned char*)(data+size)); + sha1((unsigned char*)data, size, (unsigned char*)(data+size)); + sendsize += 20; } - - if (asr_send_buffer(asr, data, size+20) < 0) { - error("ERROR: Unable to send filesystem payload\n"); + if (asr_send_buffer(asr, data, sendsize) < 0) { + error("Unable to send filesystem payload chunk, retrying...\n"); retry--; continue; } @@ -412,6 +377,5 @@ int asr_send_payload(asr_client_t asr, const char* filesystem) } free(data); - fclose(file); - return 0; + return (i == 0) ? 0 : -1; } |