Beispiel #1
0
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;
	}
}
static int
get_dictval_bool_from_key(plist_t dict, const char *key, uint8_t *val)
{
  plist_t node;

  node = plist_dict_get_item(dict, key);

  /* Not present means false */
  if (!node)
    {
      *val = 0;

      return 0;
    }

  if (plist_get_node_type(node) != PLIST_BOOLEAN)
    return -1;

  plist_get_bool_val(node, val);

  return 0;
}
Beispiel #3
0
static void plist_node_to_string(plist_t node)
{
	char *s = NULL;
	char *data = NULL;
	double d;
	uint8_t b;
	uint64_t u = 0;
	GTimeVal tv = { 0, 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", (long long)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:
		plist_get_data_val(node, &data, &u);
		s = g_base64_encode((guchar *)data, u);
		free(data);
		printf("%s\n", s);
		g_free(s);
		break;

	case PLIST_DATE:
		plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec);
		s = g_time_val_to_iso8601(&tv);
		printf("%s\n", s);
		free(s);
		break;

	case PLIST_ARRAY:
		printf("\n");
		indent_level++;
		plist_array_to_string(node);
		indent_level--;
		break;

	case PLIST_DICT:
		printf("\n");
		indent_level++;
		plist_dict_to_string(node);
		indent_level--;
		break;

	default:
		break;
	}
}
static void plist_node_to_string(plist_t node)
{
	char *s = NULL;
	char *data = NULL;
	double d;
	uint8_t b;
	uint64_t u = 0;
	struct timeval tv = { 0, 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", (long long)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:
		plist_get_data_val(node, &data, &u);
		uint64_t i;
		for (i = 0; i < u; i++) {
			printf("%02x", (unsigned char)data[i]);
		}
		free(data);
		printf("\n");
		break;

	case PLIST_DATE:
		plist_get_date_val(node, (int32_t*)&tv.tv_sec, (int32_t*)&tv.tv_usec);
		{
			time_t ti = (time_t)tv.tv_sec;
			struct tm *btime = localtime(&ti);
			if (btime) {
				s = (char*)malloc(24);
 				memset(s, 0, 24);
				if (strftime(s, 24, "%Y-%m-%dT%H:%M:%SZ", btime) <= 0) {
					free (s);
					s = NULL;
				}
			}
		}
		if (s) {
			puts(s);
			free(s);
		}
		puts("\n");
		break;

	case PLIST_ARRAY:
		printf("\n");
		indent_level++;
		plist_array_to_string(node);
		indent_level--;
		break;

	case PLIST_DICT:
		printf("\n");
		indent_level++;
		plist_dict_to_string(node);
		indent_level--;
		break;

	default:
		break;
	}
}
Beispiel #5
0
/**
 * Function used internally by lockdownd_start_service and lockdownd_start_service_with_escrow_bag.
 *
 * @param client The lockdownd client
 * @param identifier The identifier of the service to start
 * @param send_escrow_bag Should we send the device's escrow bag with the request
 * @param descriptor The service descriptor on success or NULL on failure
 *
 * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG if a parameter
 *  is NULL, LOCKDOWN_E_INVALID_SERVICE if the requested service is not known
 *  by the device, LOCKDOWN_E_START_SERVICE_FAILED if the service could not because
 *  started by the device, LOCKDOWN_E_INVALID_CONF if the host id or escrow bag (when
 *  used) are missing from the device record.
 */
