SWIGEXPORT jshort JNICALL Java_org_robovm_libimobiledevice_binding_libimobiledeviceJNI_lockdownd_1get_1value(JNIEnv *jenv, jclass jcls, jlong jarg1, jstring jarg2, jstring jarg3, jlong jarg4) { jshort jresult = 0 ; lockdownd_client_t arg1 = (lockdownd_client_t) 0 ; char *arg2 = (char *) 0 ; char *arg3 = (char *) 0 ; plist_t *arg4 = (plist_t *) 0 ; lockdownd_error_t result; (void)jenv; (void)jcls; arg1 = *(lockdownd_client_t *)&jarg1; arg2 = 0; if (jarg2) { arg2 = (char *)(*jenv)->GetStringUTFChars(jenv, jarg2, 0); if (!arg2) return 0; } arg3 = 0; if (jarg3) { arg3 = (char *)(*jenv)->GetStringUTFChars(jenv, jarg3, 0); if (!arg3) return 0; } arg4 = *(plist_t **)&jarg4; result = (lockdownd_error_t)lockdownd_get_value(arg1,(char const *)arg2,(char const *)arg3,arg4); jresult = (jshort)result; if (arg2) (*jenv)->ReleaseStringUTFChars(jenv, jarg2, (const char *)arg2); if (arg3) (*jenv)->ReleaseStringUTFChars(jenv, jarg3, (const char *)arg3); return jresult; }
FB::variant ibrowserAPI::getDeviceInfo(const std::vector<std::string>& domains,F_ADD) { THREAD(&ibrowserAPI::getDeviceInfo, domains); std::vector<std::string> result; for(int i=0;i<domains.size();i++) { std::string domain = domains[i]; plist_t node = NULL; int ret = 0; if(LOCKDOWN_E_SUCCESS != (ret = lockdownd_get_value(lockdownd_client, domain.empty()?NULL:domain.c_str(), NULL, &node)) ) { ERRO("lockdownd_get_value"); } char *xml_doc=NULL; uint32_t xml_length; plist_to_xml(node, &xml_doc, &xml_length); plist_free(node); result.insert(result.end(),std::string(xml_doc)); free(xml_doc); } SUCC(result); return result; }
int fill_in_info() { plist_t *node=NULL; char* type=NULL; char* version=NULL; char* name=NULL; char* img=NULL; lockdownd_get_device_name(client, &name); lockdownd_get_value(client, NULL, "ProductType", &node); plist_get_string_val(node, &type); plist_free(node); node=NULL; lockdownd_get_value(client, NULL, "ProductVersion", &node); plist_get_string_val(node, &version); plist_free(node); node=NULL; plist_from_xml(img_plist, strlen(img_plist), &node); plist_t devNode=plist_dict_get_item(node, type); if (!devNode) { printf("ERROR: Unknown device!\n"); } plist_get_string_val(devNode, &img); plist_free(node); node=NULL; strcpy(data, ""); gtk_image_set_from_file(devImg, img); //gtk_label_set_use_underline(dName, TRUE); char devL[512]=""; snprintf(devL, 512, "<b>%s</b>", name); gtk_label_set_text(dName, name); gtk_label_set_markup(dName, devL); gtk_label_set_text(fV, version); return 0; }
LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_get_sync_data_classes(lockdownd_client_t client, char ***classes, int *count) { if (!client) return LOCKDOWN_E_INVALID_ARG; if (!client->session_id) return LOCKDOWN_E_NO_RUNNING_SESSION; plist_t dict = NULL; lockdownd_error_t err = LOCKDOWN_E_UNKNOWN_ERROR; plist_t value = NULL; char **newlist = NULL; char *val = NULL; *classes = NULL; *count = 0; err = lockdownd_get_value(client, "com.apple.mobile.iTunes", "SyncDataClasses", &dict); if (err != LOCKDOWN_E_SUCCESS) { if (dict) { plist_free(dict); } return err; } if (plist_get_node_type(dict) != PLIST_ARRAY) { plist_free(dict); return LOCKDOWN_E_PLIST_ERROR; } while((value = plist_array_get_item(dict, *count)) != NULL) { plist_get_string_val(value, &val); newlist = realloc(*classes, sizeof(char*) * (*count+1)); str_remove_spaces(val); if (asprintf(&newlist[*count], "com.apple.%s", val) < 0) { debug_info("ERROR: asprintf failed"); } free(val); val = NULL; *classes = newlist; *count = *count+1; } newlist = realloc(*classes, sizeof(char*) * (*count+1)); newlist[*count] = NULL; *classes = newlist; if (dict) { plist_free(dict); } return LOCKDOWN_E_SUCCESS; }
LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_get_device_udid(lockdownd_client_t client, char **udid) { lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; plist_t value = NULL; ret = lockdownd_get_value(client, NULL, "UniqueDeviceID", &value); if (ret != LOCKDOWN_E_SUCCESS) { return ret; } plist_get_string_val(value, udid); plist_free(value); value = NULL; return ret; }
int normal_check_device(struct idevicerestore_client_t* client) { int i = 0; idevice_t device = NULL; char* product_type = NULL; plist_t product_type_node = NULL; lockdownd_client_t lockdown = NULL; idevice_error_t device_error = IDEVICE_E_SUCCESS; lockdownd_error_t lockdown_error = IDEVICE_E_SUCCESS; normal_idevice_new(client, &device); if (!device) { return -1; } lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore"); if (lockdown_error != LOCKDOWN_E_SUCCESS) { idevice_free(device); return -1; } lockdown_error = lockdownd_get_value(lockdown, NULL, "ProductType", &product_type_node); if (lockdown_error != LOCKDOWN_E_SUCCESS) { lockdownd_client_free(lockdown); idevice_free(device); return -1; } lockdownd_client_free(lockdown); idevice_free(device); lockdown = NULL; device = NULL; if (!product_type_node || plist_get_node_type(product_type_node) != PLIST_STRING) { if (product_type_node) plist_free(product_type_node); return -1; } plist_get_string_val(product_type_node, &product_type); plist_free(product_type_node); for (i = 0; irecv_devices[i].product != NULL; i++) { if (!strcmp(product_type, irecv_devices[i].product)) { break; } } return irecv_devices[i].index; }
/** * Retrieves the name of the device from lockdownd set by the user. * * @param client An initialized lockdownd client. * @param device_name Holds the name of the device. The caller is * responsible for freeing the memory. * * @return LOCKDOWN_E_SUCCESS on success */ lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name) { lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; plist_t value = NULL; ret = lockdownd_get_value(client, NULL, "DeviceName", &value); if (ret != LOCKDOWN_E_SUCCESS) { return ret; } plist_get_string_val(value, device_name); plist_free(value); value = NULL; return ret; }
int normal_get_nonce(struct idevicerestore_client_t* client, unsigned char** nonce, int* nonce_size) { idevice_t device = NULL; plist_t nonce_node = NULL; lockdownd_client_t lockdown = NULL; idevice_error_t device_error = IDEVICE_E_SUCCESS; lockdownd_error_t lockdown_error = IDEVICE_E_SUCCESS; device_error = idevice_new(&device, client->udid); if (device_error != IDEVICE_E_SUCCESS) { return -1; } lockdown_error = lockdownd_client_new(device, &lockdown, "idevicerestore"); if (lockdown_error != LOCKDOWN_E_SUCCESS) { error("ERROR: Unable to connect to lockdownd\n"); idevice_free(device); return -1; } lockdown_error = lockdownd_get_value(lockdown, NULL, "ApNonce", &nonce_node); if (lockdown_error != LOCKDOWN_E_SUCCESS) { error("ERROR: Unable to get ApNonce from lockdownd\n"); lockdownd_client_free(lockdown); idevice_free(device); return -1; } if (!nonce_node || plist_get_node_type(nonce_node) != PLIST_DATA) { error("ERROR: Unable to get nonce\n"); lockdownd_client_free(lockdown); idevice_free(device); return -1; } uint64_t n_size = 0; plist_get_data_val(nonce_node, (char**)nonce, &n_size); *nonce_size = (int)n_size; plist_free(nonce_node); lockdownd_client_free(lockdown); idevice_free(device); lockdown = NULL; device = NULL; return 0; }
int normal_get_ecid(struct idevicerestore_client_t* client, uint64_t* ecid) { idevice_t device = NULL; plist_t unique_chip_node = NULL; lockdownd_client_t lockdown = NULL; idevice_error_t device_error = IDEVICE_E_SUCCESS; lockdownd_error_t lockdown_error = IDEVICE_E_SUCCESS; device_error = idevice_new(&device, client->uuid); if (device_error != IDEVICE_E_SUCCESS) { return -1; } lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore"); if (lockdown_error != LOCKDOWN_E_SUCCESS) { error("ERROR: Unable to connect to lockdownd\n"); idevice_free(device); return -1; } lockdown_error = lockdownd_get_value(lockdown, NULL, "UniqueChipID", &unique_chip_node); if (lockdown_error != LOCKDOWN_E_SUCCESS) { error("ERROR: Unable to get UniqueChipID from lockdownd\n"); lockdownd_client_free(lockdown); idevice_free(device); return -1; } if (!unique_chip_node || plist_get_node_type(unique_chip_node) != PLIST_UINT) { error("ERROR: Unable to get ECID\n"); lockdownd_client_free(lockdown); idevice_free(device); return -1; } plist_get_uint_val(unique_chip_node, ecid); plist_free(unique_chip_node); lockdownd_client_free(lockdown); idevice_free(device); lockdown = NULL; device = NULL; return 0; }
/** * Retrieves the public key of the device from lockdownd. * * @param client An initialized lockdownd client. * @param public_key Holds the public key of the device. The caller is * responsible for freeing the memory. * * @return LOCKDOWN_E_SUCCESS on success */ static lockdownd_error_t lockdownd_get_device_public_key_as_key_data(lockdownd_client_t client, key_data_t *public_key) { lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; plist_t value = NULL; char *value_value = NULL; uint64_t size = 0; ret = lockdownd_get_value(client, NULL, "DevicePublicKey", &value); if (ret != LOCKDOWN_E_SUCCESS) { return ret; } plist_get_data_val(value, &value_value, &size); public_key->data = (unsigned char*)value_value; public_key->size = size; plist_free(value); value = NULL; return ret; }
int main(int argc, char *argv[]) { lockdownd_client_t client = NULL; lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR; idevice_t device = NULL; idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; int i; const char* udid = NULL; time_t setdate = 0; plist_t node = NULL; int node_type = -1; uint64_t datetime = 0; time_t rawtime; struct tm * tmp; char const *format = NULL; char buffer[80]; int result = 0; /* parse cmdline args */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { idevice_set_debug_level(1); continue; } else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { i++; if (!argv[i] || (strlen(argv[i]) != 40)) { print_usage(argc, argv); return 0; } udid = argv[i]; continue; } else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--set")) { i++; if (!argv[i] || (strlen(argv[i]) <= 1)) { print_usage(argc, argv); return 0; } setdate = atoi(argv[i]); if (setdate == 0) { printf("ERROR: Invalid timestamp value.\n"); print_usage(argc, argv); return 0; } continue; } else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--sync")) { i++; /* get current time */ setdate = time(NULL); /* convert it to local time which sets timezone/daylight variables */ tmp = localtime(&setdate); /* recalculate to make it UTC */ setdate = mktime(tmp); continue; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { print_usage(argc, argv); return 0; } else { print_usage(argc, argv); return 0; } } /* determine a date format */ if (!format) { format = DATE_FMT_LANGINFO (); if (!*format) { format = "%a %b %e %H:%M:%S %Z %Y"; } } ret = idevice_new(&device, udid); if (ret != IDEVICE_E_SUCCESS) { if (udid) { printf("No device found with udid %s, is it plugged in?\n", udid); } else { printf("No device found, is it plugged in?\n"); } return -1; } if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &client, "idevicedate"))) { fprintf(stderr, "ERROR: Could not connect to lockdownd, error code %d\n", ldret); result = -1; goto cleanup; } if(lockdownd_get_value(client, NULL, "TimeIntervalSince1970", &node) != LOCKDOWN_E_SUCCESS) { fprintf(stderr, "ERROR: Unable to retrieve 'TimeIntervalSince1970' node from device.\n"); result = -1; goto cleanup; } if (node == NULL) { fprintf(stderr, "ERROR: Empty node for 'TimeIntervalSince1970' received.\n"); result = -1; goto cleanup; } node_type = plist_get_node_type(node); /* get or set? */ if (setdate == 0) { /* get time value from device */ switch (node_type) { case PLIST_UINT: plist_get_uint_val(node, &datetime); break; case PLIST_REAL: { double rv = 0; plist_get_real_val(node, &rv); datetime = rv; } break; default: fprintf(stderr, "ERROR: Unexpected node type for 'TimeIntervalSince1970'\n"); break; } plist_free(node); node = NULL; /* date/time calculations */ rawtime = (time_t)datetime; tmp = localtime(&rawtime); /* finally we format and print the current date */ strftime(buffer, 80, format, tmp); puts(buffer); } else { datetime = setdate; plist_free(node); node = NULL; switch (node_type) { case PLIST_UINT: node = plist_new_uint(datetime); break; case PLIST_REAL: node = plist_new_real((double)datetime); break; default: fprintf(stderr, "ERROR: Unexpected node type for 'TimeIntervalSince1970'\n"); break; } if(lockdownd_set_value(client, NULL, "TimeIntervalSince1970", node) == LOCKDOWN_E_SUCCESS) { tmp = localtime(&setdate); strftime(buffer, 80, format, tmp); puts(buffer); } else { printf("ERROR: Failed to set date on device.\n"); } node = NULL; } cleanup: if (client) lockdownd_client_free(client); if (device) idevice_free(device); return result; }
G_GNUC_INTERNAL char * read_sysinfo_extended_by_uuid (const char *uuid) { lockdownd_client_t client = NULL; idevice_t device = NULL; idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; char *xml = NULL; char *str = NULL; char *gxml; uint32_t xml_length = 0; plist_t value = NULL; plist_t global = NULL; plist_t ptr = NULL; int cnt = 0; /* usbmuxd needs some time to start up so we try several times * to open the device before finally returning with an error */ while (cnt++ < 20) { ret = idevice_new(&device, uuid); if (ret == IDEVICE_E_SUCCESS) { break; } if (ret != IDEVICE_E_NO_DEVICE) { break; } g_usleep (G_USEC_PER_SEC / 2); } if (ret != IDEVICE_E_SUCCESS) { printf("No device found with uuid %s, is it plugged in?\n", uuid); return NULL; } if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(device, &client, "libgpod")) { idevice_free(device); return NULL; } /* run query and get format plist */ lockdownd_get_value(client, NULL, NULL, &global); lockdownd_get_value(client, "com.apple.mobile.iTunes", NULL, &value); /* add some required values manually to emulate old plist format */ ptr = plist_dict_get_item(global, "SerialNumber"); plist_get_string_val(ptr, &str); if (str != NULL) { ptr = plist_new_string(str); plist_dict_insert_item(value, "SerialNumber", ptr); free(str); } ptr = plist_dict_get_item(global, "ProductVersion"); plist_get_string_val(ptr, &str); if (str != NULL) { ptr = plist_new_string(str); plist_dict_insert_item(value, "VisibleBuildID", ptr); free(str); } ptr = plist_new_string(uuid); plist_dict_insert_item(value, "FireWireGUID", ptr); ptr = plist_new_string(uuid); plist_dict_insert_item(value, "UniqueDeviceID", ptr); plist_to_xml(value, &xml, &xml_length); ptr = NULL; if (value) plist_free(value); value = NULL; if (global) plist_free(global); global = NULL; lockdownd_client_free(client); idevice_free(device); /* Jump through hoops since libxml will say to free mem it allocated * with xmlFree while memory freed with g_free has to be allocated * by glib. */ if (xml != NULL) { gxml = g_strdup(xml); xmlFree(xml); } else { gxml = NULL; } return gxml; }
int main(int argc, char **argv) { idevice_t device = NULL; lockdownd_client_t lckd = NULL; mobile_image_mounter_client_t mim = NULL; afc_client_t afc = NULL; lockdownd_service_descriptor_t service = NULL; int res = -1; char *image_path = NULL; size_t image_size = 0; char *image_sig_path = NULL; parse_opts(argc, argv); argc -= optind; argv += optind; if (!list_mode) { if (argc < 1) { printf("ERROR: No IMAGE_FILE has been given!\n"); return -1; } image_path = strdup(argv[0]); if (argc >= 2) { image_sig_path = strdup(argv[1]); } else { if (asprintf(&image_sig_path, "%s.signature", image_path) < 0) { printf("Out of memory?!\n"); return -1; } } } if (IDEVICE_E_SUCCESS != idevice_new(&device, udid)) { printf("No device found, is it plugged in?\n"); return -1; } if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(device, &lckd, "ideviceimagemounter")) { printf("ERROR: could not connect to lockdown. Exiting.\n"); goto leave; } plist_t pver = NULL; char *product_version = NULL; lockdownd_get_value(lckd, NULL, "ProductVersion", &pver); if (pver && plist_get_node_type(pver) == PLIST_STRING) { plist_get_string_val(pver, &product_version); } disk_image_upload_type_t disk_image_upload_type = DISK_IMAGE_UPLOAD_TYPE_AFC; int product_version_major = 0; int product_version_minor = 0; if (product_version) { if (sscanf(product_version, "%d.%d.%*d", &product_version_major, &product_version_minor) == 2) { if (product_version_major >= 7) disk_image_upload_type = DISK_IMAGE_UPLOAD_TYPE_UPLOAD_IMAGE; } } lockdownd_start_service(lckd, "com.apple.mobile.mobile_image_mounter", &service); if (!service || service->port == 0) { printf("ERROR: Could not start mobile_image_mounter service!\n"); goto leave; } if (mobile_image_mounter_new(device, service, &mim) != MOBILE_IMAGE_MOUNTER_E_SUCCESS) { printf("ERROR: Could not connect to mobile_image_mounter!\n"); goto leave; } if (service) { lockdownd_service_descriptor_free(service); service = NULL; } if (!list_mode) { struct stat fst; if (disk_image_upload_type == DISK_IMAGE_UPLOAD_TYPE_AFC) { if ((lockdownd_start_service(lckd, "com.apple.afc", &service) != LOCKDOWN_E_SUCCESS) || !service || !service->port) { fprintf(stderr, "Could not start com.apple.afc!\n"); goto leave; } if (afc_client_new(device, service, &afc) != AFC_E_SUCCESS) { fprintf(stderr, "Could not connect to AFC!\n"); goto leave; } if (service) { lockdownd_service_descriptor_free(service); service = NULL; } } if (stat(image_path, &fst) != 0) { fprintf(stderr, "ERROR: stat: %s: %s\n", image_path, strerror(errno)); goto leave; } image_size = fst.st_size; if (stat(image_sig_path, &fst) != 0) { fprintf(stderr, "ERROR: stat: %s: %s\n", image_sig_path, strerror(errno)); goto leave; } } lockdownd_client_free(lckd); lckd = NULL; mobile_image_mounter_error_t err; plist_t result = NULL; if (list_mode) { /* list mounts mode */ if (!imagetype) { imagetype = strdup("Developer"); } err = mobile_image_mounter_lookup_image(mim, imagetype, &result); free(imagetype); if (err == MOBILE_IMAGE_MOUNTER_E_SUCCESS) { res = 0; if (xml_mode) { print_xml(result); } else { plist_print_to_stream(result, stdout); } } else { printf("Error: lookup_image returned %d\n", err); } } else { char sig[8192]; size_t sig_length = 0; FILE *f = fopen(image_sig_path, "rb"); if (!f) { fprintf(stderr, "Error opening signature file '%s': %s\n", image_sig_path, strerror(errno)); goto leave; } sig_length = fread(sig, 1, sizeof(sig), f); fclose(f); if (sig_length == 0) { fprintf(stderr, "Could not read signature from file '%s'\n", image_sig_path); goto leave; } f = fopen(image_path, "rb"); if (!f) { fprintf(stderr, "Error opening image file '%s': %s\n", image_path, strerror(errno)); goto leave; } char *targetname = NULL; if (asprintf(&targetname, "%s/%s", PKG_PATH, "staging.dimage") < 0) { fprintf(stderr, "Out of memory!?\n"); goto leave; } char *mountname = NULL; if (asprintf(&mountname, "%s/%s", PATH_PREFIX, targetname) < 0) { fprintf(stderr, "Out of memory!?\n"); goto leave; } if (!imagetype) { imagetype = strdup("Developer"); } switch(disk_image_upload_type) { case DISK_IMAGE_UPLOAD_TYPE_UPLOAD_IMAGE: printf("Uploading %s\n", image_path); err = mobile_image_mounter_upload_image(mim, imagetype, image_size, sig, sig_length, mim_upload_cb, f); break; case DISK_IMAGE_UPLOAD_TYPE_AFC: default: printf("Uploading %s --> afc:///%s\n", image_path, targetname); char **strs = NULL; if (afc_get_file_info(afc, PKG_PATH, &strs) != AFC_E_SUCCESS) { if (afc_make_directory(afc, PKG_PATH) != AFC_E_SUCCESS) { fprintf(stderr, "WARNING: Could not create directory '%s' on device!\n", PKG_PATH); } } if (strs) { int i = 0; while (strs[i]) { free(strs[i]); i++; } free(strs); } uint64_t af = 0; if ((afc_file_open(afc, targetname, AFC_FOPEN_WRONLY, &af) != AFC_E_SUCCESS) || !af) { fclose(f); fprintf(stderr, "afc_file_open on '%s' failed!\n", targetname); goto leave; } char buf[8192]; size_t amount = 0; do { amount = fread(buf, 1, sizeof(buf), f); if (amount > 0) { uint32_t written, total = 0; while (total < amount) { written = 0; if (afc_file_write(afc, af, buf, amount, &written) != AFC_E_SUCCESS) { fprintf(stderr, "AFC Write error!\n"); break; } total += written; } if (total != amount) { fprintf(stderr, "Error: wrote only %d of %d\n", total, (unsigned int)amount); afc_file_close(afc, af); fclose(f); goto leave; } } } while (amount > 0); afc_file_close(afc, af); break; } fclose(f); printf("done.\n"); printf("Mounting...\n"); err = mobile_image_mounter_mount_image(mim, mountname, sig, sig_length, imagetype, &result); free(imagetype); if (err == MOBILE_IMAGE_MOUNTER_E_SUCCESS) { if (result) { plist_t node = plist_dict_get_item(result, "Status"); if (node) { char *status = NULL; plist_get_string_val(node, &status); if (status) { if (!strcmp(status, "Complete")) { printf("Done.\n"); res = 0; } else { printf("unexpected status value:\n"); if (xml_mode) { print_xml(result); } else { plist_print_to_stream(result, stdout); } } free(status); } else { printf("unexpected result:\n"); if (xml_mode) { print_xml(result); } else { plist_print_to_stream(result, stdout); } } } node = plist_dict_get_item(result, "Error"); if (node) { char *error = NULL; plist_get_string_val(node, &error); if (error) { printf("Error: %s\n", error); free(error); } else { printf("unexpected result:\n"); if (xml_mode) { print_xml(result); } else { plist_print_to_stream(result, stdout); } } } else { if (xml_mode) { print_xml(result); } else { plist_print_to_stream(result, stdout); } } } } else { printf("Error: mount_image returned %d\n", err); } } if (result) { plist_free(result); } /* perform hangup command */ mobile_image_mounter_hangup(mim); /* free client */ mobile_image_mounter_free(mim); leave: if (afc) { afc_client_free(afc); } if (lckd) { lockdownd_client_free(lckd); } idevice_free(device); if (image_path) free(image_path); if (image_sig_path) free(image_sig_path); return res; }
/** * Function used internally by lockdownd_pair() and lockdownd_validate_pair() * * @param client The lockdown client to pair with. * @param pair_record The pair record to use for pairing. If NULL is passed, then * the pair records from the current machine are used. New records will be * generated automatically when pairing is done for the first time. * @param verb This is either "Pair", "ValidatePair" or "Unpair". * * @return LOCKDOWN_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL, * LOCKDOWN_E_PLIST_ERROR if the pair_record certificates are wrong, * LOCKDOWN_E_PAIRING_FAILED if the pairing failed, * LOCKDOWN_E_PASSWORD_PROTECTED if the device is password protected, * LOCKDOWN_E_INVALID_HOST_ID if the device does not know the caller's host id */ static lockdownd_error_t lockdownd_do_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record, const char *verb) { if (!client) return LOCKDOWN_E_INVALID_ARG; lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; plist_t dict = NULL; plist_t pair_record_plist = NULL; plist_t wifi_node = NULL; int pairing_mode = 0; /* 0 = libimobiledevice, 1 = external */ if (pair_record && pair_record->system_buid && pair_record->host_id) { /* valid pair_record passed? */ if (!pair_record->device_certificate || !pair_record->host_certificate || !pair_record->root_certificate) { return LOCKDOWN_E_PLIST_ERROR; } /* use passed pair_record */ pair_record_plist = lockdownd_pair_record_to_plist(pair_record); pairing_mode = 1; } else { /* generate a new pair record if pairing */ if (!strcmp("Pair", verb)) { ret = pair_record_generate(client, &pair_record_plist); if (ret != LOCKDOWN_E_SUCCESS) { if (pair_record_plist) plist_free(pair_record_plist); return ret; } /* get wifi mac now, if we get it later we fail on iOS 7 which causes a reconnect */ lockdownd_get_value(client, NULL, "WiFiAddress", &wifi_node); } else { /* use existing pair record */ if (userpref_has_pair_record(client->udid)) { userpref_read_pair_record(client->udid, &pair_record_plist); if (!pair_record_plist) { return LOCKDOWN_E_INVALID_CONF; } } else { return LOCKDOWN_E_INVALID_HOST_ID; } } } plist_t request_pair_record = plist_copy(pair_record_plist); /* remove stuff that is private */ plist_dict_remove_item(request_pair_record, USERPREF_ROOT_PRIVATE_KEY_KEY); plist_dict_remove_item(request_pair_record, USERPREF_HOST_PRIVATE_KEY_KEY); /* setup pair request plist */ dict = plist_new_dict(); plist_dict_add_label(dict, client->label); plist_dict_set_item(dict, "PairRecord", request_pair_record); plist_dict_set_item(dict, "Request", plist_new_string(verb)); plist_dict_set_item(dict, "ProtocolVersion", plist_new_string(LOCKDOWN_PROTOCOL_VERSION)); plist_t options = plist_new_dict(); plist_dict_set_item(options, "ExtendedPairingErrors", plist_new_bool(1)); plist_dict_set_item(dict, "PairingOptions", options); /* send to device */ ret = lockdownd_send(client, dict); plist_free(dict); dict = NULL; if (ret != LOCKDOWN_E_SUCCESS) { plist_free(pair_record_plist); if (wifi_node) plist_free(wifi_node); return ret; } /* Now get device's answer */ ret = lockdownd_receive(client, &dict); if (ret != LOCKDOWN_E_SUCCESS) { plist_free(pair_record_plist); if (wifi_node) plist_free(wifi_node); return ret; } if (strcmp(verb, "Unpair") == 0) { /* workaround for Unpair giving back ValidatePair, * seems to be a bug in the device's fw */ if (lockdown_check_result(dict, NULL) != RESULT_SUCCESS) { ret = LOCKDOWN_E_PAIRING_FAILED; } } else { if (lockdown_check_result(dict, verb) != RESULT_SUCCESS) { ret = LOCKDOWN_E_PAIRING_FAILED; } } /* if pairing succeeded */ if (ret == LOCKDOWN_E_SUCCESS) { debug_info("%s success", verb); if (!pairing_mode) { debug_info("internal pairing mode"); if (!strcmp("Unpair", verb)) { /* remove public key from config */ userpref_delete_pair_record(client->udid); } else { if (!strcmp("Pair", verb)) { /* add returned escrow bag if available */ plist_t extra_node = plist_dict_get_item(dict, USERPREF_ESCROW_BAG_KEY); if (extra_node && plist_get_node_type(extra_node) == PLIST_DATA) { debug_info("Saving EscrowBag from response in pair record"); plist_dict_set_item(pair_record_plist, USERPREF_ESCROW_BAG_KEY, plist_copy(extra_node)); plist_free(extra_node); extra_node = NULL; } /* save previously retrieved wifi mac address in pair record */ if (wifi_node) { debug_info("Saving WiFiAddress from device in pair record"); plist_dict_set_item(pair_record_plist, USERPREF_WIFI_MAC_ADDRESS_KEY, plist_copy(wifi_node)); plist_free(wifi_node); wifi_node = NULL; } userpref_save_pair_record(client->udid, pair_record_plist); } } } else { debug_info("external pairing mode"); } } else { debug_info("%s failure", verb); plist_t error_node = NULL; /* verify error condition */ error_node = plist_dict_get_item(dict, "Error"); if (error_node) { char *value = NULL; plist_get_string_val(error_node, &value); if (value) { /* the first pairing fails if the device is password protected */ if (!strcmp(value, "PasswordProtected")) { ret = LOCKDOWN_E_PASSWORD_PROTECTED; } else if (!strcmp(value, "InvalidHostID")) { ret = LOCKDOWN_E_INVALID_HOST_ID; } else if (!strcmp(value, "UserDeniedPairing")) { ret = LOCKDOWN_E_USER_DENIED_PAIRING; } else if (!strcmp(value, "PairingDialogResponsePending")) { ret = LOCKDOWN_E_PAIRING_DIALOG_PENDING; } free(value); } plist_free(error_node); error_node = NULL; } } if (pair_record_plist) { plist_free(pair_record_plist); pair_record_plist = NULL; } if (wifi_node) { plist_free(wifi_node); wifi_node = NULL; } plist_free(dict); dict = NULL; return ret; }
int main(int argc, char *argv[]) { lockdownd_client_t client = NULL; idevice_t phone = NULL; idevice_set_debug_level(1); if (IDEVICE_E_SUCCESS != idevice_new(&phone, NULL)) { printf("No device found, is it plugged in?\n"); return -1; } char *udid = NULL; if (IDEVICE_E_SUCCESS == idevice_get_udid(phone, &udid)) { printf("DeviceUniqueID : %s\n", udid); } if (udid) free(udid); if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "lckdclient")) { idevice_free(phone); return -1; } using_history(); int loop = 1; while (loop) { char *cmd = readline("> "); if (cmd) { char **args = get_tokens(cmd); int len = 0; while (args && args[len]) { len++; } if (len > 0) { add_history(cmd); if (!strcmp(*args, "quit")) loop = 0; if (!strcmp(*args, "get") && len >= 2) { plist_t value = NULL; if (LOCKDOWN_E_SUCCESS == lockdownd_get_value(client, len == 3 ? *(args + 1):NULL, len == 3 ? *(args + 2):*(args + 1), &value)) { char *xml = NULL; uint32_t length; plist_to_xml(value, &xml, &length); printf("Success : value = %s\n", xml); free(xml); } else printf("Error\n"); if (value) plist_free(value); } if (!strcmp(*args, "start") && len == 2) { uint16_t port = 0; if(LOCKDOWN_E_SUCCESS == lockdownd_start_service(client, *(args + 1), &port)) { printf("started service %s on port %i\n", *(args + 1), port); } else { printf("failed to start service %s on device.\n", *(args + 1)); } } } strfreev(args); } free(cmd); cmd = NULL; } clear_history(); lockdownd_client_free(client); idevice_free(phone); return 0; }
const char* normal_check_product_type(struct idevicerestore_client_t* client) { int i = 0; idevice_t device = NULL; char* product_type = NULL; irecv_device_t irecv_device = NULL; plist_t product_type_node = NULL; lockdownd_client_t lockdown = NULL; idevice_error_t device_error = IDEVICE_E_SUCCESS; lockdownd_error_t lockdown_error = IDEVICE_E_SUCCESS; normal_idevice_new(client, &device); if (!device) { return product_type; } lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore"); if (lockdown_error == LOCKDOWN_E_PASSWORD_PROTECTED) { lockdown_error = lockdownd_client_new(device, &lockdown, "idevicerestore"); } else if (lockdown_error == LOCKDOWN_E_INVALID_HOST_ID) { char* udid = NULL; lockdownd_unpair(lockdown, NULL); idevice_get_udid(device, &udid); if (udid) { userpref_remove_device_record(udid); } lockdown_error = lockdownd_client_new_with_handshake(device, &lockdown, "idevicerestore"); } if (lockdown_error != LOCKDOWN_E_SUCCESS) { idevice_free(device); return product_type; } plist_t pval = NULL; lockdownd_get_value(lockdown, NULL, "HardwareModel", &pval); if (pval && (plist_get_node_type(pval) == PLIST_STRING)) { char* strval = NULL; plist_get_string_val(pval, &strval); if (strval) { irecv_devices_get_device_by_hardware_model(strval, &irecv_device); if (irecv_device) { product_type = strdup(irecv_device->product_type); } free(strval); } } if (pval) { plist_free(pval); } if (product_type == NULL) { lockdown_error = lockdownd_get_value(lockdown, NULL, "ProductType", &product_type_node); if (lockdown_error != LOCKDOWN_E_SUCCESS) { lockdownd_client_free(lockdown); idevice_free(device); return product_type; } } lockdownd_client_free(lockdown); idevice_free(device); lockdown = NULL; device = NULL; if (irecv_device) { if (product_type) free(product_type); return irecv_device->product_type; } if (product_type_node != NULL) { if (!product_type_node || plist_get_node_type(product_type_node) != PLIST_STRING) { if (product_type_node) plist_free(product_type_node); return product_type; } plist_get_string_val(product_type_node, &product_type); plist_free(product_type_node); irecv_devices_get_device_by_product_type(product_type, &irecv_device); if (irecv_device && irecv_device->product_type) { free(product_type); return irecv_device->product_type; } } return product_type; }
int main(int argc, char *argv[]) { lockdownd_client_t client = NULL; idevice_t phone = NULL; idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; int i; int simple = 0; int format = FORMAT_KEY_VALUE; char uuid[41]; char *domain = NULL; char *key = NULL; char *xml_doc = NULL; uint32_t xml_length; plist_t node = NULL; plist_type node_type; uuid[0] = 0; /* parse cmdline args */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { idevice_set_debug_level(1); continue; } else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--uuid")) { i++; if (!argv[i] || (strlen(argv[i]) != 40)) { print_usage(argc, argv); return 0; } strcpy(uuid, argv[i]); continue; } else if (!strcmp(argv[i], "-q") || !strcmp(argv[i], "--domain")) { i++; if (!argv[i] || (strlen(argv[i]) < 4)) { print_usage(argc, argv); return 0; } if (!is_domain_known(argv[i])) { fprintf(stderr, "WARNING: Sending query with unknown domain \"%s\".\n", argv[i]); } domain = strdup(argv[i]); continue; } else if (!strcmp(argv[i], "-k") || !strcmp(argv[i], "--key")) { i++; if (!argv[i] || (strlen(argv[i]) <= 1)) { print_usage(argc, argv); return 0; } key = strdup(argv[i]); continue; } else if (!strcmp(argv[i], "-x") || !strcmp(argv[i], "--xml")) { format = FORMAT_XML; continue; } else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--simple")) { simple = 1; continue; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { print_usage(argc, argv); return 0; } else { print_usage(argc, argv); return 0; } } if (uuid[0] != 0) { ret = idevice_new(&phone, uuid); if (ret != IDEVICE_E_SUCCESS) { printf("No device found with uuid %s, is it plugged in?\n", uuid); return -1; } } else { ret = idevice_new(&phone, NULL); if (ret != IDEVICE_E_SUCCESS) { printf("No device found, is it plugged in?\n"); return -1; } } if (LOCKDOWN_E_SUCCESS != (simple ? lockdownd_client_new(phone, &client, "ideviceinfo"): lockdownd_client_new_with_handshake(phone, &client, "ideviceinfo"))) { idevice_free(phone); return -1; } /* run query and output information */ if(lockdownd_get_value(client, domain, key, &node) == LOCKDOWN_E_SUCCESS) { if (node) { switch (format) { case FORMAT_XML: plist_to_xml(node, &xml_doc, &xml_length); printf("%s", xml_doc); free(xml_doc); break; case FORMAT_KEY_VALUE: node_type = plist_get_node_type(node); if (node_type == PLIST_DICT) { plist_dict_to_string(node); } else if (node_type == PLIST_ARRAY) { plist_array_to_string(node); break; } default: if (key != NULL) plist_node_to_string(node); break; } plist_free(node); node = NULL; } } if (domain != NULL) free(domain); lockdownd_client_free(client); idevice_free(phone); return 0; }
int main(int argc, char *argv[]) { lockdownd_client_t client = NULL; idevice_t phone = NULL; idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; int i; char udid[41]; time_t setdate = 0; plist_t node = NULL; udid[0] = 0; uint64_t datetime = 0; time_t rawtime; struct tm * tmp; char const *format = NULL; char buffer[80]; /* parse cmdline args */ for (i = 1; i < argc; i++) { if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) { idevice_set_debug_level(1); continue; } else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) { i++; if (!argv[i] || (strlen(argv[i]) != 40)) { print_usage(argc, argv); return 0; } strcpy(udid, argv[i]); continue; } else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--set")) { i++; if (!argv[i] || (strlen(argv[i]) <= 1)) { print_usage(argc, argv); return 0; } setdate = atoi(argv[i]); if (setdate == 0) { printf("ERROR: Invalid timestamp value.\n"); print_usage(argc, argv); return 0; } continue; } else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--sync")) { i++; /* get current time */ setdate = time(NULL); /* convert it to local time which sets timezone/daylight variables */ tmp = localtime(&setdate); /* recalculate to make it UTC */ setdate = mktime(tmp); continue; } else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) { print_usage(argc, argv); return 0; } else { print_usage(argc, argv); return 0; } } /* determine a date format */ if (!format) { format = DATE_FMT_LANGINFO (); if (!*format) { format = "%a %b %e %H:%M:%S %Z %Y"; } } if (udid[0] != 0) { ret = idevice_new(&phone, udid); if (ret != IDEVICE_E_SUCCESS) { printf("No device found with udid %s, is it plugged in?\n", udid); return -1; } } else { ret = idevice_new(&phone, NULL); if (ret != IDEVICE_E_SUCCESS) { printf("No device found, is it plugged in?\n"); return -1; } } if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "idevicedate")) { idevice_free(phone); return -1; } /* get or set? */ if (setdate == 0) { /* get time value from device */ if(lockdownd_get_value(client, NULL, "TimeIntervalSince1970", &node) == LOCKDOWN_E_SUCCESS) { if (node) { plist_get_uint_val(node, &datetime); plist_free(node); node = NULL; /* date/time calculations */ rawtime = (time_t)datetime; tmp = localtime(&rawtime); /* finally we format and print the current date */ strftime(buffer, 80, format, tmp); puts(buffer); } } } else { datetime = setdate; if(lockdownd_set_value(client, NULL, "TimeIntervalSince1970", plist_new_uint(datetime)) == LOCKDOWN_E_SUCCESS) { tmp = localtime(&setdate); strftime(buffer, 80, format, tmp); puts(buffer); } else { printf("ERROR: Failed to set date on device.\n"); } } lockdownd_client_free(client); idevice_free(phone); return 0; }
int wi_connect(const char *device_id, char **to_device_id, char **to_device_name, int recv_timeout) { int ret = -1; idevice_t phone = NULL; plist_t node = NULL; lockdownd_service_descriptor_t service = NULL; lockdownd_client_t client = NULL; idevice_connection_t connection = NULL; int fd = -1; // get phone if (idevice_new(&phone, device_id)) { perror("No iPhone found, is it plugged in?"); goto leave_cleanup; } // connect to lockdownd if (lockdownd_client_new_with_handshake( phone, &client, "ios_webkit_debug_proxy")) { perror("Could not connect to lockdownd. Exiting."); goto leave_cleanup; } // get device info if (to_device_id && !lockdownd_get_value(client, NULL, "UniqueDeviceID", &node)) { plist_get_string_val(node, to_device_id); plist_free(node); node = NULL; } if (to_device_name && !lockdownd_get_value(client, NULL, "DeviceName", &node)) { plist_get_string_val(node, to_device_name); } // start webinspector, get port if (lockdownd_start_service(client, "com.apple.webinspector", &service) || !service->port) { perror("Could not start com.apple.webinspector!"); goto leave_cleanup; } // connect to webinspector if (idevice_connect(phone, service->port, &connection)) { perror("idevice_connect failed!"); goto leave_cleanup; } if (client) { // not needed anymore lockdownd_client_free(client); client = NULL; } // extract the connection fd if (idevice_connection_get_fd(connection, &fd)) { perror("Unable to get connection file descriptor."); goto leave_cleanup; } if (recv_timeout < 0) { int opts = fcntl(fd, F_GETFL); if (!opts || fcntl(fd, F_SETFL, (opts | O_NONBLOCK)) < 0) { perror("Could not set socket to non-blocking"); goto leave_cleanup; } } else { long millis = (recv_timeout > 0 ? recv_timeout : 5000); struct timeval tv; tv.tv_sec = (time_t) (millis / 1000); tv.tv_usec = (time_t) ((millis - (tv.tv_sec * 1000)) * 1000); if (setsockopt(fd, SOL_SOCKET, SO_RCVTIMEO, (char *)&tv, sizeof(tv))) { perror("Could not set socket receive timeout"); goto leave_cleanup; } } // success ret = fd; leave_cleanup: if (ret < 0 && fd > 0) { close(fd); } // don't call usbmuxd_disconnect(fd)! //idevice_disconnect(connection); free(connection); lockdownd_client_free(client); plist_free(node); idevice_free(phone); return ret; }
static int normal_idevice_new(struct idevicerestore_client_t* client, idevice_t* device) { int num_devices = 0; char **devices = NULL; idevice_get_device_list(&devices, &num_devices); if (num_devices == 0) { return -1; } *device = NULL; idevice_t dev = NULL; idevice_error_t device_error; lockdownd_client_t lockdown = NULL; int j; for (j = 0; j < num_devices; j++) { if (lockdown != NULL) { lockdownd_client_free(lockdown); lockdown = NULL; } if (dev != NULL) { idevice_free(dev); dev = NULL; } device_error = idevice_new(&dev, devices[j]); if (device_error != IDEVICE_E_SUCCESS) { error("ERROR: %s: can't open device with UUID %s", __func__, devices[j]); continue; } if (lockdownd_client_new(dev, &lockdown, "idevicerestore") != LOCKDOWN_E_SUCCESS) { error("ERROR: %s: can't connect to lockdownd on device with UUID %s", __func__, devices[j]); continue; } char* type = NULL; if (lockdownd_query_type(lockdown, &type) != LOCKDOWN_E_SUCCESS) { continue; } if (strcmp(type, "com.apple.mobile.lockdown") != 0) { free(type); continue; } free(type); if (client->ecid != 0) { plist_t node = NULL; if ((lockdownd_get_value(lockdown, NULL, "UniqueChipID", &node) != LOCKDOWN_E_SUCCESS) || !node || (plist_get_node_type(node) != PLIST_UINT)){ if (node) { plist_free(node); } continue; } lockdownd_client_free(lockdown); lockdown = NULL; uint64_t this_ecid = 0; plist_get_uint_val(node, &this_ecid); plist_free(node); if (this_ecid != client->ecid) { continue; } } if (lockdown) { lockdownd_client_free(lockdown); lockdown = NULL; } client->uuid = strdup(devices[j]); *device = dev; break; } idevice_device_list_free(devices); return 0; }
int main(int argc, char** argv) { int res = -1; char* udid = NULL; int c = 0; int optidx = 0; const struct option longopts[] = { { "udid", required_argument, NULL, 'u' }, { "help", no_argument, NULL, 'h' }, { NULL, 0, NULL, 0} }; while ((c = getopt_long(argc, argv, "u:h", longopts, &optidx)) != -1) { switch (c) { case 'u': udid = strdup(optarg); break; case 'h': print_usage(); return 0; default: print_usage(); return -1; } } argc -= optind; argv += optind; if (argc > 1) { print_usage(); return -1; } idevice_t device = NULL; if (idevice_new(&device, udid) != IDEVICE_E_SUCCESS) { fprintf(stderr, "ERROR: Could not connect to device\n"); return -1; } lockdownd_client_t lockdown = NULL; lockdownd_error_t lerr = lockdownd_client_new_with_handshake(device, &lockdown, "idevicename"); if (lerr != LOCKDOWN_E_SUCCESS) { idevice_free(device); fprintf(stderr, "ERROR: lockdown connection failed, lockdown error %d\n", lerr); return -1; } plist_t node = NULL; if (argc == 0) { // getting device name char* name = NULL; lerr = lockdownd_get_value(lockdown, NULL, "DeviceName", &node); if (node) { plist_get_string_val(node, &name); plist_free(node); } if (name) { printf("%s\n", name); free(name); res = 0; } else { fprintf(stderr, "ERROR: Could not get device name, lockdown error %d\n", lerr); } } else { // setting device name lerr = lockdownd_set_value(lockdown, NULL, "DeviceName", plist_new_string(argv[0])); if (lerr == LOCKDOWN_E_SUCCESS) { printf("device name set to '%s'\n", argv[0]); res = 0; } else { fprintf(stderr, "ERROR: Could not set device name, lockdown error %d\n", lerr); } } lockdownd_client_free(lockdown); idevice_free(device); if (udid) { free(udid); } return res; }
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; }
static void* preflight_worker_handle_device_add(void* userdata) { struct device_info *info = (struct device_info*)userdata; struct idevice_private *_dev = (struct idevice_private*)malloc(sizeof(struct idevice_private)); _dev->udid = strdup(info->serial); _dev->conn_type = CONNECTION_USBMUXD; _dev->conn_data = (void*)(long)info->id; idevice_t dev = (idevice_t)_dev; lockdownd_client_t lockdown = NULL; lockdownd_error_t lerr; plist_t value = NULL; char* version_str = NULL; usbmuxd_log(LL_INFO, "%s: Starting preflight on device %s...", __func__, _dev->udid); retry: lerr = lockdownd_client_new(dev, &lockdown, "usbmuxd"); if (lerr != LOCKDOWN_E_SUCCESS) { usbmuxd_log(LL_ERROR, "%s: ERROR: Could not connect to lockdownd on device %s, lockdown error %d", __func__, _dev->udid, lerr); goto leave; } char *type = NULL; lerr = lockdownd_query_type(lockdown, &type); if (!type) { usbmuxd_log(LL_ERROR, "%s: ERROR: Could not get lockdownd type from device %s, lockdown error %d", __func__, _dev->udid, lerr); goto leave; } if (strcmp(type, "com.apple.mobile.lockdown") != 0) { // make restore mode devices visible free(type); usbmuxd_log(LL_INFO, "%s: Finished preflight on device %s", __func__, _dev->udid); client_device_add(info); goto leave; } free(type); int is_device_paired = 0; char *host_id = NULL; if (config_has_device_record(dev->udid)) { config_device_record_get_host_id(dev->udid, &host_id); lerr = lockdownd_start_session(lockdown, host_id, NULL, NULL); if (host_id) free(host_id); if (lerr == LOCKDOWN_E_SUCCESS) { usbmuxd_log(LL_INFO, "%s: StartSession success for device %s", __func__, _dev->udid); usbmuxd_log(LL_INFO, "%s: Finished preflight on device %s", __func__, _dev->udid); client_device_add(info); goto leave; } usbmuxd_log(LL_INFO, "%s: StartSession failed on device %s, lockdown error %d", __func__, _dev->udid, lerr); } else { lerr = LOCKDOWN_E_INVALID_HOST_ID; } switch (lerr) { case LOCKDOWN_E_INVALID_HOST_ID: usbmuxd_log(LL_INFO, "%s: Device %s is not paired with this host.", __func__, _dev->udid); break; case LOCKDOWN_E_SSL_ERROR: usbmuxd_log(LL_ERROR, "%s: The stored pair record for device %s is invalid. Removing.", __func__, _dev->udid); if (config_remove_device_record(_dev->udid) == 0) { lockdownd_client_free(lockdown); lockdown = NULL; goto retry; } else { usbmuxd_log(LL_ERROR, "%s: Could not remove pair record for device %s", __func__, _dev->udid); } break; default: is_device_paired = 1; break; } lerr = lockdownd_get_value(lockdown, NULL, "ProductVersion", &value); if (lerr != LOCKDOWN_E_SUCCESS) { usbmuxd_log(LL_ERROR, "%s: ERROR: Could not get ProductVersion from device %s, lockdown error %d", __func__, _dev->udid, lerr); goto leave; } if (value && plist_get_node_type(value) == PLIST_STRING) { plist_get_string_val(value, &version_str); } if (!version_str) { usbmuxd_log(LL_ERROR, "%s: Could not get ProductVersion string from device %s handle %d", __func__, _dev->udid, (int)(long)_dev->conn_data); goto leave; } int version_major = strtol(version_str, NULL, 10); if (version_major >= 7) { /* iOS 7.0 and later */ usbmuxd_log(LL_INFO, "%s: Found ProductVersion %s device %s", __func__, version_str, _dev->udid); lockdownd_set_untrusted_host_buid(lockdown); /* if not paired, trigger the trust dialog to make sure it appears */ if (!is_device_paired) { if (lockdownd_pair(lockdown, NULL) == LOCKDOWN_E_SUCCESS) { /* if device is still showing the setup screen it will pair even without trust dialog */ usbmuxd_log(LL_INFO, "%s: Pair success for device %s", __func__, _dev->udid); usbmuxd_log(LL_INFO, "%s: Finished preflight on device %s", __func__, _dev->udid); client_device_add(info); goto leave; } } lockdownd_service_descriptor_t service = NULL; lerr = lockdownd_start_service(lockdown, "com.apple.mobile.insecure_notification_proxy", &service); if (lerr != LOCKDOWN_E_SUCCESS) { usbmuxd_log(LL_ERROR, "%s: ERROR: Could not start insecure_notification_proxy on %s, lockdown error %d", __func__, _dev->udid, lerr); goto leave; } np_client_t np = NULL; np_client_new(dev, service, &np); lockdownd_service_descriptor_free(service); service = NULL; lockdownd_client_free(lockdown); lockdown = NULL; struct cb_data cbdata; cbdata.dev = dev; cbdata.np = np; cbdata.is_device_connected = 1; np_set_notify_callback(np, np_callback, (void*)&cbdata); device_set_preflight_cb_data(info->id, (void*)&cbdata); const char* spec[] = { "com.apple.mobile.lockdown.request_pair", "com.apple.mobile.lockdown.request_host_buid", NULL }; np_observe_notifications(np, spec); /* TODO send notification to user's desktop */ usbmuxd_log(LL_INFO, "%s: Waiting for user to trust this computer on device %s", __func__, _dev->udid); /* make device visible anyways */ client_device_add(info); while (cbdata.np && cbdata.is_device_connected == 1) { sleep(1); } device_set_preflight_cb_data(info->id, NULL); usbmuxd_log(LL_INFO, "%s: Finished waiting for notification from device %s, is_device_connected %d", __func__, _dev->udid, cbdata.is_device_connected); if (cbdata.np) { np_client_free(cbdata.np); } } else { /* iOS 6.x and earlier */ lerr = lockdownd_pair(lockdown, NULL); if (lerr != LOCKDOWN_E_SUCCESS) { if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) { usbmuxd_log(LL_INFO, "%s: Device %s is locked with a passcode. Cannot pair.", __func__, _dev->udid); /* TODO send notification to user's desktop */ } else { usbmuxd_log(LL_ERROR, "%s: ERROR: Pair failed for device %s, lockdown error %d", __func__, _dev->udid, lerr); } usbmuxd_log(LL_INFO, "%s: Finished preflight on device %s", __func__, _dev->udid); /* make device visible anyways */ client_device_add(info); goto leave; } host_id = NULL; config_device_record_get_host_id(dev->udid, &host_id); lerr = lockdownd_start_session(lockdown, host_id, NULL, NULL); free(host_id); if (lerr != LOCKDOWN_E_SUCCESS) { usbmuxd_log(LL_ERROR, "%s: ERROR StartSession failed on device %s, lockdown error %d", __func__, _dev->udid, lerr); goto leave; } lerr = lockdownd_validate_pair(lockdown, NULL); if (lerr != LOCKDOWN_E_SUCCESS) { usbmuxd_log(LL_ERROR, "%s: ERROR: ValidatePair failed for device %s, lockdown error %d", __func__, _dev->udid, lerr); goto leave; } usbmuxd_log(LL_INFO, "%s: Finished preflight on device %s", __func__, _dev->udid); /* emit device added event and thus make device visible to clients */ client_device_add(info); } leave: if (value) plist_free(value); if (version_str) free(version_str); if (lockdown) lockdownd_client_free(lockdown); if (dev) idevice_free(dev); free(info); return NULL; }