/** * Checks if a notification has been sent by the device. * * @param client NP to get a notification from * @param notification Pointer to a buffer that will be allocated and filled * with the notification that has been received. * * @return 0 if a notification has been received or nothing has been received, * or a negative value if an error occured. * * @note You probably want to check out np_set_notify_callback * @see np_set_notify_callback */ static int np_get_notification(np_client_t client, char **notification) { int res = 0; plist_t dict = NULL; if (!client || !client->parent || *notification) return -1; np_lock(client); property_list_service_error_t perr = property_list_service_receive_plist_with_timeout(client->parent, &dict, 500); if (perr == PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT) { debug_info("NotificationProxy: no notification received!"); res = 0; } else if (perr != PROPERTY_LIST_SERVICE_E_SUCCESS) { debug_info("NotificationProxy: error %d occured!", perr); res = perr; } if (dict) { char *cmd_value = NULL; plist_t cmd_value_node = plist_dict_get_item(dict, "Command"); if (plist_get_node_type(cmd_value_node) == PLIST_STRING) { plist_get_string_val(cmd_value_node, &cmd_value); } if (cmd_value && !strcmp(cmd_value, "RelayNotification")) { char *name_value = NULL; plist_t name_value_node = plist_dict_get_item(dict, "Name"); if (plist_get_node_type(name_value_node) == PLIST_STRING) { plist_get_string_val(name_value_node, &name_value); } res = -2; if (name_value_node && name_value) { *notification = name_value; debug_info("got notification %s", __func__, name_value); res = 0; } } else if (cmd_value && !strcmp(cmd_value, "ProxyDeath")) { debug_info("NotificationProxy died!"); res = -1; } else if (cmd_value) { debug_info("unknown NotificationProxy command '%s' received!", cmd_value); res = -1; } else { res = -2; } if (cmd_value) { free(cmd_value); } plist_free(dict); dict = NULL; } np_unlock(client); return res; }
void build_manifest_print_information(plist_t build_manifest) { char* value = NULL; plist_t node = NULL; node = plist_dict_get_item(build_manifest, "ProductVersion"); if (!node || plist_get_node_type(node) != PLIST_STRING) { error("ERROR: Unable to find ProductVersion node\n"); return; } plist_get_string_val(node, &value); info("Product Version: %s\n", value); free(value); node = plist_dict_get_item(build_manifest, "ProductBuildVersion"); if (!node || plist_get_node_type(node) != PLIST_STRING) { error("ERROR: Unable to find ProductBuildVersion node\n"); return; } plist_get_string_val(node, &value); info("Product Build: %s\n", value); free(value); node = NULL; }
void minst_client(const char *operation, plist_t status, void *unused) { cb++; if (cb == 8) { } if (status && operation) { plist_t npercent = plist_dict_get_item(status, "PercentComplete"); plist_t nstatus = plist_dict_get_item(status, "Status"); plist_t nerror = plist_dict_get_item(status, "Error"); int percent = 0; char *status_msg = NULL; if (npercent) { uint64_t val = 0; plist_get_uint_val(npercent, &val); percent = val; } if (nstatus) { plist_get_string_val(nstatus, &status_msg); if (!strcmp(status_msg, "Complete")) { sleep(1); installing = 0; } } if (nerror) { char *err_msg = NULL; plist_get_string_val(nerror, &err_msg); free(err_msg); installing = 0; installError = 1; } } else { } }
LIBIMOBILEDEVICE_API instproxy_error_t instproxy_get_app_path_by_name(instproxy_client_t client, const char* app_name, char ** app_path, char ** exec_path) { instproxy_error_t res = INSTPROXY_E_UNKNOWN_ERROR; plist_t apps = NULL; plist_t client_options = instproxy_client_options_new(); instproxy_client_options_add(client_options, "ApplicationType", "Any", NULL); res = instproxy_browse(client, client_options, &apps); instproxy_client_options_free(client_options); int app_count = plist_array_get_size(apps); for(int app_index = 0; app_index < app_count; app_index++){ plist_t app_info_plist = plist_array_get_item(apps, app_index); plist_t app_bundle_display_name_plist = plist_dict_get_item(app_info_plist, "CFBundleDisplayName"); char* app_name_tmp = NULL; plist_t app_path_plist = NULL; plist_t exec_path_plist = NULL; if (app_bundle_display_name_plist) { plist_get_string_val(app_bundle_display_name_plist, &app_name_tmp); } if (app_name_tmp == NULL || strcasecmp(app_name_tmp, app_name) != 0) { continue; } char * app_path_tmp = NULL; char * exec_path_tmp = NULL; app_path_plist = plist_dict_get_item(app_info_plist, "Path"); if (app_path_plist) { plist_get_string_val(app_path_plist, &app_path_tmp); } exec_path_plist = plist_dict_get_item(app_info_plist, "CFBundleExecutable"); if (exec_path_plist) { plist_get_string_val(exec_path_plist, &exec_path_tmp); } size_t app_path_length = strlen(app_path_tmp); size_t exec_path_length = strlen(exec_path_tmp); *app_path = (char *)alloca(app_path_length + 1); *exec_path = (char *)alloca(exec_path_length + 1); memset(*app_path, 0, app_path_length + 1); memset(*exec_path, 0, exec_path_length + 1); memcpy(*app_path, app_path_tmp, strlen(app_path_tmp)); memcpy(*exec_path, exec_path_tmp, strlen(exec_path_tmp)); break; } return res; }
void ibrowserAPI::installCallback(const char *operation, plist_t status, void *user_data) { char *xml_doc=NULL; uint32_t xml_length; Callback *cb = (Callback *)user_data; FB::JSObjectPtr pcb = cb->get("pcb"); FB::JSObjectPtr scb = cb->get("scb"); FB::JSObjectPtr ecb = cb->get("ecb"); if(pcb) { plist_to_xml(status, &xml_doc, &xml_length); pcb->InvokeAsync("", FB::variant_list_of(xml_doc)); free(xml_doc); } plist_dict_iter it = NULL; char* key = NULL; char* s = NULL; plist_t subnode = NULL; plist_dict_new_iter(status, &it); plist_dict_next_item(status, it, &key, &subnode); while (subnode) { if(strcmp(key, "Error") == 0) { plist_get_string_val(subnode, &s); if(ecb) ecb->InvokeAsync("", FB::variant_list_of(s)); }else if(strcmp(key, "Status") == 0){ plist_get_string_val(subnode, &s); if(strcmp(s, "Complete") == 0){ if(scb) scb->InvokeAsync("", FB::variant_list_of(NULL)); } } plist_dict_next_item(status, it, &key, &subnode); } if(key) free(key); if(s) free(s); free(it); return; }
static void status_cb(const char *operation, plist_t status) #endif { if (status && operation) { plist_t npercent = plist_dict_get_item(status, "PercentComplete"); plist_t nstatus = plist_dict_get_item(status, "Status"); plist_t nerror = plist_dict_get_item(status, "Error"); int percent = 0; char *status_msg = NULL; if (npercent) { uint64_t val = 0; plist_get_uint_val(npercent, &val); percent = val; } if (nstatus) { plist_get_string_val(nstatus, &status_msg); if (!strcmp(status_msg, "Complete")) { op_completed = 1; } } if (!nerror) { if (last_status && (strcmp(last_status, status_msg))) { printf("\r"); } if (!npercent) { printf("%s - %s\n", operation, status_msg); } else { printf("%s - %s (%d%%)\n", operation, status_msg, percent); } } else { char *err_msg = NULL; plist_get_string_val(nerror, &err_msg); printf("%s - Error occured: %s\n", operation, err_msg); free(err_msg); err_occured = 1; } if (last_status) { free(last_status); last_status = NULL; } if (status_msg) { last_status = strdup(status_msg); free(status_msg); } } else { printf("%s: called with invalid data!\n", __func__); } }
int isManifestSignedForDevice(char *buildManifestPath, char **device, uint64_t ecid, int checkBaseband, char **version){ int isSigned = 0; #define reterror(a ...) {error(a); isSigned = -1; goto error;} plist_t manifest = NULL; plist_t ProductVersion = NULL; plist_t SupportedProductTypes = NULL; plist_t mDevice = NULL; info("[TSSC] opening %s\n",buildManifestPath); //filehandling FILE *fmanifest = fopen(buildManifestPath, "r"); if (!fmanifest) reterror("[TSSC] ERROR: file %s nof found!\n",buildManifestPath); fseek(fmanifest, 0, SEEK_END); long fsize = ftell(fmanifest); fseek(fmanifest, 0, SEEK_SET); char *bufManifest = (char*)malloc(fsize + 1); fread(bufManifest, fsize, 1, fmanifest); fclose(fmanifest); plist_from_xml(bufManifest, (unsigned)strlen(bufManifest), &manifest); if (version && !*version){ if (!manifest){ warning("[TSSC] WARNING: could not find ProductVersion in BuildManifest.plist, failing to properly display iOS version\n"); }else{ ProductVersion = plist_dict_get_item(manifest, "ProductVersion"); plist_get_string_val(ProductVersion, version); } } if (!*device) { if (manifest){ SupportedProductTypes = plist_dict_get_item(manifest, "SupportedProductTypes"); if (SupportedProductTypes) { mDevice = plist_array_get_item(SupportedProductTypes, 0); plist_get_string_val(mDevice, device); } } if (!*device) reterror("[TSSR] ERROR: device wasn't specified and could not be fetched from BuildManifest\n") else info("[TSSR] requesting ticket for %s\n",*device); } isSigned = isManifestBufSignedForDevice(bufManifest, *device, ecid, checkBaseband); error: if (manifest) plist_free(manifest); free(bufManifest); return isSigned; #undef reterror }
/** * Internally used function for checking the result from restore's answer * plist to a previously sent request. * * @param dict The plist to evaluate. * @param query_match Name of the request to match. * * @return RESULT_SUCCESS when the result is 'Success', * RESULT_FAILURE when the result is 'Failure', * or a negative value if an error occured during evaluation. */ static int restored_check_result(plist_t dict) { int ret = -1; plist_t result_node = plist_dict_get_item(dict, "Result"); if (!result_node) { return ret; } plist_type result_type = plist_get_node_type(result_node); if (result_type == PLIST_STRING) { char *result_value = NULL; plist_get_string_val(result_node, &result_value); if (result_value) { if (!strcmp(result_value, "Success")) { ret = RESULT_SUCCESS; } else if (!strcmp(result_value, "Failure")) { ret = RESULT_FAILURE; } else { debug_info("ERROR: unknown result value '%s'", result_value); } } if (result_value) free(result_value); } return ret; }
DeviceStatus Device::getApps() { plist_t apps = NULL; plist_t opts; opts = instproxy_client_options_new(); instproxy_client_options_add(opts, "ApplicationType", "Any", NULL); if (instproxy_browse(this->mInstProxy, opts, &apps) != INSTPROXY_E_SUCCESS) { instproxy_client_options_free(opts); return StatusError; } int count = plist_array_get_size(apps) / 2; for (int i = 0; i < count; i++) { plist_t app; app = plist_array_get_item(apps, i); plist_t appId; appId = plist_dict_get_item(app, "CFBundleIdentifier"); char *sAppId; plist_get_string_val(appId, &sAppId); this->mApps.insert(sAppId); //cout << i << "\t" << sAppId << endl; free(sAppId); plist_free(appId); plist_free(app); } plist_free(apps); instproxy_client_options_free(opts); return StatusOK; }
/** * Internally used function to extract the message string from a DLMessage* * plist. * * @param dl_msg The DeviceLink property list to parse. * * @return An allocated char* with the DLMessage from the given plist, * or NULL when the plist does not contain any DLMessage. It is up to * the caller to free the allocated memory. */ static char *device_link_service_get_message(plist_t dl_msg) { uint32_t cnt = 0; plist_t cmd = 0; char *cmd_str = NULL; /* sanity check */ if ((plist_get_node_type(dl_msg) != PLIST_ARRAY) || ((cnt = plist_array_get_size(dl_msg)) < 1)) { return NULL; } /* get dl command */ cmd = plist_array_get_item(dl_msg, 0); if (!cmd || (plist_get_node_type(cmd) != PLIST_STRING)) { return NULL; } plist_get_string_val(cmd, &cmd_str); if (!cmd_str) { return NULL; } if ((strlen(cmd_str) < (strlen("DLMessage")+1)) || (strncmp(cmd_str, "DLMessage", strlen("DLMessage")))) { free(cmd_str); return NULL; } /* we got a DLMessage* command */ return cmd_str; }
/** * Internally used function to extract the message string from a DL* message * plist. * * @param dl_msg The DeviceLink property list to parse. * @param message A pointer that will be set to a newly allocated char* * containing the DLMessage* string from the given plist. It is up to * the caller to free the allocated memory. If this parameter is NULL * it will be ignored. * * @return 1 if the given plist is a DL* message, or 0 if the plist does not * contain any DL* message. */ static int device_link_service_get_message(plist_t dl_msg, char **message) { plist_t cmd = NULL; char *cmd_str = NULL; /* sanity check */ if ((plist_get_node_type(dl_msg) != PLIST_ARRAY) || (plist_array_get_size(dl_msg) < 1)) { return 0; } /* get dl command */ cmd = plist_array_get_item(dl_msg, 0); if (!cmd || (plist_get_node_type(cmd) != PLIST_STRING)) { return 0; } plist_get_string_val(cmd, &cmd_str); if (!cmd_str) { return 0; } if ((strlen(cmd_str) < 9) || (strncmp(cmd_str, "DL", 2))) { free(cmd_str); return 0; } if (message) *message = cmd_str; /* we got a DL* message */ return 1; }
static mobileactivation_error_t mobileactivation_send_command_plist(mobileactivation_client_t client, plist_t command, plist_t *result) { if (!client || !command) return MOBILEACTIVATION_E_INVALID_ARG; plist_t cmd = plist_dict_get_item(command, "Command"); char* command_str = NULL; if (cmd) { plist_get_string_val(cmd, &command_str); } if (!command_str) return MOBILEACTIVATION_E_INVALID_ARG; mobileactivation_error_t ret = MOBILEACTIVATION_E_UNKNOWN_ERROR; *result = NULL; ret = mobileactivation_error(property_list_service_send_binary_plist(client->parent, command)); plist_t dict = NULL; ret = mobileactivation_error(property_list_service_receive_plist(client->parent, &dict)); if (!dict) { debug_info("ERROR: Did not get reply for %s command", command_str); free(command_str); return MOBILEACTIVATION_E_PLIST_ERROR; } *result = dict; ret = mobileactivation_check_result(dict, command_str); free(command_str); return ret; }
/** * Request a backup from the connected device. * * @param client The connected MobileBackup client to use. * @param backup_manifest The backup manifest, a plist_t of type PLIST_DICT * containing the backup state of the last backup. For a first-time backup * set this parameter to NULL. * @param base_path The base path on the device to use for the backup * operation, usually "/". * @param proto_version A string denoting the version of the backup protocol * to use. Latest known version is "1.6" * * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if * one of the parameters is invalid, MOBILEBACKUP_E_PLIST_ERROR if * backup_manifest is not of type PLIST_DICT, MOBILEBACKUP_E_MUX_ERROR * if a communication error occurs, MOBILEBACKUP_E_REPLY_NOT_OK */ mobilebackup_error_t mobilebackup_request_backup(mobilebackup_client_t client, plist_t backup_manifest, const char *base_path, const char *proto_version) { if (!client || !client->parent || !base_path || !proto_version) return MOBILEBACKUP_E_INVALID_ARG; if (backup_manifest && (plist_get_node_type(backup_manifest) != PLIST_DICT)) return MOBILEBACKUP_E_PLIST_ERROR; mobilebackup_error_t err; /* construct request plist */ plist_t dict = plist_new_dict(); if (backup_manifest) plist_dict_insert_item(dict, "BackupManifestKey", plist_copy(backup_manifest)); plist_dict_insert_item(dict, "BackupComputerBasePathKey", plist_new_string(base_path)); plist_dict_insert_item(dict, "BackupMessageTypeKey", plist_new_string("BackupMessageBackupRequest")); plist_dict_insert_item(dict, "BackupProtocolVersion", plist_new_string(proto_version)); /* send request */ err = mobilebackup_send_message(client, NULL, dict); plist_free(dict); dict = NULL; if (err != MOBILEBACKUP_E_SUCCESS) { debug_info("ERROR: Could not send backup request message (%d)!", err); goto leave; } /* now receive and hopefully get a BackupMessageBackupReplyOK */ err = mobilebackup_receive_message(client, "BackupMessageBackupReplyOK", &dict); if (err != MOBILEBACKUP_E_SUCCESS) { debug_info("ERROR: Could not receive BackupReplyOK message (%d)!", err); goto leave; } plist_t node = plist_dict_get_item(dict, "BackupProtocolVersion"); if (node) { char *str = NULL; plist_get_string_val(node, &str); if (str) { if (strcmp(str, proto_version) != 0) { err = MOBILEBACKUP_E_BAD_VERSION; } free(str); } } if (err != MOBILEBACKUP_E_SUCCESS) goto leave; /* BackupMessageBackupReplyOK received, send it back */ err = mobilebackup_send_message(client, NULL, dict); if (err != MOBILEBACKUP_E_SUCCESS) { debug_info("ERROR: Could not send BackupReplyOK ACK (%d)", err); } leave: if (dict) plist_free(dict); return err; }
LIBIMOBILEDEVICE_API void instproxy_command_get_name(plist_t command, char** name) { *name = NULL; plist_t node = plist_dict_get_item(command, "Command"); if (node) { plist_get_string_val(node, name); } }
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; }
int restore_check_device(const char* uuid) { int i = 0; char* type = NULL; char* model = NULL; plist_t node = NULL; uint64_t version = 0; idevice_t device = NULL; restored_client_t restore = NULL; idevice_error_t device_error = IDEVICE_E_SUCCESS; restored_error_t restore_error = RESTORE_E_SUCCESS; device_error = idevice_new(&device, uuid); if (device_error != IDEVICE_E_SUCCESS) { return -1; } restore_error = restored_client_new(device, &restore, "idevicerestore"); if (restore_error != RESTORE_E_SUCCESS) { idevice_free(device); return -1; } restore_error = restored_query_type(restore, &type, &version); if (restore_error != RESTORE_E_SUCCESS) { restored_client_free(restore); idevice_free(device); return -1; } restore_error = restored_get_value(restore, "HardwareModel", &node); if (restore_error != RESTORE_E_SUCCESS) { error("ERROR: Unable to get HardwareModel from restored\n"); restored_client_free(restore); idevice_free(device); return -1; } restored_client_free(restore); idevice_free(device); restore = NULL; device = NULL; if (!node || plist_get_node_type(node) != PLIST_STRING) { error("ERROR: Unable to get HardwareModel information\n"); if (node) plist_free(node); return -1; } plist_get_string_val(node, &model); for (i = 0; idevicerestore_devices[i].model != NULL; i++) { if (!strcasecmp(model, idevicerestore_devices[i].model)) { break; } } return idevicerestore_devices[i].device_id; }
LIBIMOBILEDEVICE_API restored_error_t restored_query_type(restored_client_t client, char **type, uint64_t *version) { 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("QueryType")); debug_info("called"); ret = restored_send(client, dict); plist_free(dict); dict = NULL; ret = restored_receive(client, &dict); if (RESTORE_E_SUCCESS != ret) return ret; ret = RESTORE_E_UNKNOWN_ERROR; plist_t type_node = plist_dict_get_item(dict, "Type"); if (type_node && (plist_get_node_type(type_node) == PLIST_STRING)) { char* typestr = NULL; /* save our device information info */ client->info = dict; plist_get_string_val(type_node, &typestr); debug_info("success with type %s", typestr); /* return the type if requested */ if (type) { *type = typestr; } else { free(typestr); } /* fetch the restore protocol version */ if (version) { plist_t version_node = plist_dict_get_item(dict, "RestoreProtocolVersion"); if (version_node && PLIST_UINT == plist_get_node_type(version_node)) { plist_get_uint_val(version_node, version); debug_info("restored protocol version %llu", *version); } else { return RESTORE_E_UNKNOWN_ERROR; } } ret = RESTORE_E_SUCCESS; } else { debug_info("hmm. QueryType response does not contain a type?!"); debug_plist(dict); plist_free(dict); } return ret; }
void plist_node_to_string(plist_t *node) { char *s = NULL; double d; uint8_t b; uint64_t u = 0; plist_type t; if (!node) return; t = plist_get_node_type(node); switch (t) { case PLIST_BOOLEAN: plist_get_bool_val(node, &b); printf("%s\n", (b ? "true" : "false")); break; case PLIST_UINT: plist_get_uint_val(node, &u); printf("%llu\n", u); break; case PLIST_REAL: plist_get_real_val(node, &d); printf("%f\n", d); break; case PLIST_STRING: plist_get_string_val(node, &s); printf("%s\n", s); free(s); break; case PLIST_KEY: plist_get_key_val(node, &s); printf("%s: ", s); free(s); break; case PLIST_DATA: printf("\n"); break; case PLIST_DATE: printf("\n"); break; case PLIST_ARRAY: case PLIST_DICT: printf("\n"); plist_children_to_string(node); break; default: break; } }
LIBIMOBILEDEVICE_API void instproxy_status_get_name(plist_t status, char **name) { *name = NULL; if (name) { plist_t node = plist_dict_get_item(status, "Status"); if (node) { plist_get_string_val(node, name); } } }
void build_manifest_get_version_information(plist_t build_manifest, char** product_version, char** product_build) { plist_t node = NULL; *product_version = NULL; *product_build = NULL; node = plist_dict_get_item(build_manifest, "ProductVersion"); if (!node || plist_get_node_type(node) != PLIST_STRING) { error("ERROR: Unable to find ProductVersion node\n"); return; } plist_get_string_val(node, product_version); node = plist_dict_get_item(build_manifest, "ProductBuildVersion"); if (!node || plist_get_node_type(node) != PLIST_STRING) { error("ERROR: Unable to find ProductBuildVersion node\n"); return; } plist_get_string_val(node, product_build); }
/** * Query the type of the service daemon. Depending on whether the device is * queried in normal mode or restore mode, different types will be returned. * * @param client The restored client * @param type The type returned by the service daemon. Pass NULL to ignore. * @param version The restore protocol version. Pass NULL to ignore. * * @return RESTORE_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL */ restored_error_t restored_query_type(restored_client_t client, char **type, uint64_t *version) { 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("QueryType")); debug_info("called"); ret = restored_send(client, dict); plist_free(dict); dict = NULL; ret = restored_receive(client, &dict); if (RESTORE_E_SUCCESS != ret) return ret; ret = RESTORE_E_UNKNOWN_ERROR; if (restored_check_result(dict) == RESULT_SUCCESS) { /* save our device information info */ client->info = dict; /* return the type if requested */ if (type) { plist_t type_node = plist_dict_get_item(dict, "Type"); if (type_node && PLIST_STRING == plist_get_node_type(type_node)) { plist_get_string_val(type_node, type); debug_info("success with type %s", *type); ret = RESTORE_E_SUCCESS; } else { return RESTORE_E_UNKNOWN_ERROR; } } /* fetch the restore protocol version */ if (version) { plist_t version_node = plist_dict_get_item(dict, "RestoreProtocolVersion"); if (version_node && PLIST_UINT == plist_get_node_type(version_node)) { plist_get_uint_val(version_node, version); debug_info("restored protocol version %llu", *version); ret = RESTORE_E_SUCCESS; } else { return RESTORE_E_UNKNOWN_ERROR; } } ret = RESTORE_E_SUCCESS; } return ret; }
int tss_response_get_blob_by_path(plist_t tss, const char* path, unsigned char** blob) { uint32_t i = 0; uint32_t tss_size = 0; uint64_t blob_size = 0; char* entry_key = NULL; char* blob_data = NULL; char* entry_path = NULL; plist_t tss_entry = NULL; plist_t blob_node = NULL; plist_t path_node = NULL; plist_dict_iter iter = NULL; *blob = NULL; plist_dict_new_iter(tss, &iter); tss_size = plist_dict_get_size(tss); for (i = 0; i < tss_size; i++) { plist_dict_next_item(tss, iter, &entry_key, &tss_entry); if (entry_key == NULL) break; if (!tss_entry || plist_get_node_type(tss_entry) != PLIST_DICT) { continue; } path_node = plist_dict_get_item(tss_entry, "Path"); if (!path_node || plist_get_node_type(path_node) != PLIST_STRING) { error("ERROR: Unable to find TSS path node in entry %s\n", entry_key); free(iter); return -1; } plist_get_string_val(path_node, &entry_path); if (strcmp(path, entry_path) == 0) { blob_node = plist_dict_get_item(tss_entry, "Blob"); if (!blob_node || plist_get_node_type(blob_node) != PLIST_DATA) { error("ERROR: Unable to find TSS blob node in entry %s\n", entry_key); free(iter); return -1; } plist_get_data_val(blob_node, &blob_data, &blob_size); break; } free(entry_key); } free(iter); if (blob_data == NULL || blob_size <= 0) { return -1; } *blob = (unsigned char*)blob_data; 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; }
static char* plist_dict_get_string_val(plist_t dict, const char* key) { if (!dict || plist_get_node_type(dict) != PLIST_DICT) return NULL; plist_t item = plist_dict_get_item(dict, key); if (!item || plist_get_node_type(item) != PLIST_STRING) return NULL; char *str = NULL; plist_get_string_val(item, &str); return str; }
/** * Get a screen shot from the connected device. * * @param client The connection screenshotr service client. * @param imgdata Pointer that will point to a newly allocated buffer * containing TIFF image data upon successful return. It is up to the * caller to free the memory. * @param imgsize Pointer to a uint64_t that will be set to the size of the * buffer imgdata points to upon successful return. * * @return SCREENSHOTR_E_SUCCESS on success, SCREENSHOTR_E_INVALID_ARG if * one or more parameters are invalid, or another error code if an * error occured. */ screenshotr_error_t screenshotr_take_screenshot(screenshotr_client_t client, char **imgdata, uint64_t *imgsize) { if (!client || !client->parent || !imgdata) return SCREENSHOTR_E_INVALID_ARG; screenshotr_error_t res = SCREENSHOTR_E_UNKNOWN_ERROR; plist_t dict = plist_new_dict(); plist_dict_insert_item(dict, "MessageType", plist_new_string("ScreenShotRequest")); res = screenshotr_error(device_link_service_send_process_message(client->parent, dict)); plist_free(dict); if (res != SCREENSHOTR_E_SUCCESS) { debug_info("could not send plist, error %d", res); return res; } dict = NULL; res = screenshotr_error(device_link_service_receive_process_message(client->parent, &dict)); if (res != SCREENSHOTR_E_SUCCESS) { debug_info("could not get screenshot data, error %d", res); goto leave; } if (!dict) { debug_info("did not receive screenshot data!"); res = SCREENSHOTR_E_PLIST_ERROR; goto leave; } plist_t node = plist_dict_get_item(dict, "MessageType"); char *strval = NULL; plist_get_string_val(node, &strval); if (!strval || strcmp(strval, "ScreenShotReply")) { debug_info("invalid screenshot data received!"); res = SCREENSHOTR_E_PLIST_ERROR; goto leave; } node = plist_dict_get_item(dict, "ScreenShotData"); if (!node || plist_get_node_type(node) != PLIST_DATA) { debug_info("no PNG data received!"); res = SCREENSHOTR_E_PLIST_ERROR; goto leave; } plist_get_data_val(node, imgdata, imgsize); res = SCREENSHOTR_E_SUCCESS; leave: if (dict) plist_free(dict); return res; }
LIBIMOBILEDEVICE_API np_error_t np_client_free(np_client_t client) { plist_t dict; property_list_service_client_t parent; if (!client) return NP_E_INVALID_ARG; dict = plist_new_dict(); plist_dict_set_item(dict,"Command", plist_new_string("Shutdown")); property_list_service_send_xml_plist(client->parent, dict); plist_free(dict); parent = client->parent; /* notifies the client->notifier thread that it should terminate */ client->parent = NULL; if (client->notifier) { debug_info("joining np callback"); thread_join(client->notifier); thread_free(client->notifier); client->notifier = (thread_t)NULL; } else { dict = NULL; property_list_service_receive_plist(parent, &dict); if (dict) { #ifndef STRIP_DEBUG_CODE char *cmd_value = NULL; plist_t cmd_value_node = plist_dict_get_item(dict, "Command"); if (plist_get_node_type(cmd_value_node) == PLIST_STRING) { plist_get_string_val(cmd_value_node, &cmd_value); } if (cmd_value && !strcmp(cmd_value, "ProxyDeath")) { // this is the expected answer } else { debug_info("Did not get ProxyDeath but:"); debug_plist(dict); } if (cmd_value) { free(cmd_value); } #endif plist_free(dict); } } property_list_service_client_free(parent); mutex_destroy(&client->mutex); free(client); return NP_E_SUCCESS; }
void build_manifest_get_version_information(plist_t build_manifest, struct idevicerestore_client_t* client) { plist_t node = NULL; client->version = NULL; client->build = NULL; node = plist_dict_get_item(build_manifest, "ProductVersion"); if (!node || plist_get_node_type(node) != PLIST_STRING) { error("ERROR: Unable to find ProductVersion node\n"); return; } plist_get_string_val(node, &client->version); node = plist_dict_get_item(build_manifest, "ProductBuildVersion"); if (!node || plist_get_node_type(node) != PLIST_STRING) { error("ERROR: Unable to find ProductBuildVersion node\n"); return; } plist_get_string_val(node, &client->build); client->build_major = strtoul(client->build, NULL, 10); }
/** * Request that a backup should be restored to the connected device. * * @param client The connected MobileBackup client to use. * @param backup_manifest The backup manifest, a plist_t of type PLIST_DICT * containing the backup state to be restored. * @param flags Flags to send with the request. Currently this is a combination * of the following mobilebackup_flags_t: * MB_RESTORE_NOTIFY_SPRINGBOARD - let SpringBoard show a 'Restore' screen * MB_RESTORE_PRESERVE_SETTINGS - do not overwrite any settings * MB_RESTORE_PRESERVE_CAMERA_ROLL - preserve the photos of the camera roll * @param proto_version A string denoting the version of the backup protocol * to use. Latest known version is "1.6". Ideally this value should be * extracted from the given manifest plist. * * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if * one of the parameters is invalid, MOBILEBACKUP_E_PLIST_ERROR if * backup_manifest is not of type PLIST_DICT, MOBILEBACKUP_E_MUX_ERROR * if a communication error occurs, or MOBILEBACKUP_E_REPLY_NOT_OK * if the device did not accept the request. */ mobilebackup_error_t mobilebackup_request_restore(mobilebackup_client_t client, plist_t backup_manifest, mobilebackup_flags_t flags, const char *proto_version) { if (!client || !client->parent || !backup_manifest || !proto_version) return MOBILEBACKUP_E_INVALID_ARG; if (backup_manifest && (plist_get_node_type(backup_manifest) != PLIST_DICT)) return MOBILEBACKUP_E_PLIST_ERROR; mobilebackup_error_t err; /* construct request plist */ plist_t dict = plist_new_dict(); plist_dict_insert_item(dict, "BackupManifestKey", plist_copy(backup_manifest)); plist_dict_insert_item(dict, "BackupMessageTypeKey", plist_new_string("kBackupMessageRestoreRequest")); plist_dict_insert_item(dict, "BackupProtocolVersion", plist_new_string(proto_version)); /* add flags */ plist_dict_insert_item(dict, "BackupNotifySpringBoard", plist_new_bool(IS_FLAG_SET(flags, MB_RESTORE_NOTIFY_SPRINGBOARD))); plist_dict_insert_item(dict, "BackupPreserveSettings", plist_new_bool(IS_FLAG_SET(flags, MB_RESTORE_PRESERVE_SETTINGS))); plist_dict_insert_item(dict, "BackupPreserveCameraRoll", plist_new_bool(IS_FLAG_SET(flags, MB_RESTORE_PRESERVE_CAMERA_ROLL))); /* send request */ err = mobilebackup_send_message(client, NULL, dict); plist_free(dict); dict = NULL; if (err != MOBILEBACKUP_E_SUCCESS) { debug_info("ERROR: Could not send restore request message (%d)!", err); goto leave; } /* now receive and hopefully get a BackupMessageRestoreReplyOK */ err = mobilebackup_receive_message(client, "BackupMessageRestoreReplyOK", &dict); if (err != MOBILEBACKUP_E_SUCCESS) { debug_info("ERROR: Could not receive RestoreReplyOK message (%d)!", err); goto leave; } plist_t node = plist_dict_get_item(dict, "BackupProtocolVersion"); if (node) { char *str = NULL; plist_get_string_val(node, &str); if (str) { if (strcmp(str, proto_version) != 0) { err = MOBILEBACKUP_E_BAD_VERSION; } free(str); } } leave: if (dict) plist_free(dict); return err; }
void build_identity_print_information(plist_t build_identity) { char* value = NULL; plist_t info_node = NULL; plist_t node = NULL; info_node = plist_dict_get_item(build_identity, "Info"); if (!info_node || plist_get_node_type(info_node) != PLIST_DICT) { error("ERROR: Unable to find Info node\n"); return; } node = plist_dict_get_item(info_node, "Variant"); if (!node || plist_get_node_type(node) != PLIST_STRING) { error("ERROR: Unable to find Variant node\n"); return; } plist_get_string_val(node, &value); info("Variant: %s\n", value); free(value); node = plist_dict_get_item(info_node, "RestoreBehavior"); if (!node || plist_get_node_type(node) != PLIST_STRING) { error("ERROR: Unable to find RestoreBehavior node\n"); return; } plist_get_string_val(node, &value); if (!strcmp(value, "Erase")) info("This restore will erase your device data.\n"); if (!strcmp(value, "Update")) info("This restore will update your device without loosing data.\n"); free(value); info_node = NULL; node = NULL; }
LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record) { if (!client) return LOCKDOWN_E_INVALID_ARG; if (!client->session_id) return LOCKDOWN_E_NO_RUNNING_SESSION; if (!activation_record) return LOCKDOWN_E_INVALID_ARG; lockdownd_error_t ret = LOCKDOWN_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("Activate")); plist_dict_set_item(dict,"ActivationRecord", plist_copy(activation_record)); ret = lockdownd_send(client, dict); plist_free(dict); dict = NULL; ret = lockdownd_receive(client, &dict); if (!dict) { debug_info("LOCKDOWN_E_PLIST_ERROR"); return LOCKDOWN_E_PLIST_ERROR; } ret = LOCKDOWN_E_ACTIVATION_FAILED; if (lockdown_check_result(dict, "Activate") == RESULT_SUCCESS) { debug_info("success"); ret = LOCKDOWN_E_SUCCESS; } else { plist_t error_node = plist_dict_get_item(dict, "Error"); if (error_node && PLIST_STRING == plist_get_node_type(error_node)) { char *error = NULL; plist_get_string_val(error_node, &error); if (!strcmp(error, "InvalidActivationRecord")) { ret = LOCKDOWN_E_INVALID_ACTIVATION_RECORD; } free(error); } } plist_free(dict); dict = NULL; return ret; }