diff options
| author | 2012-02-02 21:35:22 +0100 | |
|---|---|---|
| committer | 2012-02-02 21:35:22 +0100 | |
| commit | 25652afe4c0cb323b16e5666e2cc8372f320f49a (patch) | |
| tree | 6cb88e0e1bcd97d6f90f31031beeefc5f09465de | |
| parent | bc6550dbbcddb3bc04b1d624881fa31b6b2ab881 (diff) | |
| download | idevicerestore-25652afe4c0cb323b16e5666e2cc8372f320f49a.tar.gz idevicerestore-25652afe4c0cb323b16e5666e2cc8372f320f49a.tar.bz2 | |
main: fix mode handling code
| -rw-r--r-- | src/idevicerestore.c | 92 | 
1 files changed, 90 insertions, 2 deletions
| diff --git a/src/idevicerestore.c b/src/idevicerestore.c index 0edec02..ef821f8 100644 --- a/src/idevicerestore.c +++ b/src/idevicerestore.c @@ -257,6 +257,7 @@ int main(int argc, char* argv[]) {  	// if the device is in DFU mode, place device into recovery mode  	if (client->mode->index == MODE_DFU) { +		recovery_client_free(client);  		if (dfu_enter_recovery(client, build_identity) < 0) {  			error("ERROR: Unable to place device into recovery mode\n");  			plist_free(buildmanifest); @@ -266,7 +267,66 @@ int main(int argc, char* argv[]) {  		}  	} -	// if the device is in recovery mode, place device into restore mode +	if (client->mode->index == MODE_DFU) { +		client->mode = &idevicerestore_modes[MODE_RECOVERY]; +	} else { +		/* now we load the iBEC */ +		if (recovery_send_ibec(client, build_identity) < 0) { +			error("ERROR: Unable to send iBEC\n"); +			return -1; +		} +		recovery_client_free(client); +	 +		/* this must be long enough to allow the device to run the iBEC */ +		/* FIXME: Probably better to detect if the device is back then */ +		sleep(7); +	} + +	if (client->build[0] > '8') { +		// we need another tss request with nonce. +		unsigned char* nonce = NULL; +		int nonce_size = 0; +		int nonce_changed = 0; +		if (get_nonce(client, &nonce, &nonce_size) < 0) { +			error("ERROR: Unable to get nonce from device!\n"); +			recovery_send_reset(client); +			return -1; +		} + +		if (!client->nonce || (nonce_size != client->nonce_size) || (memcmp(nonce, client->nonce, nonce_size) != 0)) { +			nonce_changed = 1; +			if (client->nonce) { +				free(client->nonce); +			} +			client->nonce = nonce; +			client->nonce_size = nonce_size; +		} else { +			free(nonce); +		} + +		info("Nonce: "); +		int i; +		for (i = 0; i < client->nonce_size; i++) { +			info("%02x ", client->nonce[i]); +		} +		info("\n"); + +		if (nonce_changed && !(client->flags & FLAG_CUSTOM)) { +			// Welcome iOS5. We have to re-request the TSS with our nonce. +			plist_free(client->tss); +			if (get_shsh_blobs(client, client->ecid, client->nonce, client->nonce_size, build_identity, &client->tss) < 0) { +				error("ERROR: Unable to get SHSH blobs for this device\n"); +				return -1; +			} +			if (!client->tss) { +				error("ERROR: can't continue without TSS\n"); +				return -1; +			} +			fixup_tss(client->tss); +		} +	} + +	// now finally do the magic to put the device into restore mode  	if (client->mode->index == MODE_RECOVERY) {  		if (recovery_enter_restore(client, build_identity) < 0) {  			error("ERROR: Unable to place device into restore mode\n"); @@ -279,7 +339,7 @@ int main(int argc, char* argv[]) {  	// device is finally in restore mode, let's do this  	if (client->mode->index == MODE_RESTORE) { -		info("Restoring device... \n"); +		info("About to restore device... \n");  		if (restore_device(client, build_identity, filesystem) < 0) {  			error("ERROR: Unable to restore device\n");  			return -1; @@ -535,6 +595,34 @@ int get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) {  	return 0;  } +int get_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size) { +	*nonce = NULL; +	*nonce_size = 0; + +	switch (client->mode->index) { +	case MODE_NORMAL: +		error("ERROR: Can't get nonce in Normal mode\n"); +		return -1; +	case MODE_DFU: +		if (dfu_get_nonce(client, nonce, nonce_size) < 0) { +			return -1; +		} +		break; +	case MODE_RECOVERY: +		if (recovery_get_nonce(client, nonce, nonce_size) < 0) { +			return -1; +		} +		break; + +	default: +		error("ERROR: Device is in an invalid state\n"); +		return -1; +	} + +	return 0; +} + +  plist_t build_manifest_get_build_identity(plist_t build_manifest, uint32_t identity) {  	// fetch build identities array from BuildManifest  	plist_t build_identities_array = plist_dict_get_item(build_manifest, "BuildIdentities"); | 