static lockdownd_error_t lockdownd_do_start_service(lockdownd_client_t client, const char *identifier, int send_escrow_bag, lockdownd_service_descriptor_t *service)
{
	if (!client || !identifier || !service)
		return LOCKDOWN_E_INVALID_ARG;

	if (*service) {
		// reset fields if service descriptor is reused
		(*service)->port = 0;
		(*service)->ssl_enabled = 0;
	}

	plist_t dict = NULL;
	uint16_t port_loc = 0;
	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;

	/* create StartService request */
	ret = lockdownd_build_start_service_request(client, identifier, send_escrow_bag, &dict);
	if (LOCKDOWN_E_SUCCESS != ret)
		return ret;

	/* send to device */
	ret = lockdownd_send(client, dict);
	plist_free(dict);
	dict = NULL;

	if (LOCKDOWN_E_SUCCESS != ret)
		return ret;

	ret = lockdownd_receive(client, &dict);

	if (LOCKDOWN_E_SUCCESS != ret)
		return ret;

	if (!dict)
		return LOCKDOWN_E_PLIST_ERROR;

	ret = LOCKDOWN_E_UNKNOWN_ERROR;
	if (lockdown_check_result(dict, "StartService") == RESULT_SUCCESS) {
		if (*service == NULL)
			*service = (lockdownd_service_descriptor_t)malloc(sizeof(struct lockdownd_service_descriptor));
		(*service)->port = 0;
		(*service)->ssl_enabled = 0;

		/* read service port number */
		plist_t node = plist_dict_get_item(dict, "Port");
		if (node && (plist_get_node_type(node) == PLIST_UINT)) {
			uint64_t port_value = 0;
			plist_get_uint_val(node, &port_value);

			if (port_value) {
				port_loc = port_value;
				ret = LOCKDOWN_E_SUCCESS;
			}
			if (port_loc && ret == LOCKDOWN_E_SUCCESS) {
				(*service)->port = port_loc;
			}
		}

		/* check if the service requires SSL */
		node = plist_dict_get_item(dict, "EnableServiceSSL");
		if (node && (plist_get_node_type(node) == PLIST_BOOLEAN)) {
			uint8_t b = 0;
			plist_get_bool_val(node, &b);
			(*service)->ssl_enabled = b;
		}
	} else {
		ret = LOCKDOWN_E_START_SERVICE_FAILED;
		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, "InvalidService")) {
				ret = LOCKDOWN_E_INVALID_SERVICE;
			} else if (!strcmp(error, "NoRunningSession")) {
				ret = LOCKDOWN_E_NO_RUNNING_SESSION;
			}
			free(error);
		}
	}

	plist_free(dict);
	dict = NULL;
	return ret;
}
Beispiel #6
0
LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char *host_id, char **session_id, int *ssl_enabled)
{
	lockdownd_error_t ret = LOCKDOWN_E_SUCCESS;
	property_list_service_error_t plret;
	plist_t dict = NULL;

	if (!client || !host_id)
		ret = LOCKDOWN_E_INVALID_ARG;

	/* if we have a running session, stop current one first */
	if (client->session_id) {
		lockdownd_stop_session(client, client->session_id);
	}

	/* setup request plist */
	dict = plist_new_dict();
	plist_dict_add_label(dict, client->label);
	plist_dict_set_item(dict,"Request", plist_new_string("StartSession"));

	/* add host id */
	if (host_id) {
		plist_dict_set_item(dict, "HostID", plist_new_string(host_id));
	}

	/* add system buid */
	char *system_buid = NULL;
	userpref_read_system_buid(&system_buid);
	if (system_buid) {
		plist_dict_set_item(dict, "SystemBUID", plist_new_string(system_buid));
		if (system_buid) {
			free(system_buid);
			system_buid = NULL;
		}
	}

	ret = lockdownd_send(client, dict);
	plist_free(dict);
	dict = NULL;

	if (ret != LOCKDOWN_E_SUCCESS)
		return ret;

	ret = lockdownd_receive(client, &dict);

	if (!dict)
		return LOCKDOWN_E_PLIST_ERROR;

	if (lockdown_check_result(dict, "StartSession") == RESULT_FAILURE) {
		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, "InvalidHostID")) {
				ret = LOCKDOWN_E_INVALID_HOST_ID;
			}
			free(error);
		}
	} else {
		uint8_t use_ssl = 0;

		plist_t enable_ssl = plist_dict_get_item(dict, "EnableSessionSSL");
		if (enable_ssl && (plist_get_node_type(enable_ssl) == PLIST_BOOLEAN)) {
			plist_get_bool_val(enable_ssl, &use_ssl);
		}
		debug_info("Session startup OK");

		if (ssl_enabled != NULL)
			*ssl_enabled = use_ssl;

		/* store session id, we need it for StopSession */
		plist_t session_node = plist_dict_get_item(dict, "SessionID");
		if (session_node && (plist_get_node_type(session_node) == PLIST_STRING)) {
			plist_get_string_val(session_node, &client->session_id);
		}

		if (client->session_id) {
			debug_info("SessionID: %s", client->session_id);
			if (session_id != NULL)
				*session_id = strdup(client->session_id);
		} else {
			debug_info("Failed to get SessionID!");
		}

		debug_info("Enable SSL Session: %s", (use_ssl?"true":"false"));

		if (use_ssl) {
			plret = property_list_service_enable_ssl(client->parent);
			if (plret == PROPERTY_LIST_SERVICE_E_SUCCESS) {
				ret = LOCKDOWN_E_SUCCESS;
				client->ssl_enabled = 1;
			} else {
				ret = LOCKDOWN_E_SSL_ERROR;
				client->ssl_enabled = 0;
			}
		} else {
			client->ssl_enabled = 0;
			ret = LOCKDOWN_E_SUCCESS;
		}
	}

	plist_free(dict);
	dict = NULL;

	return ret;
}
Beispiel #7
0
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;
}
Beispiel #8
0
int tss_request_add_ap_tags(plist_t request, plist_t parameters, plist_t overrides) {
	/* loop over components from build manifest */
	plist_t manifest_node = plist_dict_get_item(parameters, "Manifest");
	if (!manifest_node || plist_get_node_type(manifest_node) != PLIST_DICT) {
		error("ERROR: Unable to find restore manifest\n");
		return -1;
	}

	/* add components to request */
	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");
			return -1;
		}

		/* do not populate BaseBandFirmware, only in basebaseband request */
		if ((strcmp(key, "BasebandFirmware") == 0)) {
			free(key);
			continue;
		}

		/* FIXME: only used with diagnostics firmware */
		if (strcmp(key, "Diags") == 0) {
			free(key);
			continue;
		}

		/* copy this entry */
		plist_t tss_entry = plist_copy(manifest_entry);

		/* remove obsolete Info node */
		plist_dict_remove_item(tss_entry, "Info");

		/* handle RestoreRequestRules */
		plist_t rules = plist_access_path(manifest_entry, 2, "Info", "RestoreRequestRules");
		if (rules) {
			debug("DEBUG: Applying restore request rules for entry %s\n", key);
			tss_entry_apply_restore_request_rules(tss_entry, parameters, rules);
		}

		/* Make sure we have a Digest key for Trusted items even if empty */
		plist_t node = plist_dict_get_item(manifest_entry, "Trusted");
		if (node && plist_get_node_type(node) == PLIST_BOOLEAN) {
			uint8_t trusted;
			plist_get_bool_val(node, &trusted);
			if (trusted && !plist_access_path(manifest_entry, 1, "Digest")) {
				debug("DEBUG: No Digest data, using empty value for entry %s\n", key);
				plist_dict_set_item(tss_entry, "Digest", plist_new_data(NULL, 0));
			}
		}

		/* finally 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;
}
Beispiel #9
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);
		}
	}
}
Beispiel #10
0
int asr_open_with_timeout(idevice_t device, asr_client_t* asr) {
	int i = 0;
	int attempts = 10;
	idevice_connection_t connection = NULL;
	idevice_error_t device_error = IDEVICE_E_SUCCESS;

	*asr = NULL;

	if (device == NULL) {
		return -1;
	}

	debug("Connecting to ASR\n");
	for (i = 1; i <= attempts; i++) {
		device_error = idevice_connect(device, ASR_PORT, &connection);
		if (device_error == IDEVICE_E_SUCCESS) {
			break;
		}

		if (i >= attempts) {
			error("ERROR: Unable to connect to ASR client\n");
			return -1;
		}

		sleep(2);
		debug("Retrying connection...\n");
	}

	asr_client_t asr_loc = (asr_client_t)malloc(sizeof(struct asr_client));
	memset(asr_loc, '\0', sizeof(struct asr_client));
	asr_loc->connection = connection;

	/* receive Initiate command message */
	plist_t data = NULL;
	asr_loc->checksum_chunks = 0;
	if (asr_receive(asr_loc, &data) < 0) {
		error("ERROR: Unable to receive data from ASR\n");
		asr_free(asr_loc);
		plist_free(data);
		return -1;
	}
	plist_t node;
	node = plist_dict_get_item(data, "Command");
	if (node && (plist_get_node_type(node) == PLIST_STRING)) {
		char* strval = NULL;
		plist_get_string_val(node, &strval);
		if (strval && (strcmp(strval, "Initiate") != 0)) {
			error("ERROR: unexpected ASR plist received:\n");
			debug_plist(data);
			plist_free(data);
			asr_free(asr_loc);
			return -1;
		}
	}

	node = plist_dict_get_item(data, "Checksum Chunks");
	if (node && (plist_get_node_type(node) == PLIST_BOOLEAN)) {
		plist_get_bool_val(node, &(asr_loc->checksum_chunks));
	}
	plist_free(data);

	*asr = asr_loc;

	return 0;
}
Beispiel #11
0
/**
 * Receives changed entitites of the currently set data class from the device
 *
 * @param client The mobilesync client
 * @param entities A pointer to store the changed entity records as a PLIST_DICT
 * @param is_last_record A pointer to store a flag indicating if this submission is the last one
 * @param actions A pointer to additional flags the device is sending or NULL to ignore
 *
 * @retval MOBILESYNC_E_SUCCESS on success
 * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid
 * @retval MOBILESYNC_E_CANCELLED if the device explicitly cancelled the
 * session
 */
