/** * 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; }
int tss_request_add_ap_img3_tags(plist_t request, plist_t parameters) { plist_t node = NULL; if (!parameters) { error("ERROR: Missing required AP parameters\n"); return -1; } /* ApNonce */ node = plist_dict_get_item(parameters, "ApNonce"); if (node) { if (plist_get_node_type(node) != PLIST_DATA) { error("ERROR: Unable to find required ApNonce in parameters\n"); return -1; } plist_dict_set_item(request, "ApNonce", plist_copy(node)); node = NULL; } /* @APTicket */ plist_dict_set_item(request, "@APTicket", plist_new_bool(1)); /* ApBoardID */ node = plist_dict_get_item(request, "ApBoardID"); if (!node || plist_get_node_type(node) != PLIST_UINT) { error("ERROR: Unable to find required ApBoardID in request\n"); return -1; } node = NULL; /* ApChipID */ node = plist_dict_get_item(request, "ApChipID"); if (!node || plist_get_node_type(node) != PLIST_UINT) { error("ERROR: Unable to find required ApChipID in request\n"); return -1; } node = NULL; /* ApSecurityDomain */ node = plist_dict_get_item(request, "ApSecurityDomain"); if (!node || plist_get_node_type(node) != PLIST_UINT) { error("ERROR: Unable to find required ApSecurityDomain in request\n"); return -1; } node = NULL; /* ApProductionMode */ node = plist_dict_get_item(parameters, "ApProductionMode"); if (!node || plist_get_node_type(node) != PLIST_BOOLEAN) { error("ERROR: Unable to find required ApProductionMode in parameters\n"); return -1; } plist_dict_set_item(request, "ApProductionMode", plist_copy(node)); node = NULL; return 0; }
static diagnostics_relay_error_t internal_diagnostics_relay_action(diagnostics_relay_client_t client, const char* name, int flags) { if (!client) return DIAGNOSTICS_RELAY_E_INVALID_ARG; diagnostics_relay_error_t ret = DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR; plist_t dict = plist_new_dict(); plist_dict_insert_item(dict,"Request", plist_new_string(name)); if (flags & DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT) { plist_dict_insert_item(dict, "WaitForDisconnect", plist_new_bool(1)); } if (flags & DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_PASS) { plist_dict_insert_item(dict, "DisplayPass", plist_new_bool(1)); } if (flags & DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_FAIL) { plist_dict_insert_item(dict, "DisplayFail", plist_new_bool(1)); } ret = diagnostics_relay_send(client, dict); plist_free(dict); dict = NULL; ret = diagnostics_relay_receive(client, &dict); if (!dict) { return DIAGNOSTICS_RELAY_E_PLIST_ERROR; } int check = diagnostics_relay_check_result(dict); if (check == RESULT_SUCCESS) { ret = DIAGNOSTICS_RELAY_E_SUCCESS; } else if (check == RESULT_UNKNOWN_REQUEST) { ret = DIAGNOSTICS_RELAY_E_UNKNOWN_REQUEST; } else { ret = DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR; } plist_free(dict); return ret; }
int tss_request_add_ap_img4_tags(plist_t request, plist_t parameters) { plist_t node = NULL; if (!parameters) { error("ERROR: Missing required AP parameters\n"); return -1; } /* ApNonce */ node = plist_dict_get_item(parameters, "ApNonce"); if (!node || plist_get_node_type(node) != PLIST_DATA) { error("ERROR: Unable to find required ApNonce in parameters\n"); return -1; } plist_dict_set_item(request, "ApNonce", plist_copy(node)); node = NULL; plist_dict_set_item(request, "@ApImg4Ticket", plist_new_bool(1)); /* ApSecurityMode */ node = plist_dict_get_item(request, "ApSecurityMode"); if (!node) { /* copy from parameters if available */ node = plist_dict_get_item(parameters, "ApSecurityMode"); if (!node || plist_get_node_type(node) != PLIST_BOOLEAN) { error("ERROR: Unable to find required ApSecurityMode in parameters\n"); return -1; } plist_dict_set_item(request, "ApSecurityMode", plist_copy(node)); node = NULL; } node = plist_dict_get_item(request, "ApProductionMode"); if (!node) { /* ApProductionMode */ node = plist_dict_get_item(parameters, "ApProductionMode"); if (!node || plist_get_node_type(node) != PLIST_BOOLEAN) { error("ERROR: Unable to find required ApProductionMode in parameters\n"); return -1; } plist_dict_set_item(request, "ApProductionMode", plist_copy(node)); node = NULL; } /* ApSepNonce */ node = plist_dict_get_item(parameters, "ApSepNonce"); if (!node || plist_get_node_type(node) != PLIST_DATA) { error("ERROR: Unable to find required ApSepNonce in parameters\n"); return -1; } plist_dict_set_item(request, "SepNonce", plist_copy(node)); node = NULL; return 0; }
/** * Add one or more new key:value pairs to the given client_options. * * @param client_options The client options to modify. * @param ... KEY, VALUE, [KEY, VALUE], NULL * * @note The keys and values passed are expected to be strings, except for the * keys "ApplicationSINF", "iTunesMetadata", "ReturnAttributes" which are * expecting a plist_t node as value and "SkipUninstall" expects int. */ void instproxy_client_options_add(plist_t client_options, ...) { if (!client_options) return; va_list args; va_start(args, client_options); char *arg = va_arg(args, char*); while (arg) { char *key = strdup(arg); if (!strcmp(key, "SkipUninstall")) { int intval = va_arg(args, int); plist_dict_insert_item(client_options, key, plist_new_bool(intval)); } else if (!strcmp(key, "ApplicationSINF") || !strcmp(key, "iTunesMetadata") || !strcmp(key, "ReturnAttributes")) {
int tss_populate_devicevals(plist_t tssreq, uint64_t ecid, char *nonce, size_t nonce_size, char *sep_nonce, size_t sep_nonce_size, int image4supported){ plist_dict_set_item(tssreq, "ApECID", plist_new_uint(ecid)); //0000000000000000 if (nonce) { plist_dict_set_item(tssreq, "ApNonce", plist_new_data(nonce, nonce_size));//aa aa aa aa bb cc dd ee ff 00 11 22 33 44 55 66 77 88 99 aa } if (sep_nonce) {//aa aa aa aa bb cc dd ee ff 00 11 22 33 44 55 66 77 88 99 aa plist_dict_set_item(tssreq, "ApSepNonce", plist_new_data(sep_nonce, sep_nonce_size)); } plist_dict_set_item(tssreq, "ApProductionMode", plist_new_bool(1)); if (image4supported) { plist_dict_set_item(tssreq, "ApSecurityMode", plist_new_bool(1)); plist_dict_set_item(tssreq, "ApSupportsImg4", plist_new_bool(1)); } else { plist_dict_set_item(tssreq, "ApSupportsImg4", plist_new_bool(0)); } return 0; }
static plist_t create_process_changes_message(const char *data_class, plist_t entities, uint8_t more_changes, plist_t actions) { plist_t msg = plist_new_array(); plist_array_append_item(msg, plist_new_string("SDMessageProcessChanges")); plist_array_append_item(msg, plist_new_string(data_class)); plist_array_append_item(msg, plist_copy(entities)); plist_array_append_item(msg, plist_new_bool(more_changes)); if (actions) plist_array_append_item(msg, plist_copy(actions)); else plist_array_append_item(msg, plist_new_string(EMPTY_PARAMETER_STRING)); return msg; }
Node::Node(plist_type type, Node* parent) : _parent(parent) { _node = NULL; switch (type) { case PLIST_BOOLEAN: _node = plist_new_bool(0); break; case PLIST_UINT: _node = plist_new_uint(0); break; case PLIST_REAL: _node = plist_new_real(0.); break; case PLIST_STRING: _node = plist_new_string(""); break; case PLIST_KEY: _node = plist_new_string(""); plist_set_key_val(_node, ""); break; case PLIST_UID: _node = plist_new_uid(0); break; case PLIST_DATA: _node = plist_new_data(NULL,0); break; case PLIST_DATE: _node = plist_new_date(0,0); break; case PLIST_ARRAY: _node = plist_new_array(); break; case PLIST_DICT: _node = plist_new_dict(); break; case PLIST_NONE: default: break; } }
plist_t tss_create_request(plist_t build_identity, uint64_t ecid, unsigned char* nonce, int nonce_size) { uint64_t unique_build_size = 0; char* unique_build_data = NULL; plist_t unique_build_node = plist_dict_get_item(build_identity, "UniqueBuildID"); if (!unique_build_node || plist_get_node_type(unique_build_node) != PLIST_DATA) { error("ERROR: Unable to find UniqueBuildID node\n"); return NULL; } plist_get_data_val(unique_build_node, &unique_build_data, &unique_build_size); int chip_id = 0; char* chip_id_string = NULL; plist_t chip_id_node = plist_dict_get_item(build_identity, "ApChipID"); if (!chip_id_node || plist_get_node_type(chip_id_node) != PLIST_STRING) { error("ERROR: Unable to find ApChipID node\n"); return NULL; } plist_get_string_val(chip_id_node, &chip_id_string); sscanf(chip_id_string, "%x", &chip_id); int board_id = 0; char* board_id_string = NULL; plist_t board_id_node = plist_dict_get_item(build_identity, "ApBoardID"); if (!board_id_node || plist_get_node_type(board_id_node) != PLIST_STRING) { error("ERROR: Unable to find ApBoardID node\n"); return NULL; } plist_get_string_val(board_id_node, &board_id_string); sscanf(board_id_string, "%x", &board_id); int security_domain = 0; char* security_domain_string = NULL; plist_t security_domain_node = plist_dict_get_item(build_identity, "ApSecurityDomain"); if (!security_domain_node || plist_get_node_type(security_domain_node) != PLIST_STRING) { error("ERROR: Unable to find ApSecurityDomain node\n"); return NULL; } plist_get_string_val(security_domain_node, &security_domain_string); sscanf(security_domain_string, "%x", &security_domain); char ecid_string[ECID_STRSIZE]; memset(ecid_string, '\0', ECID_STRSIZE); if (ecid == 0) { error("ERROR: Unable to get ECID\n"); return NULL; } snprintf(ecid_string, ECID_STRSIZE, FMT_qu, (long long unsigned int)ecid); // Add build information to TSS request plist_t tss_request = plist_new_dict(); plist_dict_insert_item(tss_request, "@APTicket", plist_new_bool(1)); plist_dict_insert_item(tss_request, "@BBTicket", plist_new_bool(1)); plist_dict_insert_item(tss_request, "@HostIpAddress", plist_new_string("192.168.0.1")); plist_dict_insert_item(tss_request, "@HostPlatformInfo", plist_new_string("mac")); plist_dict_insert_item(tss_request, "@Locality", plist_new_string("en_US")); char* guid = generate_guid(); if (guid) { plist_dict_insert_item(tss_request, "@UUID", plist_new_string(guid)); free(guid); } plist_dict_insert_item(tss_request, "@VersionInfo", plist_new_string("libauthinstall-107.3")); plist_dict_insert_item(tss_request, "ApBoardID", plist_new_uint(board_id)); plist_dict_insert_item(tss_request, "ApChipID", plist_new_uint(chip_id)); plist_dict_insert_item(tss_request, "ApECID", plist_new_string(ecid_string)); if (nonce && (nonce_size > 0)) { plist_dict_insert_item(tss_request, "ApNonce", plist_new_data(nonce, nonce_size)); } plist_dict_insert_item(tss_request, "ApProductionMode", plist_new_bool(1)); plist_dict_insert_item(tss_request, "ApSecurityDomain", plist_new_uint(security_domain)); plist_dict_insert_item(tss_request, "UniqueBuildID", plist_new_data(unique_build_data, unique_build_size)); free(unique_build_data); // Add all firmware files to TSS request plist_t manifest_node = plist_dict_get_item(build_identity, "Manifest"); if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { error("ERROR: Unable to find restore manifest\n"); plist_free(tss_request); return NULL; } char* key = NULL; plist_t manifest_entry = NULL; plist_dict_iter iter = NULL; plist_dict_new_iter(manifest_node, &iter); while (1) { plist_dict_next_item(manifest_node, iter, &key, &manifest_entry); if (key == NULL) break; if (!manifest_entry || plist_get_node_type(manifest_entry) != PLIST_DICT) { error("ERROR: Unable to fetch BuildManifest entry\n"); free(tss_request); return NULL; } if (strcmp(key, "BasebandFirmware") == 0) { free(key); continue; } plist_t tss_entry = plist_copy(manifest_entry); plist_dict_insert_item(tss_request, key, tss_entry); free(key); } if (idevicerestore_debug) { debug_plist(tss_request); } return tss_request; }
/** * 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 tss_request_add_se_tags(plist_t request, plist_t parameters, plist_t overrides) { plist_t node = NULL; plist_t manifest_node = plist_dict_get_item(parameters, "Manifest"); if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); return -1; } /* add tags indicating we want to get the SE,Ticket */ plist_dict_set_item(request, "@BBTicket", plist_new_bool(1)); plist_dict_set_item(request, "@SE,Ticket", plist_new_bool(1)); /* add SE,ChipID */ node = plist_dict_get_item(parameters, "SE,ChipID"); if (!node) { error("ERROR: %s: Unable to find required SE,ChipID in parameters\n", __func__); return -1; } plist_dict_set_item(request, "SE,ChipID", plist_copy(node)); node = NULL; /* add SE,ID */ node = plist_dict_get_item(parameters, "SE,ID"); if (!node) { error("ERROR: %s: Unable to find required SE,ID in parameters\n", __func__); return -1; } plist_dict_set_item(request, "SE,ID", plist_copy(node)); node = NULL; /* add SE,Nonce */ node = plist_dict_get_item(parameters, "SE,Nonce"); if (!node) { error("ERROR: %s: Unable to find required SE,Nonce in parameters\n", __func__); return -1; } plist_dict_set_item(request, "SE,Nonce", plist_copy(node)); node = NULL; /* add SE,RootKeyIdentifier */ node = plist_dict_get_item(parameters, "SE,RootKeyIdentifier"); if (!node) { error("ERROR: %s: Unable to find required SE,RootKeyIdentifier in parameters\n", __func__); return -1; } plist_dict_set_item(request, "SE,RootKeyIdentifier", plist_copy(node)); node = NULL; /* 'IsDev' determines whether we have Production or Development */ const char *removing_cmac_key = "DevelopmentCMAC"; node = plist_dict_get_item(parameters, "SE,IsDev"); if (node && plist_get_node_type(node) == PLIST_BOOLEAN) { uint8_t is_dev = 0; plist_get_bool_val(node, &is_dev); removing_cmac_key = (is_dev) ? "ProductionCMAC" : "DevelopmentCMAC"; } /* add SE,* components from build manifest to request */ char* key = NULL; plist_t manifest_entry = NULL; plist_dict_iter iter = NULL; plist_dict_new_iter(manifest_node, &iter); while (1) { key = NULL; plist_dict_next_item(manifest_node, iter, &key, &manifest_entry); if (key == NULL) break; if (!manifest_entry || plist_get_node_type(manifest_entry) != PLIST_DICT) { free(key); error("ERROR: Unable to fetch BuildManifest entry\n"); return -1; } if (strncmp(key, "SE,", 3)) { free(key); continue; } /* copy this entry */ plist_t tss_entry = plist_copy(manifest_entry); /* remove Info node */ plist_dict_remove_item(tss_entry, "Info"); /* remove 'DevelopmentCMAC' (or 'ProductionCMAC') node */ if (plist_dict_get_item(tss_entry, removing_cmac_key)) { plist_dict_remove_item(tss_entry, removing_cmac_key); } /* add entry to request */ plist_dict_set_item(request, key, tss_entry); free(key); } free(iter); /* apply overrides */ if (overrides) { plist_dict_merge(&request, overrides); } return 0; }
int tss_request_add_baseband_tags(plist_t request, plist_t parameters, plist_t overrides) { plist_t node = NULL; /* BbChipID */ node = plist_dict_get_item(parameters, "BbChipID"); if (node) { plist_dict_set_item(request, "BbChipID", plist_copy(node)); } node = NULL; /* BbProvisioningManifestKeyHash */ node = plist_dict_get_item(parameters, "BbProvisioningManifestKeyHash"); if (node) { plist_dict_set_item(request, "BbProvisioningManifestKeyHash", plist_copy(node)); } node = NULL; /* BbActivationManifestKeyHash - Used by Qualcomm MDM6610 */ node = plist_dict_get_item(parameters, "BbActivationManifestKeyHash"); if (node) { plist_dict_set_item(request, "BbActivationManifestKeyHash", plist_copy(node)); } node = NULL; node = plist_dict_get_item(parameters, "BbCalibrationManifestKeyHash"); if (node) { plist_dict_set_item(request, "BbCalibrationManifestKeyHash", plist_copy(node)); } node = NULL; /* BbFactoryActivationManifestKeyHash */ node = plist_dict_get_item(parameters, "BbFactoryActivationManifestKeyHash"); if (node) { plist_dict_set_item(request, "BbFactoryActivationManifestKeyHash", plist_copy(node)); } node = NULL; /* BbFDRSecurityKeyHash */ node = plist_dict_get_item(parameters, "BbFDRSecurityKeyHash"); if (node) { plist_dict_set_item(request, "BbFDRSecurityKeyHash", plist_copy(node)); } node = NULL; /* BbSkeyId - Used by XMM 6180/GSM */ node = plist_dict_get_item(parameters, "BbSkeyId"); if (node) { plist_dict_set_item(request, "BbSkeyId", plist_copy(node)); } node = NULL; /* BbNonce */ node = plist_dict_get_item(parameters, "BbNonce"); if (node) { plist_dict_set_item(request, "BbNonce", plist_copy(node)); } node = NULL; /* @BBTicket */ plist_dict_set_item(request, "@BBTicket", plist_new_bool(1)); /* BbGoldCertId */ node = plist_dict_get_item(parameters, "BbGoldCertId"); if (!node || plist_get_node_type(node) != PLIST_UINT) { error("ERROR: Unable to find required BbGoldCertId in parameters\n"); return -1; } node = plist_copy(node); uint64_t val; plist_get_uint_val(node, &val); plist_set_uint_val(node, (int32_t)val); plist_dict_set_item(request, "BbGoldCertId", node); node = NULL; /* BbSNUM */ node = plist_dict_get_item(parameters, "BbSNUM"); if (!node || plist_get_node_type(node) != PLIST_DATA) { error("ERROR: Unable to find required BbSNUM in parameters\n"); return -1; } plist_dict_set_item(request, "BbSNUM", plist_copy(node)); node = NULL; /* BasebandFirmware */ node = plist_access_path(parameters, 2, "Manifest", "BasebandFirmware"); if (!node || plist_get_node_type(node) != PLIST_DICT) { error("ERROR: Unable to get BasebandFirmware node\n"); return -1; } plist_t bbfwdict = plist_copy(node); node = NULL; if (plist_dict_get_item(bbfwdict, "Info")) { plist_dict_remove_item(bbfwdict, "Info"); } plist_dict_set_item(request, "BasebandFirmware", bbfwdict); /* apply overrides */ if (overrides) { plist_dict_merge(&request, overrides); } return 0; }
static void tss_entry_apply_restore_request_rules(plist_t tss_entry, plist_t parameters, plist_t rules) { if (!tss_entry || !rules) { return; } if (plist_get_node_type(tss_entry) != PLIST_DICT) { return; } if (plist_get_node_type(rules) != PLIST_ARRAY) { return; } uint32_t i; for (i = 0; i < plist_array_get_size(rules); i++) { plist_t rule = plist_array_get_item(rules, i); plist_t conditions = plist_dict_get_item(rule, "Conditions"); plist_dict_iter iter = NULL; plist_dict_new_iter(conditions, &iter); char* key = NULL; plist_t value = NULL; plist_t value2 = NULL; int conditions_fulfilled = 1; while (conditions_fulfilled) { plist_dict_next_item(conditions, iter, &key, &value); if (key == NULL) break; if (!strcmp(key, "ApRawProductionMode")) { value2 = plist_dict_get_item(parameters, "ApProductionMode"); } else if (!strcmp(key, "ApCurrentProductionMode")) { value2 = plist_dict_get_item(parameters, "ApProductionMode"); } else if (!strcmp(key, "ApRawSecurityMode")) { value2 = plist_dict_get_item(parameters, "ApSecurityMode"); } else if (!strcmp(key, "ApRequiresImage4")) { value2 = plist_dict_get_item(parameters, "ApSupportsImg4"); } else if (!strcmp(key, "ApDemotionPolicyOverride")) { value2 = plist_dict_get_item(parameters, "DemotionPolicy"); } else if (!strcmp(key, "ApInRomDFU")) { value2 = plist_dict_get_item(parameters, "ApInRomDFU"); } else { error("WARNING: Unhandled condition '%s' while parsing RestoreRequestRules\n", key); value2 = NULL; } if (value2) { conditions_fulfilled = plist_compare_node_value(value, value2); } else { conditions_fulfilled = 0; } free(key); } free(iter); iter = NULL; if (!conditions_fulfilled) { continue; } plist_t actions = plist_dict_get_item(rule, "Actions"); plist_dict_new_iter(actions, &iter); while (1) { plist_dict_next_item(actions, iter, &key, &value); if (key == NULL) break; uint8_t bv = 0; plist_get_bool_val(value, &bv); if (bv) { value2 = plist_dict_get_item(tss_entry, key); if (value2) { plist_dict_remove_item(tss_entry, key); } debug("DEBUG: Adding action %s to TSS entry\n", key); plist_dict_set_item(tss_entry, key, plist_new_bool(1)); } free(key); } } }
int tss_request_add_yonkers_tags(plist_t request, plist_t parameters, plist_t overrides, char **component_name) { plist_t node = NULL; plist_t manifest_node = plist_dict_get_item(parameters, "Manifest"); if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); return -1; } /* add tags indicating we want to get the Savage,Ticket */ plist_dict_set_item(request, "@BBTicket", plist_new_bool(1)); plist_dict_set_item(request, "@Yonkers,Ticket", plist_new_bool(1)); /* add SEP */ node = plist_access_path(manifest_node, 2, "SEP", "Digest"); if (!node) { error("ERROR: Unable to get SEP digest from manifest\n"); return -1; } plist_t dict = plist_new_dict(); plist_dict_set_item(dict, "Digest", plist_copy(node)); plist_dict_set_item(request, "SEP", dict); { static const char *keys[] = {"Yonkers,AllowOfflineBoot", "Yonkers,BoardID", "Yonkers,ChipID", "Yonkers,ECID", "Yonkers,Nonce", "Yonkers,PatchEpoch", "Yonkers,ProductionMode", "Yonkers,ReadECKey", "Yonkers,ReadFWKey", }; int i; for (i = 0; i < (int)(sizeof(keys) / sizeof(keys[0])); ++i) { node = plist_dict_get_item(parameters, keys[i]); if (!node) { error("ERROR: %s: Unable to find required %s in parameters\n", __func__, keys[i]); } plist_dict_set_item(request, keys[i], plist_copy(node)); node = NULL; } } char *comp_name = NULL; plist_t comp_node = NULL; uint8_t isprod = 1; uint64_t fabrevision = (uint64_t)-1; node = plist_dict_get_item(parameters, "Yonkers,ProductionMode"); if (node && (plist_get_node_type(node) == PLIST_BOOLEAN)) { plist_get_bool_val(node, &isprod); } node = plist_dict_get_item(parameters, "Yonkers,FabRevision"); if (node && (plist_get_node_type(node) == PLIST_UINT)) { plist_get_uint_val(node, &fabrevision); } plist_dict_iter iter = NULL; plist_dict_new_iter(manifest_node, &iter); while (iter) { node = NULL; comp_name = NULL; plist_dict_next_item(manifest_node, iter, &comp_name, &node); if (comp_name == NULL) { node = NULL; break; } if (strncmp(comp_name, "Yonkers,", 8) == 0) { int target_node = 1; plist_t sub_node; if ((sub_node = plist_dict_get_item(node, "EPRO")) != NULL && plist_get_node_type(sub_node) == PLIST_BOOLEAN) { uint8_t b = 0; plist_get_bool_val(sub_node, &b); target_node &= ((isprod) ? b : !b); } if ((sub_node = plist_dict_get_item(node, "FabRevision")) != NULL && plist_get_node_type(sub_node) == PLIST_UINT) { uint64_t v = 0; plist_get_uint_val(sub_node, &v); target_node &= (v == fabrevision); } if (target_node) { comp_node = node; break; } } free(comp_name); } free(iter); if (comp_name == NULL) { error("ERROR: No Yonkers node for %s/%lu\n", (isprod) ? "Production" : "Development", (unsigned long)fabrevision); return -1; } /* add Yonkers,SysTopPatch* */ if (comp_node != NULL) { plist_t comp_dict = plist_copy(comp_node); plist_dict_remove_item(comp_dict, "Info"); plist_dict_set_item(request, comp_name, comp_dict); } if (component_name) { *component_name = comp_name; } else { free(comp_name); } /* apply overrides */ if (overrides) { plist_dict_merge(&request, overrides); } return 0; }
int tss_request_add_savage_tags(plist_t request, plist_t parameters, plist_t overrides, char **component_name) { plist_t node = NULL; plist_t manifest_node = plist_dict_get_item(parameters, "Manifest"); if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) { error("ERROR: %s: Unable to get restore manifest from parameters\n", __func__); return -1; } /* add tags indicating we want to get the Savage,Ticket */ plist_dict_set_item(request, "@BBTicket", plist_new_bool(1)); plist_dict_set_item(request, "@Savage,Ticket", plist_new_bool(1)); /* add Savage,UID */ node = plist_dict_get_item(parameters, "Savage,UID"); if (!node) { error("ERROR: %s: Unable to find required Savage,UID in parameters\n", __func__); return -1; } plist_dict_set_item(request, "Savage,UID", plist_copy(node)); node = NULL; /* add SEP */ node = plist_access_path(manifest_node, 2, "SEP", "Digest"); if (!node) { error("ERROR: Unable to get SEP digest from manifest\n"); return -1; } plist_t dict = plist_new_dict(); plist_dict_set_item(dict, "Digest", plist_copy(node)); plist_dict_set_item(request, "SEP", dict); /* add Savage,PatchEpoch */ node = plist_dict_get_item(parameters, "Savage,PatchEpoch"); if (!node) { error("ERROR: %s: Unable to find required Savage,PatchEpoch in parameters\n", __func__); return -1; } plist_dict_set_item(request, "Savage,PatchEpoch", plist_copy(node)); node = NULL; /* add Savage,ChipID */ node = plist_dict_get_item(parameters, "Savage,ChipID"); if (!node) { error("ERROR: %s: Unable to find required Savage,ChipID in parameters\n", __func__); return -1; } plist_dict_set_item(request, "Savage,ChipID", plist_copy(node)); node = NULL; /* add Savage,AllowOfflineBoot */ node = plist_dict_get_item(parameters, "Savage,AllowOfflineBoot"); if (!node) { error("ERROR: %s: Unable to find required Savage,AllowOfflineBoot in parameters\n", __func__); return -1; } plist_dict_set_item(request, "Savage,AllowOfflineBoot", plist_copy(node)); node = NULL; /* add Savage,ReadFWKey */ node = plist_dict_get_item(parameters, "Savage,ReadFWKey"); if (!node) { error("ERROR: %s: Unable to find required Savage,ReadFWKey in parameters\n", __func__); return -1; } plist_dict_set_item(request, "Savage,ReadFWKey", plist_copy(node)); node = NULL; /* add Savage,ProductionMode */ node = plist_dict_get_item(parameters, "Savage,ProductionMode"); if (!node) { error("ERROR: %s: Unable to find required Savage,ProductionMode in parameters\n", __func__); return -1; } plist_dict_set_item(request, "Savage,ProductionMode", plist_copy(node)); const char *comp_name = NULL; uint8_t isprod = 0; plist_get_bool_val(node, &isprod); node = NULL; /* get the right component name */ comp_name = (isprod) ? "Savage,B0-Prod-Patch" : "Savage,B0-Dev-Patch"; node = plist_dict_get_item(parameters, "Savage,Revision"); if (node && (plist_get_node_type(node) == PLIST_DATA)) { unsigned char *savage_rev = NULL; uint64_t savage_rev_len = 0; plist_get_data_val(node, (char**)&savage_rev, &savage_rev_len); if (savage_rev_len > 0) { if (((savage_rev[0] | 0x10) & 0xF0) == 0x30) { comp_name = (isprod) ? "Savage,B2-Prod-Patch" : "Savage,B2-Dev-Patch"; } else if ((savage_rev[0] & 0xF0) == 0xA0) { comp_name = (isprod) ? "Savage,BA-Prod-Patch" : "Savage,BA-Dev-Patch"; } } free(savage_rev); } /* add Savage,B?-*-Patch */ node = plist_dict_get_item(manifest_node, comp_name); if (!node) { error("ERROR: Unable to get %s entry from manifest\n", comp_name); return -1; } dict = plist_copy(node); plist_dict_remove_item(dict, "Info"); plist_dict_set_item(request, comp_name, dict); if (component_name) { *component_name = strdup(comp_name); } /* add Savage,Nonce */ node = plist_dict_get_item(parameters, "Savage,Nonce"); if (!node) { error("ERROR: %s: Unable to find required Savage,Nonce in parameters\n", __func__); return -1; } plist_dict_set_item(request, "Savage,Nonce", plist_copy(node)); node = NULL; /* add Savage,ReadECKey */ node = plist_dict_get_item(parameters, "Savage,ReadECKey"); if (!node) { error("ERROR: %s: Unable to find required Savage,ReadECKey in parameters\n", __func__); return -1; } plist_dict_set_item(request, "Savage,ReadECKey", plist_copy(node)); node = NULL; /* apply overrides */ if (overrides) { plist_dict_merge(&request, overrides); } return 0; }