idevice_error_t idevice_connect(idevice_t device, uint16_t port, idevice_connection_t *connection) { if (!device) { return IDEVICE_E_INVALID_ARG; } if (device->conn_type == CONNECTION_USBMUXD) { int sfd = usbmuxd_connect((uint32_t)(long)device->conn_data, port); if (sfd < 0) { debug_info("ERROR: Connecting to usbmuxd failed: %d (%s)", sfd, strerror(-sfd)); return IDEVICE_E_UNKNOWN_ERROR; } idevice_connection_t new_connection = (idevice_connection_t)malloc(sizeof(struct idevice_connection_private)); new_connection->type = CONNECTION_USBMUXD; new_connection->data = (void*)(long)sfd; new_connection->ssl_data = NULL; idevice_get_udid(device, &new_connection->udid); *connection = new_connection; return IDEVICE_E_SUCCESS; } else { debug_info("Unknown connection type %d", device->conn_type); } return IDEVICE_E_UNKNOWN_ERROR; }
LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, const char *label) { if (!client) return LOCKDOWN_E_INVALID_ARG; static struct lockdownd_service_descriptor service = { 0xf27e, 0 }; property_list_service_client_t plistclient = NULL; if (property_list_service_client_new(device, (lockdownd_service_descriptor_t)&service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) { debug_info("could not connect to lockdownd (device %s)", device->udid); return LOCKDOWN_E_MUX_ERROR; } lockdownd_client_t client_loc = (lockdownd_client_t) malloc(sizeof(struct lockdownd_client_private)); client_loc->parent = plistclient; client_loc->ssl_enabled = 0; client_loc->session_id = NULL; if (idevice_get_udid(device, &client_loc->udid) != IDEVICE_E_SUCCESS) { debug_info("failed to get device udid."); } debug_info("device udid: %s", client_loc->udid); client_loc->label = label ? strdup(label) : NULL; *client = client_loc; return LOCKDOWN_E_SUCCESS; }
SWIGEXPORT jshort JNICALL Java_org_robovm_libimobiledevice_binding_libimobiledeviceJNI_idevice_1get_1udid(JNIEnv *jenv, jclass jcls, jlong jarg1, jlong jarg2) { jshort jresult = 0 ; idevice_t arg1 = (idevice_t) 0 ; char **arg2 = (char **) 0 ; idevice_error_t result; (void)jenv; (void)jcls; arg1 = *(idevice_t *)&jarg1; arg2 = *(char ***)&jarg2; result = (idevice_error_t)idevice_get_udid(arg1,arg2); jresult = (jshort)result; return jresult; }
int deviceConnect() { idevice_error_t ideverr = 0; ideverr = idevice_new(&gDevice, NULL); if (ideverr != IDEVICE_E_SUCCESS) { return -1; } // grab UDID to show which device we're connected to. ideverr = idevice_get_udid(gDevice, &udid); if (ideverr != IDEVICE_E_SUCCESS) { printf("%s Unable to communicate with device.%s\n", KRED, KNRM); } printf(" UDID: %s!\n", udid); return 0; }
LIBIMOBILEDEVICE_API restored_error_t restored_client_new(idevice_t device, restored_client_t *client, const char *label) { if (!client) return RESTORE_E_INVALID_ARG; restored_error_t ret = RESTORE_E_SUCCESS; idevice_error_t idev_ret; static struct lockdownd_service_descriptor service = { /*.port = 0xf27e, .ssl_enabled = 0*/ 0xf27e, 0 }; property_list_service_client_t plistclient = NULL; if (property_list_service_client_new(device, (lockdownd_service_descriptor_t)&service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) { debug_info("could not connect to restored (device %s)", device->udid); return RESTORE_E_MUX_ERROR; } restored_client_t client_loc = (restored_client_t) malloc(sizeof(struct restored_client_private)); client_loc->parent = plistclient; client_loc->udid = NULL; client_loc->label = NULL; client_loc->info = NULL; if (label != NULL) //client_loc->label = strdup(label); client_loc->label = _strdup(label); idev_ret = idevice_get_udid(device, &client_loc->udid); if (IDEVICE_E_SUCCESS != idev_ret) { debug_info("failed to get device udid."); ret = RESTORE_E_DEVICE_ERROR; } debug_info("device udid: %s", client_loc->udid); if (RESTORE_E_SUCCESS == ret) { *client = client_loc; } else { restored_client_free(client_loc); } return ret; }
/** * Creates a new restored client for the device. * * @param device The device to create a restored client for * @param client The pointer to the location of the new restored_client * @param label The label to use for communication. Usually the program name. * * @return RESTORE_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL */ restored_error_t restored_client_new(idevice_t device, restored_client_t *client, const char *label) { if (!client) return RESTORE_E_INVALID_ARG; restored_error_t ret = RESTORE_E_SUCCESS; static struct lockdownd_service_descriptor service = { .port = 0xf27e, .ssl_enabled = 0 }; property_list_service_client_t plistclient = NULL; if (property_list_service_client_new(device, (lockdownd_service_descriptor_t)&service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) { debug_info("could not connect to restored (device %s)", device->udid); return RESTORE_E_MUX_ERROR; } restored_client_t client_loc = (restored_client_t) malloc(sizeof(struct restored_client_private)); client_loc->parent = plistclient; client_loc->udid = NULL; client_loc->label = NULL; client_loc->info = NULL; if (label != NULL) client_loc->label = strdup(label); ret = idevice_get_udid(device, &client_loc->udid); if (RESTORE_E_SUCCESS != ret) { debug_info("failed to get device udid."); } debug_info("device udid: %s", client_loc->udid); if (RESTORE_E_SUCCESS == ret) { *client = client_loc; } else { restored_client_free(client_loc); } return ret; } /** * Sends the Goodbye request to restored signaling the end of communication. * * @param client The restore client * * @return RESTORE_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL, * RESTORE_E_PLIST_ERROR if the device did not acknowledge the request */ restored_error_t restored_goodbye(restored_client_t client) { if (!client) return RESTORE_E_INVALID_ARG; restored_error_t ret = RESTORE_E_UNKNOWN_ERROR; plist_t dict = plist_new_dict(); plist_dict_add_label(dict, client->label); plist_dict_insert_item(dict,"Request", plist_new_string("Goodbye")); debug_info("called"); ret = restored_send(client, dict); plist_free(dict); dict = NULL; ret = restored_receive(client, &dict); if (!dict) { debug_info("did not get goodbye response back"); return RESTORE_E_PLIST_ERROR; } if (restored_check_result(dict) == RESULT_SUCCESS) { debug_info("success"); ret = RESTORE_E_SUCCESS; } plist_free(dict); dict = NULL; return ret; } /** * Requests to start a restore and retrieve it's port on success. * * @param client The restored client * @param options PLIST_DICT with options for the restore process or NULL * @param version the restore protocol version, see restored_query_type() * * @return RESTORE_E_SUCCESS on success, NP_E_INVALID_ARG if a parameter * is NULL, RESTORE_E_START_RESTORE_FAILED if the request fails */ restored_error_t restored_start_restore(restored_client_t client, plist_t options, uint64_t version) { if (!client) return RESTORE_E_INVALID_ARG; plist_t dict = NULL; restored_error_t ret = RESTORE_E_UNKNOWN_ERROR; dict = plist_new_dict(); plist_dict_add_label(dict, client->label); plist_dict_insert_item(dict,"Request", plist_new_string("StartRestore")); if (options) { plist_dict_insert_item(dict, "RestoreOptions", plist_copy(options)); } plist_dict_insert_item(dict,"RestoreProtocolVersion", plist_new_uint(version)); /* send to device */ ret = restored_send(client, dict); plist_free(dict); dict = NULL; return ret; } /** * Requests device to reboot. * * @param client The restored client * * @return RESTORE_E_SUCCESS on success, NP_E_INVALID_ARG if a parameter * is NULL */ restored_error_t restored_reboot(restored_client_t client) { if (!client) return RESTORE_E_INVALID_ARG; plist_t dict = NULL; restored_error_t ret = RESTORE_E_UNKNOWN_ERROR; dict = plist_new_dict(); plist_dict_add_label(dict, client->label); plist_dict_insert_item(dict,"Request", plist_new_string("Reboot")); /* send to device */ ret = restored_send(client, dict); plist_free(dict); dict = NULL; if (RESTORE_E_SUCCESS != ret) return ret; ret = restored_receive(client, &dict); if (RESTORE_E_SUCCESS != ret) return ret; if (!dict) return RESTORE_E_PLIST_ERROR; plist_free(dict); dict = NULL; return ret; }
LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, const char *label) { if (!client) return LOCKDOWN_E_INVALID_ARG; static struct lockdownd_service_descriptor service = { .port = 0xf27e, .ssl_enabled = 0 }; property_list_service_client_t plistclient = NULL; if (property_list_service_client_new(device, (lockdownd_service_descriptor_t)&service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) { debug_info("could not connect to lockdownd (device %s)", device->udid); return LOCKDOWN_E_MUX_ERROR; } lockdownd_client_t client_loc = (lockdownd_client_t) malloc(sizeof(struct lockdownd_client_private)); client_loc->parent = plistclient; client_loc->ssl_enabled = 0; client_loc->session_id = NULL; if (idevice_get_udid(device, &client_loc->udid) != IDEVICE_E_SUCCESS) { debug_info("failed to get device udid."); } debug_info("device udid: %s", client_loc->udid); client_loc->label = label ? strdup(label) : NULL; *client = client_loc; return LOCKDOWN_E_SUCCESS; } LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, const char *label) { if (!client) return LOCKDOWN_E_INVALID_ARG; lockdownd_error_t ret = LOCKDOWN_E_SUCCESS; lockdownd_client_t client_loc = NULL; char *host_id = NULL; char *type = NULL; ret = lockdownd_client_new(device, &client_loc, label); if (LOCKDOWN_E_SUCCESS != ret) { debug_info("failed to create lockdownd client."); return ret; } /* perform handshake */ if (LOCKDOWN_E_SUCCESS != lockdownd_query_type(client_loc, &type)) { debug_info("QueryType failed in the lockdownd client."); ret = LOCKDOWN_E_NOT_ENOUGH_DATA; } else { if (strcmp("com.apple.mobile.lockdown", type)) { debug_info("Warning QueryType request returned \"%s\".", type); } } if (type) free(type); plist_t pair_record = NULL; userpref_read_pair_record(client_loc->udid, &pair_record); if (pair_record) { pair_record_get_host_id(pair_record, &host_id); } if (LOCKDOWN_E_SUCCESS == ret && !host_id) { ret = LOCKDOWN_E_INVALID_CONF; } if (LOCKDOWN_E_SUCCESS == ret && !pair_record) { /* attempt pairing */ ret = lockdownd_pair(client_loc, NULL); } plist_free(pair_record); pair_record = NULL; /* in any case, we need to validate pairing to receive trusted host status */ ret = lockdownd_validate_pair(client_loc, NULL); /* if not paired yet, let's do it now */ if (LOCKDOWN_E_INVALID_HOST_ID == ret) { ret = lockdownd_pair(client_loc, NULL); if (LOCKDOWN_E_SUCCESS == ret) { ret = lockdownd_validate_pair(client_loc, NULL); } else if (LOCKDOWN_E_PAIRING_DIALOG_PENDING == ret) { debug_info("Device shows the pairing dialog."); } } if (LOCKDOWN_E_SUCCESS == ret) { if (!host_id) { userpref_read_pair_record(client_loc->udid, &pair_record); if (pair_record) { pair_record_get_host_id(pair_record, &host_id); plist_free(pair_record); } } ret = lockdownd_start_session(client_loc, host_id, NULL, NULL); if (LOCKDOWN_E_SUCCESS != ret) { debug_info("Session opening failed."); } if (host_id) { free(host_id); host_id = NULL; } } if (LOCKDOWN_E_SUCCESS == ret) { *client = client_loc; } else { lockdownd_client_free(client_loc); } return ret; } /** * Returns a new plist from the supplied lockdownd pair record. The caller is * responsible for freeing the plist. * * @param pair_record The pair record to create a plist from. * * @return A pair record plist from the device, NULL if pair_record is not set */ static plist_t lockdownd_pair_record_to_plist(lockdownd_pair_record_t pair_record) { if (!pair_record) return NULL; /* setup request plist */ plist_t dict = plist_new_dict(); plist_dict_set_item(dict, "DeviceCertificate", plist_new_data(pair_record->device_certificate, strlen(pair_record->device_certificate))); plist_dict_set_item(dict, "HostCertificate", plist_new_data(pair_record->host_certificate, strlen(pair_record->host_certificate))); plist_dict_set_item(dict, "HostID", plist_new_string(pair_record->host_id)); plist_dict_set_item(dict, "RootCertificate", plist_new_data(pair_record->root_certificate, strlen(pair_record->root_certificate))); plist_dict_set_item(dict, "SystemBUID", plist_new_string(pair_record->system_buid)); return dict; } /** * Generates a pair record plist with required certificates for a specific * device. If a pairing exists, it is loaded from the computer instead of being * generated. * * @param pair_record_plist Holds the pair record. * * @return LOCKDOWN_E_SUCCESS on success */ static lockdownd_error_t pair_record_generate(lockdownd_client_t client, plist_t *pair_record) { lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR; key_data_t public_key = { NULL, 0 }; char* host_id = NULL; char* system_buid = NULL; /* retrieve device public key */ ret = lockdownd_get_device_public_key_as_key_data(client, &public_key); if (ret != LOCKDOWN_E_SUCCESS) { debug_info("device refused to send public key."); goto leave; } debug_info("device public key follows:\n%.*s", public_key.size, public_key.data); *pair_record = plist_new_dict(); /* generate keys and certificates into pair record */ userpref_error_t uret = USERPREF_E_SUCCESS; uret = pair_record_generate_keys_and_certs(*pair_record, public_key); switch(uret) { case USERPREF_E_INVALID_ARG: ret = LOCKDOWN_E_INVALID_ARG; break; case USERPREF_E_INVALID_CONF: ret = LOCKDOWN_E_INVALID_CONF; break; case USERPREF_E_SSL_ERROR: ret = LOCKDOWN_E_SSL_ERROR; default: break; } /* set SystemBUID */ userpref_read_system_buid(&system_buid); if (system_buid) { plist_dict_set_item(*pair_record, USERPREF_SYSTEM_BUID_KEY, plist_new_string(system_buid)); } /* set HostID */ host_id = generate_uuid(); pair_record_set_host_id(*pair_record, host_id); leave: if (host_id) free(host_id); if (system_buid) free(system_buid); if (public_key.data) free(public_key.data); return ret; }
int main(int argc, const char **argv) { char *errmsg = ""; idevice_t device = NULL; lockdownd_client_t client = NULL; lockdownd_service_descriptor_t service = NULL; house_arrest_client_t hac = NULL; const char *service_name = "com.apple.afc"; const char *appid = NULL; char *device_name = NULL; int result = 0; char* udid = NULL; int cmd = CMD_INTERACTIVE; const char *cmdstr = NULL; int i; cwd = strdup("/"); /* parse cmdline args */ for (i = 1; i < argc; i++) { if (str_is_equal(argv[i], "-d") || str_is_equal(argv[i], "--debug")) { idevice_set_debug_level(1); continue; } else if (str_is_equal(argv[i], "-u") || str_is_equal(argv[i], "--udid")) { i++; if (!argv[i] || (strlen(argv[i]) != 40)) { print_usage(argc, argv); exit(EXIT_FAILURE); } udid = strdup(argv[i]); continue; } else if (str_is_equal(argv[i], "-2") || str_is_equal(argv[i], "--afc2")) { service_name = "com.apple.afc2"; continue; } else if (str_is_equal(argv[i], "-a") || str_is_equal(argv[i], "--appid")) { if (++i >= argc) { print_usage(argc, argv); exit(EXIT_FAILURE); } appid = argv[i]; } else if (str_is_equal(argv[i], "-h") || str_is_equal(argv[i], "--help")) { print_usage(argc, argv); exit(EXIT_SUCCESS); } else if ((cmd = str_to_cmd(argv[i])) != CMD_UNKNOWN) { cmdstr = argv[i]; i++; break; } } argc -= i; argv += i; /* Connect to device */ if (udid) { result = idevice_new(&device, udid); if (result != IDEVICE_E_SUCCESS) errx(EXIT_FAILURE, "No device found with udid %s, is it plugged in?", udid); } else { result = idevice_new(&device, NULL); if (result != IDEVICE_E_SUCCESS) errx(EXIT_FAILURE, "No device found, is it plugged in?"); idevice_get_udid(device, &udid); } /* Connect to lockdownd */ result = lockdownd_client_new_with_handshake(device, &client, "afccl"); if (result != LOCKDOWN_E_SUCCESS) { asprintf(&errmsg, "ERROR: Connecting to lockdownd service failed!"); goto bail; } result = lockdownd_get_device_name(client, &device_name); if ((result != LOCKDOWN_E_SUCCESS) || !device_name) { asprintf(&errmsg, "ERROR: Could not get device name!"); goto bail; } if (appid) { result = lockdownd_start_service(client, "com.apple.mobile.house_arrest", &service); if (result != LOCKDOWN_E_SUCCESS || !service || !service->port) { asprintf(&errmsg, "error starting house arrest service: (%d) %s", result, afc_strerror(result)); goto bail; } if (client) { lockdownd_client_free(client); client = NULL; } if (house_arrest_client_new(device, service, &hac) != HOUSE_ARREST_E_SUCCESS) { asprintf(&errmsg, "could not connect to house_arrest service!\n"); goto bail; } if (service) { lockdownd_service_descriptor_free(service); service = NULL; } result = house_arrest_send_command(hac, "VendDocuments", appid); if (result != HOUSE_ARREST_E_SUCCESS) { asprintf(&errmsg, "error %d when trying to get VendDocuments\n", result); goto bail; } plist_t dict = NULL; if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) { if (house_arrest_get_result(hac, &dict) != HOUSE_ARREST_E_SUCCESS) { asprintf(&errmsg, "hmmm....\n"); goto bail; } } plist_t node = plist_dict_get_item(dict, "Error"); if (node) { char *str = NULL; plist_get_string_val(node, &str); asprintf(&errmsg, "Error: %s\n", str); if (str) free(str); plist_free(dict); dict = NULL; goto bail; } node = plist_dict_get_item(dict, "Status"); if (node) { char *str = NULL; plist_get_string_val(node, &str); if (str && (strcmp(str, "Complete") != 0)) { printf("Warning: Status is not 'Complete' but '%s'\n", str); } if (str) free(str); } if (dict) { plist_free(dict); } afc_error_t ae = afc_client_new_from_house_arrest_client(hac, &afc); if (ae != AFC_E_SUCCESS) { printf("afc error %d\n", ae); } } else { result = lockdownd_start_service(client, service_name, &service); if (result != LOCKDOWN_E_SUCCESS || !service || !service->port) { asprintf(&errmsg, "error starting AFC service: (%d) %s", result, afc_strerror(result)); goto bail; } /* Connect to AFC */ result = afc_client_new(device, service, &afc); lockdownd_client_free(client); idevice_free(device); if (result != AFC_E_SUCCESS) { errx(EXIT_FAILURE, "AFC connection failed (%d) %s", result, afc_strerror(result)); } } result = do_cmd(cmd, argc, argv); if (hac) house_arrest_client_free(hac); afc_client_free(afc); exit(result == 0 ? EXIT_SUCCESS : EXIT_FAILURE); bail: if (hac) house_arrest_client_free(hac); if (service) lockdownd_service_descriptor_free(service); if (client) lockdownd_client_free(client); if (device) idevice_free(device); errx(EXIT_FAILURE, "%s", errmsg); }
int main(int argc, char **argv) { lockdownd_client_t client = NULL; idevice_t device = NULL; idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; lockdownd_error_t lerr; int result; char *type = NULL; char *cmd; typedef enum { OP_NONE = 0, OP_PAIR, OP_VALIDATE, OP_UNPAIR, OP_LIST, OP_HOSTID } op_t; op_t op = OP_NONE; parse_opts(argc, argv); if ((argc - optind) < 1) { printf("ERROR: You need to specify a COMMAND!\n"); print_usage(argc, argv); exit(EXIT_FAILURE); } cmd = (argv+optind)[0]; if (!strcmp(cmd, "pair")) { op = OP_PAIR; } else if (!strcmp(cmd, "validate")) { op = OP_VALIDATE; } else if (!strcmp(cmd, "unpair")) { op = OP_UNPAIR; } else if (!strcmp(cmd, "list")) { op = OP_LIST; } else if (!strcmp(cmd, "hostid")) { op = OP_HOSTID; } else { printf("ERROR: Invalid command '%s' specified\n", cmd); print_usage(argc, argv); exit(EXIT_FAILURE); } if (op == OP_HOSTID) { char *hostid = NULL; userpref_get_host_id(&hostid); printf("%s\n", hostid); if (hostid) free(hostid); return EXIT_SUCCESS; } if (op == OP_LIST) { unsigned int i; char **udids = NULL; unsigned int count = 0; userpref_get_paired_udids(&udids, &count); for (i = 0; i < count; i++) { printf("%s\n", udids[i]); free(udids[i]); } if (udids) free(udids); if (udid) free(udid); return EXIT_SUCCESS; } if (udid) { ret = idevice_new(&device, udid); free(udid); udid = NULL; if (ret != IDEVICE_E_SUCCESS) { printf("No device found with udid %s, is it plugged in?\n", udid); return EXIT_FAILURE; } } else { ret = idevice_new(&device, NULL); if (ret != IDEVICE_E_SUCCESS) { printf("No device found, is it plugged in?\n"); return EXIT_FAILURE; } } lerr = lockdownd_client_new(device, &client, "idevicepair"); if (lerr != LOCKDOWN_E_SUCCESS) { idevice_free(device); printf("ERROR: lockdownd_client_new failed with error code %d\n", lerr); return EXIT_FAILURE; } result = EXIT_SUCCESS; lerr = lockdownd_query_type(client, &type); if (lerr != LOCKDOWN_E_SUCCESS) { printf("QueryType failed, error code %d\n", lerr); result = EXIT_FAILURE; goto leave; } else { if (strcmp("com.apple.mobile.lockdown", type)) { printf("WARNING: QueryType request returned '%s'\n", type); } if (type) { free(type); } } ret = idevice_get_udid(device, &udid); if (ret != IDEVICE_E_SUCCESS) { printf("ERROR: Could not get device udid, error code %d\n", ret); result = EXIT_FAILURE; goto leave; } switch(op) { default: case OP_PAIR: lerr = lockdownd_pair(client, NULL); if (lerr == LOCKDOWN_E_SUCCESS) { printf("SUCCESS: Paired with device %s\n", udid); } else { result = EXIT_FAILURE; if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) { printf("ERROR: Could not pair with the device because a passcode is set. Please enter the passcode on the device and retry.\n"); } else { printf("ERROR: Pairing with device %s failed with unhandled error code %d\n", udid, lerr); } } break; case OP_VALIDATE: lerr = lockdownd_validate_pair(client, NULL); if (lerr == LOCKDOWN_E_SUCCESS) { printf("SUCCESS: Validated pairing with device %s\n", udid); } else { result = EXIT_FAILURE; if (lerr == LOCKDOWN_E_PASSWORD_PROTECTED) { printf("ERROR: Could not validate with the device because a passcode is set. Please enter the passcode on the device and retry.\n"); } else if (lerr == LOCKDOWN_E_INVALID_HOST_ID) { printf("ERROR: Device %s is not paired with this host\n", udid); } else { printf("ERROR: Pairing failed with unhandled error code %d\n", lerr); } } break; case OP_UNPAIR: lerr = lockdownd_unpair(client, NULL); if (lerr == LOCKDOWN_E_SUCCESS) { /* also remove local device public key */ userpref_remove_device_public_key(udid); printf("SUCCESS: Unpaired with device %s\n", udid); } else { result = EXIT_FAILURE; if (lerr == LOCKDOWN_E_INVALID_HOST_ID) { printf("ERROR: Device %s is not paired with this host\n", udid); } else { printf("ERROR: Unpairing with device %s failed with unhandled error code %d\n", udid, lerr); } } break; } leave: lockdownd_client_free(client); idevice_free(device); if (udid) { free(udid); } return result; }
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_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; }
int main(int argc, char **argv) { lockdownd_client_t client = NULL; idevice_t device = NULL; idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR; lockdownd_error_t lerr; int result; char *type = NULL; char *cmd; typedef enum { OP_NONE = 0, OP_PAIR, OP_VALIDATE, OP_UNPAIR, OP_LIST, OP_HOSTID, OP_SYSTEMBUID } op_t; op_t op = OP_NONE; parse_opts(argc, argv); if ((argc - optind) < 1) { printf("ERROR: You need to specify a COMMAND!\n"); print_usage(argc, argv); exit(EXIT_FAILURE); } cmd = (argv+optind)[0]; if (!strcmp(cmd, "pair")) { op = OP_PAIR; } else if (!strcmp(cmd, "validate")) { op = OP_VALIDATE; } else if (!strcmp(cmd, "unpair")) { op = OP_UNPAIR; } else if (!strcmp(cmd, "list")) { op = OP_LIST; } else if (!strcmp(cmd, "hostid")) { op = OP_HOSTID; } else if (!strcmp(cmd, "systembuid")) { op = OP_SYSTEMBUID; } else { printf("ERROR: Invalid command '%s' specified\n", cmd); print_usage(argc, argv); exit(EXIT_FAILURE); } if (op == OP_SYSTEMBUID) { char *systembuid = NULL; userpref_read_system_buid(&systembuid); printf("%s\n", systembuid); if (systembuid) free(systembuid); return EXIT_SUCCESS; } if (op == OP_LIST) { unsigned int i; char **udids = NULL; unsigned int count = 0; userpref_get_paired_udids(&udids, &count); for (i = 0; i < count; i++) { printf("%s\n", udids[i]); free(udids[i]); } if (udids) free(udids); if (udid) free(udid); return EXIT_SUCCESS; } if (udid) { ret = idevice_new(&device, udid); free(udid); udid = NULL; if (ret != IDEVICE_E_SUCCESS) { printf("No device found with udid %s, is it plugged in?\n", udid); return EXIT_FAILURE; } } else { ret = idevice_new(&device, NULL); if (ret != IDEVICE_E_SUCCESS) { printf("No device found, is it plugged in?\n"); return EXIT_FAILURE; } } ret = idevice_get_udid(device, &udid); if (ret != IDEVICE_E_SUCCESS) { printf("ERROR: Could not get device udid, error code %d\n", ret); result = EXIT_FAILURE; goto leave; } if (op == OP_HOSTID) { plist_t pair_record = NULL; char *hostid = NULL; userpref_read_pair_record(udid, &pair_record); pair_record_get_host_id(pair_record, &hostid); printf("%s\n", hostid); if (hostid) free(hostid); if (pair_record) plist_free(pair_record); return EXIT_SUCCESS; } lerr = lockdownd_client_new(device, &client, "idevicepair"); if (lerr != LOCKDOWN_E_SUCCESS) { idevice_free(device); printf("ERROR: Could not connect to lockdownd, error code %d\n", lerr); return EXIT_FAILURE; } result = EXIT_SUCCESS; lerr = lockdownd_query_type(client, &type); if (lerr != LOCKDOWN_E_SUCCESS) { printf("QueryType failed, error code %d\n", lerr); result = EXIT_FAILURE; goto leave; } else { if (strcmp("com.apple.mobile.lockdown", type)) { printf("WARNING: QueryType request returned '%s'\n", type); } if (type) { free(type); } } switch(op) { default: case OP_PAIR: lerr = lockdownd_pair(client, NULL); if (lerr == LOCKDOWN_E_SUCCESS) { printf("SUCCESS: Paired with device %s\n", udid); } else { result = EXIT_FAILURE; print_error_message(lerr); } break; case OP_VALIDATE: lerr = lockdownd_validate_pair(client, NULL); if (lerr == LOCKDOWN_E_SUCCESS) { printf("SUCCESS: Validated pairing with device %s\n", udid); } else { result = EXIT_FAILURE; print_error_message(lerr); } break; case OP_UNPAIR: lerr = lockdownd_unpair(client, NULL); if (lerr == LOCKDOWN_E_SUCCESS) { printf("SUCCESS: Unpaired with device %s\n", udid); } else { result = EXIT_FAILURE; print_error_message(lerr); } break; } leave: lockdownd_client_free(client); idevice_free(device); if (udid) { free(udid); } return result; }
LIBIMOBILEDEVICE_API restored_error_t restored_client_new(idevice_t device, restored_client_t *client, const char *label) { if (!client) return RESTORE_E_INVALID_ARG; restored_error_t ret = RESTORE_E_SUCCESS; idevice_error_t idev_ret; static struct lockdownd_service_descriptor service = { .port = 0xf27e, .ssl_enabled = 0 }; property_list_service_client_t plistclient = NULL; if (property_list_service_client_new(device, (lockdownd_service_descriptor_t)&service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) { debug_info("could not connect to restored (device %s)", device->udid); return RESTORE_E_MUX_ERROR; } restored_client_t client_loc = (restored_client_t) malloc(sizeof(struct restored_client_private)); client_loc->parent = plistclient; client_loc->udid = NULL; client_loc->label = NULL; client_loc->info = NULL; if (label != NULL) client_loc->label = strdup(label); idev_ret = idevice_get_udid(device, &client_loc->udid); if (IDEVICE_E_SUCCESS != idev_ret) { debug_info("failed to get device udid."); ret = RESTORE_E_DEVICE_ERROR; } debug_info("device udid: %s", client_loc->udid); if (RESTORE_E_SUCCESS == ret) { *client = client_loc; } else { restored_client_free(client_loc); } return ret; } LIBIMOBILEDEVICE_API restored_error_t restored_goodbye(restored_client_t client) { if (!client) return RESTORE_E_INVALID_ARG; restored_error_t ret = RESTORE_E_UNKNOWN_ERROR; plist_t dict = plist_new_dict(); plist_dict_add_label(dict, client->label); plist_dict_set_item(dict,"Request", plist_new_string("Goodbye")); debug_info("called"); ret = restored_send(client, dict); plist_free(dict); dict = NULL; ret = restored_receive(client, &dict); if (!dict) { debug_info("did not get goodbye response back"); return RESTORE_E_PLIST_ERROR; } if (restored_check_result(dict) == RESULT_SUCCESS) { debug_info("success"); ret = RESTORE_E_SUCCESS; } plist_free(dict); dict = NULL; return ret; } LIBIMOBILEDEVICE_API restored_error_t restored_start_restore(restored_client_t client, plist_t options, uint64_t version) { if (!client) return RESTORE_E_INVALID_ARG; plist_t dict = NULL; restored_error_t ret = RESTORE_E_UNKNOWN_ERROR; dict = plist_new_dict(); plist_dict_add_label(dict, client->label); plist_dict_set_item(dict,"Request", plist_new_string("StartRestore")); if (options) { plist_dict_set_item(dict, "RestoreOptions", plist_copy(options)); } plist_dict_set_item(dict,"RestoreProtocolVersion", plist_new_uint(version)); /* send to device */ ret = restored_send(client, dict); plist_free(dict); dict = NULL; return ret; } LIBIMOBILEDEVICE_API restored_error_t restored_reboot(restored_client_t client) { if (!client) return RESTORE_E_INVALID_ARG; plist_t dict = NULL; restored_error_t ret = RESTORE_E_UNKNOWN_ERROR; dict = plist_new_dict(); plist_dict_add_label(dict, client->label); plist_dict_set_item(dict,"Request", plist_new_string("Reboot")); /* send to device */ ret = restored_send(client, dict); plist_free(dict); dict = NULL; if (RESTORE_E_SUCCESS != ret) return ret; ret = restored_receive(client, &dict); if (RESTORE_E_SUCCESS != ret) return ret; if (!dict) return RESTORE_E_PLIST_ERROR; plist_free(dict); dict = NULL; return ret; }
int main(int argc, char *argv[]) { unsigned int bytes = 0; uint16_t i = 0; lockdownd_service_descriptor_t service = NULL; lockdownd_client_t client = NULL; idevice_t phone = NULL; uint64_t lockfile = 0; np_client_t gnp = NULL; if (argc > 1 && !strcasecmp(argv[1], "--debug")) { idevice_set_debug_level(1); } else { idevice_set_debug_level(0); } 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, "ideviceclient")) { idevice_free(phone); printf("Exiting.\n"); return -1; } char *nnn = NULL; if (LOCKDOWN_E_SUCCESS == lockdownd_get_device_name(client, &nnn)) { printf("DeviceName : %s\n", nnn); free(nnn); } lockdownd_start_service(client, "com.apple.afc", &service); if (service && service->port) { afc_client_t afc = NULL; afc_client_new(phone, service, &afc); if (afc) { service->port = 0; service->ssl_enabled = 0; lockdownd_start_service(client, "com.apple.mobile.notification_proxy", &service); if (service->port) { printf("Notification Proxy started.\n"); np_client_new(phone, service, &gnp); } else { printf("ERROR: Notification proxy could not be started.\n"); } if (gnp) { const char *nspec[5] = { NP_SYNC_CANCEL_REQUEST, NP_SYNC_SUSPEND_REQUEST, NP_SYNC_RESUME_REQUEST, NP_ITDBPREP_DID_END, NULL }; np_observe_notifications(gnp, nspec); np_set_notify_callback(gnp, notifier, NULL); } perform_notification(phone, client, NP_SYNC_WILL_START); afc_file_open(afc, "/com.apple.itunes.lock_sync", AFC_FOPEN_RW, &lockfile); if (lockfile) { printf("locking file\n"); afc_file_lock(afc, lockfile, AFC_LOCK_EX); perform_notification(phone, client, NP_SYNC_DID_START); } char **dirs = NULL; afc_read_directory(afc, "/eafaedf", &dirs); if (!dirs) afc_read_directory(afc, "/", &dirs); printf("Directory time.\n"); for (i = 0; dirs[i]; i++) { printf("/%s\n", dirs[i]); free(dirs[i]); } if (dirs) free(dirs); dirs = NULL; afc_get_device_info(afc, &dirs); if (dirs) { for (i = 0; dirs[i]; i += 2) { printf("%s: %s\n", dirs[i], dirs[i + 1]); free(dirs[i]); } free(dirs); } uint64_t my_file = 0; char **info = NULL; uint64_t fsize = 0; if (AFC_E_SUCCESS == afc_get_file_info(afc, "/readme.libimobiledevice.fx", &info) && info) { for (i = 0; info[i]; i += 2) { printf("%s: %s\n", info[i], info[i+1]); if (!strcmp(info[i], "st_size")) { fsize = atoll(info[i+1]); } } } if (AFC_E_SUCCESS == afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_RDONLY, &my_file) && my_file) { printf("A file size: %llu\n", (long long)fsize); char *file_data = (char *) malloc(sizeof(char) * fsize); afc_file_read(afc, my_file, file_data, fsize, &bytes); if (bytes > 0) { printf("The file's data:\n"); fwrite(file_data, 1, bytes, stdout); } printf("\nClosing my file.\n"); afc_file_close(afc, my_file); free(file_data); } else printf("couldn't open a file\n"); afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_WR, &my_file); if (my_file) { char *outdatafile = strdup("this is a bitchin text file\n"); afc_file_write(afc, my_file, outdatafile, strlen(outdatafile), &bytes); free(outdatafile); if (bytes > 0) printf("Wrote a surprise. ;)\n"); else printf("I wanted to write a surprise, but... :(\n"); afc_file_close(afc, my_file); } printf("Deleting a file...\n"); bytes = afc_remove_path(afc, "/delme"); if (bytes) printf("Success.\n"); else printf("Failure. (expected unless you have a /delme file on your phone)\n"); printf("Renaming a file...\n"); bytes = afc_rename_path(afc, "/renme", "/renme2"); if (bytes > 0) printf("Success.\n"); else printf("Failure. (expected unless you have a /renme file on your phone)\n"); printf("Seek & read\n"); afc_file_open(afc, "/readme.libimobiledevice.fx", AFC_FOPEN_RDONLY, &my_file); if (AFC_E_SUCCESS != afc_file_seek(afc, my_file, 5, SEEK_CUR)) printf("WARN: SEEK DID NOT WORK\n"); char *threeletterword = (char *) malloc(sizeof(char) * 5); afc_file_read(afc, my_file, threeletterword, 3, &bytes); threeletterword[3] = '\0'; if (bytes > 0) printf("Result: %s\n", threeletterword); else printf("Couldn't read!\n"); free(threeletterword); afc_file_close(afc, my_file); } if (gnp && lockfile) { printf("XXX sleeping\n"); sleep(5); printf("XXX unlocking file\n"); afc_file_lock(afc, lockfile, AFC_LOCK_UN); printf("XXX closing file\n"); afc_file_close(afc, lockfile); printf("XXX sleeping\n"); sleep(5); //perform_notification(phone, client, NP_SYNC_DID_FINISH); } if (gnp) { np_client_free(gnp); gnp = NULL; } afc_client_free(afc); lockdownd_service_descriptor_free(service); service = NULL; } else { printf("Start service failure.\n"); } printf("All done.\n"); lockdownd_client_free(client); idevice_free(phone); return 0; }