summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/idevicerestore.c46
1 files changed, 45 insertions, 1 deletions
diff --git a/src/idevicerestore.c b/src/idevicerestore.c
index f1d441a..ca3c94c 100644
--- a/src/idevicerestore.c
+++ b/src/idevicerestore.c
@@ -49,6 +49,7 @@ static struct option longopts[] = {
{ "custom", no_argument, NULL, 'c' },
{ "cydia", no_argument, NULL, 's' },
{ "exclude", no_argument, NULL, 'x' },
+ { "shsh", no_argument, NULL, 't' },
{ NULL, 0, NULL, 0 }
};
@@ -63,6 +64,7 @@ void usage(int argc, char* argv[]) {
printf(" -c, --custom\t\trestore with a custom firmware\n");
printf(" -s, --cydia\t\tuse Cydia's signature service instead of Apple's\n");
printf(" -x, --exclude\t\texclude nor/baseband upgrade\n");
+ printf(" -t, --shsh\t\tfetch TSS record and save to .shsh file, then exit\n");
printf("\n");
}
@@ -72,6 +74,8 @@ int main(int argc, char* argv[]) {
char* ipsw = NULL;
char* uuid = NULL;
int tss_enabled = 0;
+ int shsh_only = 0;
+ char* shsh_dir = NULL;
use_apple_server=1;
// create an instance of our context
@@ -82,7 +86,7 @@ int main(int argc, char* argv[]) {
}
memset(client, '\0', sizeof(struct idevicerestore_client_t));
- while ((opt = getopt_long(argc, argv, "dhcesxu:", longopts, &optindex)) > 0) {
+ while ((opt = getopt_long(argc, argv, "dhcesxtu:", longopts, &optindex)) > 0) {
switch (opt) {
case 'h':
usage(argc, argv);
@@ -112,6 +116,10 @@ int main(int argc, char* argv[]) {
uuid = optarg;
break;
+ case 't':
+ shsh_only = 1;
+ break;
+
default:
usage(argc, argv);
return -1;
@@ -372,6 +380,42 @@ int main(int argc, char* argv[]) {
}
}
+ if (shsh_only) {
+ if (!tss_enabled) {
+ info("This device does not require a TSS record");
+ return 0;
+ }
+ if (!client->tss) {
+ error("ERROR: could not fetch TSS record");
+ plist_free(buildmanifest);
+ return -1;
+ } else {
+ char *bin = NULL;
+ uint32_t blen = 0;
+ plist_to_bin(client->tss, &bin, &blen);
+ if (bin) {
+ char zfn[512];
+ sprintf(zfn, "shsh/%lld-%s-%s.shsh", (long long int)client->ecid, client->device->product, client->version);
+ mkdir("shsh", 0755);
+ struct stat fst;
+ if (stat(zfn, &fst) != 0) {
+ gzFile zf = gzopen(zfn, "wb");
+ gzwrite(zf, bin, blen);
+ gzclose(zf);
+ info("SHSH saved to '%s'\n", zfn);
+ } else {
+ info("SHSH '%s' already present.\n", zfn);
+ }
+ free(bin);
+ } else {
+ error("ERROR: could not get TSS record data\n");
+ }
+ plist_free(client->tss);
+ plist_free(buildmanifest);
+ return 0;
+ }
+ }
+
/* verify if we have tss records if required */
if ((tss_enabled) && (client->tss == NULL)) {
error("ERROR: Unable to proceed without a TSS record.\n");