mobilesync_error_t mobilesync_receive_changes(mobilesync_client_t client, plist_t *entities, uint8_t *is_last_record, plist_t *actions)
{
	if (!client || !client->data_class) {
		return MOBILESYNC_E_INVALID_ARG;
	}

	plist_t msg = NULL;
	plist_t response_type_node = NULL;
	plist_t actions_node = NULL;
	char *response_type = NULL;
	uint8_t has_more_changes = 0;

	mobilesync_error_t err = mobilesync_receive(client, &msg);
	if (err != MOBILESYNC_E_SUCCESS) {
		goto out;
	}

	response_type_node = plist_array_get_item(msg, 0);
	if (!response_type_node) {
		err = MOBILESYNC_E_PLIST_ERROR;
		goto out;
	}

	plist_get_string_val(response_type_node, &response_type);
	if (!response_type) {
		err = MOBILESYNC_E_PLIST_ERROR;
		goto out;
	}

	if (!strcmp(response_type, "SDMessageCancelSession")) {
		char *reason = NULL;
		err = MOBILESYNC_E_CANCELLED;
		plist_get_string_val(plist_array_get_item(msg, 2), &reason);
		debug_info("Device cancelled: %s", reason);
		free(reason);
		goto out;
	}

	if (entities != NULL) {
		*entities = plist_copy(plist_array_get_item(msg, 2));
	}

	if (is_last_record != NULL) {
		plist_get_bool_val(plist_array_get_item(msg, 3), &has_more_changes);
		*is_last_record = (has_more_changes > 0 ? 0 : 1);
	}

	if (actions != NULL) {
		actions_node = plist_array_get_item(msg, 4);
		if (plist_get_node_type(actions) == PLIST_DICT)
			*actions = plist_copy(actions_node);
		else
			*actions = NULL;
	}

	out:
	if (response_type) {
		free(response_type);
		response_type = NULL;
	}
	if (msg) {
		plist_free(msg);
		msg = NULL;
	}
	return err;
}
int main(int argc, char *argv[])
{
	heartbeat_client_t heartbeat = NULL;
	idevice_t device = NULL;
	idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
	int i;
	const char* udid = NULL;

	signal(SIGINT, clean_exit);
	signal(SIGTERM, clean_exit);
#ifndef WIN32
	signal(SIGQUIT, clean_exit);
	signal(SIGPIPE, SIG_IGN);
#endif
	/* parse cmdline args */
	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
			idevice_set_debug_level(1);
			continue;
		}
		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) != 40)) {
				print_usage(argc, argv);
				return 0;
			}
			udid = argv[i];
			continue;
		}
		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
			print_usage(argc, argv);
			return 0;
		}
		else {
			print_usage(argc, argv);
			return 0;
		}
	}

	ret = idevice_new(&device, udid);
	if (ret != IDEVICE_E_SUCCESS) {
		if (udid) {
			printf("No device found with udid %s, is it plugged in?\n", udid);
		} else {
			printf("No device found, is it plugged in?\n");
		}
		return -1;
	}

	/* start heartbeat service on device */
	heartbeat_client_start_service(device, &heartbeat, "ideviceheartbeat");
	if (heartbeat) {
		printf("< heartbeat started, listening...\n");
	} else {
		printf("Failed to start heartbeat service\n");
		idevice_free(device);
		return -1;
	}

	/* main loop */
	uint8_t b = 0;
	uint64_t interval = 10000;
	plist_t message = NULL;
	plist_t node = NULL;
	do {
		/* await a "ping" message from the device every interval seconds */
		heartbeat_receive_with_timeout(heartbeat, &message, (uint32_t)interval);
		if (message) {
			/* report device beat settings */
			node = plist_dict_get_item(message, "SupportsSleepyTime");
			if (node && plist_get_node_type(node) == PLIST_BOOLEAN) {
				plist_get_bool_val(node, &b);
			}
			node = plist_dict_get_item(message, "Interval");
			if (node && plist_get_node_type(node) == PLIST_UINT) {
				plist_get_uint_val(node, &interval);
			}

			printf("> marco: supports_sleepy_time %d, interval %llu\n", b, interval);

			plist_free(message);
			message = NULL;

			/* answer with a "pong" message */
			message = plist_new_dict();
			plist_dict_insert_item(message, "Command", plist_new_string("Polo"));
			heartbeat_send(heartbeat, message);

			printf("< polo\n");

			if (message) {
				plist_free(message);
				message = NULL;
			}
		}
	} while(!quit_flag);

	heartbeat_client_free(heartbeat);

	idevice_free(device);

	return 0;
}
Beispiel #13
0
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;
}
Beispiel #14
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;
}