Ejemplo n.º 1
0
int tss_populate_basebandvals(plist_t tssreq, plist_t tssparameters, int64_t BbGoldCertId){
    plist_t parameters = plist_new_dict();
    char bbnonce[noncelen+1];
    char bbsnum[5];
    int64_t BbChipID = 0;
    
    getRandNum(bbnonce, noncelen, 256);
    getRandNum(bbsnum, 4, 256);
    
    int n=0; for (int i=1; i<7; i++) BbChipID += (arc4random() % 10) * pow(10, ++n);
    
    
    plist_dict_set_item(parameters, "BbNonce", plist_new_data(bbnonce, noncelen));
    plist_dict_set_item(parameters, "BbChipID", plist_new_uint(BbChipID));
    plist_dict_set_item(parameters, "BbGoldCertId", plist_new_uint(BbGoldCertId));
    plist_dict_set_item(parameters, "BbSNUM", plist_new_data(bbsnum, 4));
    
    /* BasebandFirmware */
    plist_t BasebandFirmware = plist_access_path(tssparameters, 2, "Manifest", "BasebandFirmware");
    if (!BasebandFirmware || plist_get_node_type(BasebandFirmware) != PLIST_DICT) {
        error("ERROR: Unable to get BasebandFirmware node\n");
        return -1;
    }
    plist_t bbfwdict = plist_copy(BasebandFirmware);
    BasebandFirmware = NULL;
    if (plist_dict_get_item(bbfwdict, "Info")) {
        plist_dict_remove_item(bbfwdict, "Info");
    }
    plist_dict_set_item(tssreq, "BasebandFirmware", bbfwdict);
    
    tss_request_add_baseband_tags(tssreq, parameters, NULL);
    return 0;
}
Ejemplo n.º 2
0
static plist_t create_device_attached_plist(struct device_info *dev)
{
    plist_t dict = plist_new_dict();
    plist_dict_set_item(dict, "MessageType", plist_new_string("Attached"));
    plist_dict_set_item(dict, "DeviceID", plist_new_uint(dev->id));
    plist_t props = plist_new_dict();
    plist_dict_set_item(props, "ConnectionSpeed", plist_new_uint(dev->speed));
    plist_dict_set_item(props, "ConnectionType", plist_new_string("USB"));
    plist_dict_set_item(props, "DeviceID", plist_new_uint(dev->id));
    plist_dict_set_item(props, "LocationID", plist_new_uint(dev->location));
    plist_dict_set_item(props, "ProductID", plist_new_uint(dev->pid));
    plist_dict_set_item(props, "SerialNumber", plist_new_string(dev->serial));
    plist_dict_set_item(dict, "Properties", props);
    return dict;
}
Ejemplo n.º 3
0
static int send_result(struct mux_client *client, uint32_t tag, uint32_t result)
{
	int res = -1;
	if (client->proto_version == 1) {
		/* XML plist packet */
		plist_t dict = plist_new_dict();
		plist_dict_insert_item(dict, "MessageType", plist_new_string("Result"));
		plist_dict_insert_item(dict, "Number", plist_new_uint(result));
		res = send_plist_pkt(client, tag, dict);
		plist_free(dict);
	} else {
		/* binary packet */
		res = send_pkt(client, tag, MESSAGE_RESULT, &result, sizeof(uint32_t));
	}
	return res;
}
Ejemplo n.º 4
0
static int notify_device_remove(struct mux_client *client, uint32_t device_id)
{
	int res = -1;
	if (client->proto_version == 1) {
		/* XML plist packet */
		plist_t dict = plist_new_dict();
		plist_dict_insert_item(dict, "MessageType", plist_new_string("Detached"));
		plist_dict_insert_item(dict, "DeviceID", plist_new_uint(device_id));
		res = send_plist_pkt(client, 0, dict);
		plist_free(dict);
	} else {
		/* binary packet */
		res = send_pkt(client, 0, MESSAGE_DEVICE_REMOVE, &device_id, sizeof(uint32_t));
	}
	return res;
}
Ejemplo n.º 5
0
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;
    }
}
Ejemplo n.º 6
0
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;
}
Ejemplo n.º 7
0
/**
 * Requests to start a restore and retrieve it's port on success.
 *
 * @param client The restored client
 * @param options PLIST_DICT with options for the restore process or NULL
 * @param version the restore protocol version, see restored_query_type()
 *
 * @return RESTORE_E_SUCCESS on success, NP_E_INVALID_ARG if a parameter
 *  is NULL, RESTORE_E_START_RESTORE_FAILED if the request fails
 */
restored_error_t restored_start_restore(restored_client_t client, plist_t options, uint64_t version)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	plist_t dict = NULL;
	restored_error_t ret = RESTORE_E_UNKNOWN_ERROR;

	dict = plist_new_dict();
	plist_dict_add_label(dict, client->label);
	plist_dict_insert_item(dict,"Request", plist_new_string("StartRestore"));
	if (options) {
		plist_dict_insert_item(dict, "RestoreOptions", plist_copy(options));
	}
	plist_dict_insert_item(dict,"RestoreProtocolVersion", plist_new_uint(version));

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

	return ret;
}
/**
 * Sends a DLMessageStatusResponse to the device.
 * 
 * @param client The MobileBackup client to use.
 * @param status_code The status code to send.
 * @param status1 A status message to send. Can be NULL if not required.
 * @param status2 An additional status plist to attach to the response.
 *     Can be NULL if not required.
 *
 * @return MOBILEBACKUP2_E_SUCCESS on success, MOBILEBACKUP2_E_INVALID_ARG
 *     if client is invalid, or another MOBILEBACKUP2_E_* otherwise.
 */
mobilebackup2_error_t mobilebackup2_send_status_response(mobilebackup2_client_t client, int status_code, const char *status1, plist_t status2)
{
	if (!client || !client->parent)
		return MOBILEBACKUP2_E_INVALID_ARG;

	plist_t array = plist_new_array();
	plist_array_append_item(array, plist_new_string("DLMessageStatusResponse"));
	plist_array_append_item(array, plist_new_uint(status_code));
	if (status1) {
		plist_array_append_item(array, plist_new_string(status1));
	} else {
		plist_array_append_item(array, plist_new_string("___EmptyParameterString___"));
	}
	if (status2) {
		plist_array_append_item(array, plist_copy(status2));
	} else {
		plist_array_append_item(array, plist_new_string("___EmptyParameterString___"));
	}

	mobilebackup2_error_t err = mobilebackup2_error(device_link_service_send(client->parent, array));
	plist_free(array);

	return err;
}
Ejemplo n.º 9
0
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;
}
Ejemplo n.º 10
0
/**
 * Creates a new restored client for the device.
 *
 * @param device The device to create a restored client for
 * @param client The pointer to the location of the new restored_client
 * @param label The label to use for communication. Usually the program name.
 *
 * @return RESTORE_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL
 */
restored_error_t restored_client_new(idevice_t device, restored_client_t *client, const char *label)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	restored_error_t ret = RESTORE_E_SUCCESS;

	static struct lockdownd_service_descriptor service = {
		.port = 0xf27e,
		.ssl_enabled = 0
	};

	property_list_service_client_t plistclient = NULL;
	if (property_list_service_client_new(device, (lockdownd_service_descriptor_t)&service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		debug_info("could not connect to restored (device %s)", device->udid);
		return RESTORE_E_MUX_ERROR;
	}

	restored_client_t client_loc = (restored_client_t) malloc(sizeof(struct restored_client_private));
	client_loc->parent = plistclient;
	client_loc->udid = NULL;
	client_loc->label = NULL;
	client_loc->info = NULL;
	if (label != NULL)
		client_loc->label = strdup(label);

	ret = idevice_get_udid(device, &client_loc->udid);
	if (RESTORE_E_SUCCESS != ret) {
		debug_info("failed to get device udid.");
	}
	debug_info("device udid: %s", client_loc->udid);

	if (RESTORE_E_SUCCESS == ret) {
		*client = client_loc;
	} else {
		restored_client_free(client_loc);
	}

	return ret;
}

/**
 * Sends the Goodbye request to restored signaling the end of communication.
 *
 * @param client The restore client
 *
 * @return RESTORE_E_SUCCESS on success, NP_E_INVALID_ARG when client is NULL,
 *  RESTORE_E_PLIST_ERROR if the device did not acknowledge the request
 */
restored_error_t restored_goodbye(restored_client_t client)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	restored_error_t ret = RESTORE_E_UNKNOWN_ERROR;

	plist_t dict = plist_new_dict();
	plist_dict_add_label(dict, client->label);
	plist_dict_insert_item(dict,"Request", plist_new_string("Goodbye"));

	debug_info("called");

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

	ret = restored_receive(client, &dict);
	if (!dict) {
		debug_info("did not get goodbye response back");
		return RESTORE_E_PLIST_ERROR;
	}

	if (restored_check_result(dict) == RESULT_SUCCESS) {
		debug_info("success");
		ret = RESTORE_E_SUCCESS;
	}
	plist_free(dict);
	dict = NULL;
	return ret;
}

/**
 * Requests to start a restore and retrieve it's port on success.
 *
 * @param client The restored client
 * @param options PLIST_DICT with options for the restore process or NULL
 * @param version the restore protocol version, see restored_query_type()
 *
 * @return RESTORE_E_SUCCESS on success, NP_E_INVALID_ARG if a parameter
 *  is NULL, RESTORE_E_START_RESTORE_FAILED if the request fails
 */
restored_error_t restored_start_restore(restored_client_t client, plist_t options, uint64_t version)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	plist_t dict = NULL;
	restored_error_t ret = RESTORE_E_UNKNOWN_ERROR;

	dict = plist_new_dict();
	plist_dict_add_label(dict, client->label);
	plist_dict_insert_item(dict,"Request", plist_new_string("StartRestore"));
	if (options) {
		plist_dict_insert_item(dict, "RestoreOptions", plist_copy(options));
	}
	plist_dict_insert_item(dict,"RestoreProtocolVersion", plist_new_uint(version));

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

	return ret;
}

/**
 * Requests device to reboot.
 *
 * @param client The restored client
 *
 * @return RESTORE_E_SUCCESS on success, NP_E_INVALID_ARG if a parameter
 *  is NULL
 */
restored_error_t restored_reboot(restored_client_t client)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	plist_t dict = NULL;
	restored_error_t ret = RESTORE_E_UNKNOWN_ERROR;

	dict = plist_new_dict();
	plist_dict_add_label(dict, client->label);
	plist_dict_insert_item(dict,"Request", plist_new_string("Reboot"));

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

	if (RESTORE_E_SUCCESS != ret)
		return ret;

	ret = restored_receive(client, &dict);
	if (RESTORE_E_SUCCESS != ret)
		return ret;

	if (!dict)
		return RESTORE_E_PLIST_ERROR;

	plist_free(dict);
	dict = NULL;
	return ret;
}
Ejemplo n.º 11
0
LIBIMOBILEDEVICE_API restored_error_t restored_client_new(idevice_t device, restored_client_t *client, const char *label)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	restored_error_t ret = RESTORE_E_SUCCESS;
	idevice_error_t idev_ret;

	static struct lockdownd_service_descriptor service = {
		.port = 0xf27e,
		.ssl_enabled = 0
	};

	property_list_service_client_t plistclient = NULL;
	if (property_list_service_client_new(device, (lockdownd_service_descriptor_t)&service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		debug_info("could not connect to restored (device %s)", device->udid);
		return RESTORE_E_MUX_ERROR;
	}

	restored_client_t client_loc = (restored_client_t) malloc(sizeof(struct restored_client_private));
	client_loc->parent = plistclient;
	client_loc->udid = NULL;
	client_loc->label = NULL;
	client_loc->info = NULL;
	if (label != NULL)
		client_loc->label = strdup(label);

	idev_ret = idevice_get_udid(device, &client_loc->udid);
	if (IDEVICE_E_SUCCESS != idev_ret) {
		debug_info("failed to get device udid.");
		ret = RESTORE_E_DEVICE_ERROR;
	}
	debug_info("device udid: %s", client_loc->udid);

	if (RESTORE_E_SUCCESS == ret) {
		*client = client_loc;
	} else {
		restored_client_free(client_loc);
	}

	return ret;
}

LIBIMOBILEDEVICE_API restored_error_t restored_goodbye(restored_client_t client)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	restored_error_t ret = RESTORE_E_UNKNOWN_ERROR;

	plist_t dict = plist_new_dict();
	plist_dict_add_label(dict, client->label);
	plist_dict_set_item(dict,"Request", plist_new_string("Goodbye"));

	debug_info("called");

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

	ret = restored_receive(client, &dict);
	if (!dict) {
		debug_info("did not get goodbye response back");
		return RESTORE_E_PLIST_ERROR;
	}

	if (restored_check_result(dict) == RESULT_SUCCESS) {
		debug_info("success");
		ret = RESTORE_E_SUCCESS;
	}
	plist_free(dict);
	dict = NULL;
	return ret;
}

LIBIMOBILEDEVICE_API restored_error_t restored_start_restore(restored_client_t client, plist_t options, uint64_t version)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	plist_t dict = NULL;
	restored_error_t ret = RESTORE_E_UNKNOWN_ERROR;

	dict = plist_new_dict();
	plist_dict_add_label(dict, client->label);
	plist_dict_set_item(dict,"Request", plist_new_string("StartRestore"));
	if (options) {
		plist_dict_set_item(dict, "RestoreOptions", plist_copy(options));
	}
	plist_dict_set_item(dict,"RestoreProtocolVersion", plist_new_uint(version));

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

	return ret;
}

LIBIMOBILEDEVICE_API restored_error_t restored_reboot(restored_client_t client)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	plist_t dict = NULL;
	restored_error_t ret = RESTORE_E_UNKNOWN_ERROR;

	dict = plist_new_dict();
	plist_dict_add_label(dict, client->label);
	plist_dict_set_item(dict,"Request", plist_new_string("Reboot"));

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

	if (RESTORE_E_SUCCESS != ret)
		return ret;

	ret = restored_receive(client, &dict);
	if (RESTORE_E_SUCCESS != ret)
		return ret;

	if (!dict)
		return RESTORE_E_PLIST_ERROR;

	plist_free(dict);
	dict = NULL;
	return ret;
}
Ejemplo n.º 12
0
/**
 * Performs the DLMessageVersionExchange with the connected device.
 * This should be the first operation to be executed by an implemented
 * device link service client.
 *
 * @param client The device_link_service client to use.
 * @param version_major The major version number to check.
 * @param version_minor The minor version number to check.
 *
 * @return DEVICE_LINK_SERVICE_E_SUCCESS on success,
 *     DEVICE_LINK_SERVICE_E_INVALID_ARG when client is NULL,
 *     DEVICE_LINK_SERVICE_E_MUX_ERROR when a communication error occurs,
 *     DEVICE_LINK_SERVICE_E_PLIST_ERROR when the received plist has not the
 *     expected contents, DEVICE_LINK_SERVICE_E_BAD_VERSION when the version
 *     given by the device is larger than the given version,
 *     or DEVICE_LINK_SERVICE_E_UNKNOWN_ERROR otherwise.
 */
device_link_service_error_t device_link_service_version_exchange(device_link_service_client_t client, uint64_t version_major, uint64_t version_minor)
{
    if (!client)
        return DEVICE_LINK_SERVICE_E_INVALID_ARG;

    device_link_service_error_t err = DEVICE_LINK_SERVICE_E_UNKNOWN_ERROR;

    /* perform version exchange */
    plist_t array = NULL;
    char *msg = NULL;

    /* receive DLMessageVersionExchange from device */
    if (property_list_service_receive_plist(client->parent, &array) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
        debug_info("Did not receive initial message from device!");
        err = DEVICE_LINK_SERVICE_E_MUX_ERROR;
        goto leave;
    }
    msg = device_link_service_get_message(array);
    if (!msg || strcmp(msg, "DLMessageVersionExchange")) {
        debug_info("Did not receive DLMessageVersionExchange from device!");
        err = DEVICE_LINK_SERVICE_E_PLIST_ERROR;
        goto leave;
    }
    free(msg);
    msg = NULL;

    /* get major and minor version number */
    if (plist_array_get_size(array) < 3) {
        debug_info("DLMessageVersionExchange has unexpected format!");
        err = DEVICE_LINK_SERVICE_E_PLIST_ERROR;
        goto leave;
    }
    plist_t maj = plist_array_get_item(array, 1);
    plist_t min = plist_array_get_item(array, 2);
    uint64_t vmajor = 0;
    uint64_t vminor = 0;
    if (maj) {
        plist_get_uint_val(maj, &vmajor);
    }
    if (min) {
        plist_get_uint_val(min, &vminor);
    }
    if (vmajor > version_major) {
        debug_info("Version mismatch: device=(%lld,%lld) > expected=(%lld,%lld)", vmajor, vminor, version_major, version_minor);
        err = DEVICE_LINK_SERVICE_E_BAD_VERSION;
        goto leave;
    } else if ((vmajor == version_major) && (vminor > version_minor)) {
        debug_info("WARNING: Version mismatch: device=(%lld,%lld) > expected=(%lld,%lld)", vmajor, vminor, version_major, version_minor);
        err = DEVICE_LINK_SERVICE_E_BAD_VERSION;
        goto leave;
    }
    plist_free(array);

    /* version is ok, send reply */
    array = plist_new_array();
    plist_array_append_item(array, plist_new_string("DLMessageVersionExchange"));
    plist_array_append_item(array, plist_new_string("DLVersionsOk"));
    plist_array_append_item(array, plist_new_uint(version_major));
    if (property_list_service_send_binary_plist(client->parent, array) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
        debug_info("Error when sending DLVersionsOk");
        err = DEVICE_LINK_SERVICE_E_MUX_ERROR;
        goto leave;
    }
    plist_free(array);

    /* receive DeviceReady message */
    array = NULL;
    if (property_list_service_receive_plist(client->parent, &array) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
        debug_info("Error when receiving DLMessageDeviceReady!");
        err = DEVICE_LINK_SERVICE_E_MUX_ERROR;
        goto leave;
    }
    msg = device_link_service_get_message(array);
    if (!msg || strcmp(msg, "DLMessageDeviceReady")) {
        debug_info("Did not get DLMessageDeviceReady!");
        err = DEVICE_LINK_SERVICE_E_PLIST_ERROR;
        goto leave;
    }
    err = DEVICE_LINK_SERVICE_E_SUCCESS;

leave:
    if (msg) {
        free(msg);
    }
    if (array) {
        plist_free(array);
    }
    return err;
}
Ejemplo n.º 13
0
int tss_parameters_add_from_manifest(plist_t parameters, plist_t build_identity)
{
	plist_t node = NULL;
	char* string = NULL;

	/* UniqueBuildID */
	node = plist_dict_get_item(build_identity, "UniqueBuildID");
	if (!node || plist_get_node_type(node) != PLIST_DATA) {
		error("ERROR: Unable to find UniqueBuildID node\n");
		return -1;
	}
	plist_dict_set_item(parameters, "UniqueBuildID", plist_copy(node));
	node = NULL;

	/* ApChipID */
	int chip_id = 0;
	node = plist_dict_get_item(build_identity, "ApChipID");
	if (!node || plist_get_node_type(node) != PLIST_STRING) {
		error("ERROR: Unable to find ApChipID node\n");
		return -1;
	}
	plist_get_string_val(node, &string);
	sscanf(string, "%x", &chip_id);
	plist_dict_set_item(parameters, "ApChipID", plist_new_uint(chip_id));
	free(string);
	string = NULL;
	node = NULL;

	/* ApBoardID */
	int board_id = 0;
	node = plist_dict_get_item(build_identity, "ApBoardID");
	if (!node || plist_get_node_type(node) != PLIST_STRING) {
		error("ERROR: Unable to find ApBoardID node\n");
		return -1;
	}
	plist_get_string_val(node, &string);
	sscanf(string, "%x", &board_id);
	plist_dict_set_item(parameters, "ApBoardID", plist_new_uint(board_id));
	free(string);
	string = NULL;
	node = NULL;

	/* ApSecurityDomain */
	int security_domain = 0;
	node = plist_dict_get_item(build_identity, "ApSecurityDomain");
	if (!node || plist_get_node_type(node) != PLIST_STRING) {
		error("ERROR: Unable to find ApSecurityDomain node\n");
		return -1;
	}
	plist_get_string_val(node, &string);
	sscanf(string, "%x", &security_domain);
	plist_dict_set_item(parameters, "ApSecurityDomain", plist_new_uint(security_domain));
	free(string);
	string = NULL;
	node = NULL;

	/* BbChipID */
	int bb_chip_id = 0;
	char* bb_chip_id_string = NULL;
	node = plist_dict_get_item(build_identity, "BbChipID");
	if (node && plist_get_node_type(node) == PLIST_STRING) {
		plist_get_string_val(node, &bb_chip_id_string);
		sscanf(bb_chip_id_string, "%x", &bb_chip_id);
		plist_dict_set_item(parameters, "BbChipID", plist_new_uint(bb_chip_id));
	} else {
		error("WARNING: Unable to find BbChipID node\n");
	}
	node = NULL;

	/* BbProvisioningManifestKeyHash */
	node = plist_dict_get_item(build_identity, "BbProvisioningManifestKeyHash");
	if (node && plist_get_node_type(node) == PLIST_DATA) {
		plist_dict_set_item(parameters, "BbProvisioningManifestKeyHash", plist_copy(node));
	} else {
		debug("NOTE: Unable to find BbProvisioningManifestKeyHash node\n");
	}
	node = NULL;

	/* BbActivationManifestKeyHash - Used by Qualcomm MDM6610 */
	node = plist_dict_get_item(build_identity, "BbActivationManifestKeyHash");
	if (node && plist_get_node_type(node) == PLIST_DATA) {
		plist_dict_set_item(parameters, "BbActivationManifestKeyHash", plist_copy(node));
	} else {
		debug("NOTE: Unable to find BbActivationManifestKeyHash node\n");
	}
	node = NULL;

	node = plist_dict_get_item(build_identity, "BbCalibrationManifestKeyHash");
	if (node && plist_get_node_type(node) == PLIST_DATA) {
		plist_dict_set_item(parameters, "BbCalibrationManifestKeyHash", plist_copy(node));
	} else {
		debug("NOTE: Unable to find BbCalibrationManifestKeyHash node\n");
	}
	node = NULL;

	/* BbFactoryActivationManifestKeyHash */
	node = plist_dict_get_item(build_identity, "BbFactoryActivationManifestKeyHash");
	if (node && plist_get_node_type(node) == PLIST_DATA) {
		plist_dict_set_item(parameters, "BbFactoryActivationManifestKeyHash", plist_copy(node));
	} else {
		debug("NOTE: Unable to find BbFactoryActivationManifestKeyHash node\n");
	}
	node = NULL;

	/* BbFDRSecurityKeyHash */
	node = plist_dict_get_item(build_identity, "BbFDRSecurityKeyHash");
	if (node && plist_get_node_type(node) == PLIST_DATA) {
		plist_dict_set_item(parameters, "BbFDRSecurityKeyHash", plist_copy(node));
	} else {
		debug("NOTE: Unable to find BbFDRSecurityKeyHash node\n");
	}
	node = NULL;

	/* BbSkeyId - Used by XMM 6180/GSM */
	node = plist_dict_get_item(build_identity, "BbSkeyId");
	if (node && plist_get_node_type(node) == PLIST_DATA) {
		plist_dict_set_item(parameters, "BbSkeyId", plist_copy(node));
	} else {
		error("WARNING: Unable to find BbSkeyId node\n");
	}
	node = NULL;

	/* add build identity manifest dictionary */
	node = plist_dict_get_item(build_identity, "Manifest");
	if (!node || plist_get_node_type(node) != PLIST_DICT) {
		error("ERROR: Unable to find Manifest node\n");
		return -1;
	}
	plist_dict_set_item(parameters, "Manifest", plist_copy(node));

	return 0;
}
Ejemplo n.º 14
0
static int rproxy_connect_control_service(idevice_t device, idevice_connection_t * control_connection, uint16_t * connection_port)
{
    plist_t dict = NULL;

    /* Connect to the proxy service */
    idevice_connection_t new_connection = NULL;
    if (IDEVICE_E_SUCCESS != rproxy_create_connection(device, REVERSE_PROXY_MUX_PORT, CONTROL_CONNECTION_START_STRING, &new_connection)) {
        error("ERROR: Failed to connect to the proxy service\n");
        goto cleanup;
    }

    /* Send the BeginCtrl command */
    dict = plist_new_dict();
    plist_dict_set_item(dict, "Command", plist_new_string("BeginCtrl"));
    plist_dict_set_item(dict, "CtrlProtoVersion", plist_new_uint(CONTROL_PROTOCOL_VERSION));

    if (0 != rproxy_send_dict(new_connection, dict)) {
        error("ERROR: Failed send BeginCtrl command to the service\n");
        goto cleanup;
    }
    plist_free(dict);
    dict = NULL;

    /* Get the BeginCtrl's response */
    if (0 != rproxy_recv_dict(new_connection, &dict, RPROXY_RECV_TIMEOUT)) {
        error("ERROR: Failed receive a response for BeginCtrl\n");
        goto cleanup;
    }

    /* Parse the recieved protocol version */
    uint64_t device_ctrl_proto_ver = 0;
    if (get_plist_uint_val(dict, "CtrlProtoVersion", &device_ctrl_proto_ver) < 0) {
        error("ERROR: Device response to BeginCtrl doesn't contain a protocol version\n");
        goto cleanup;
    }
    if (CONTROL_PROTOCOL_VERSION != device_ctrl_proto_ver) {
        error("ERROR: Proxy protocol version mismatch: expected "PRIu64", device reported "PRIu64"\n",
              CONTROL_PROTOCOL_VERSION,
              device_ctrl_proto_ver);
        goto cleanup;
    }

    /* Parse the connection port from the response */
    uint64_t received_conn_port = 0;
    if (get_plist_uint_val(dict, "ConnPort", &received_conn_port) < 0) {
        error("ERROR: Device response to BeginCtrl is missing a connection port\n");
        goto cleanup;
    }
    debug("Reverse proxy connection port: %us", (uint16_t)received_conn_port);

    plist_free(dict);
    dict = NULL;

    *control_connection = new_connection;
    *connection_port = (uint16_t)received_conn_port;
    return 0;

cleanup:
    if (dict) {
        plist_free(dict);
    }
    if (new_connection) {
        idevice_disconnect(new_connection);
    }

    return -1;
}
Ejemplo n.º 15
0
/**
 * Requests starting synchronization of a data class with the device
 *
 * @param client The mobilesync client
 * @param data_class The data class identifier to sync
 * @param anchors The anchors required to exchange with the device. The anchors
 *   allow the device to tell if the synchronization information on the computer
 *   and device are consistent to determine what sync type is required.
 * @param computer_data_class_version The version of the data class storage on the computer
 * @param sync_type A pointer to store the sync type reported by the device_anchor
 * @param device_data_class_version The version of the data class storage on the device
 * @param error_description A pointer to store an error message if reported by the device
 *
 * @retval MOBILESYNC_E_SUCCESS on success
 * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid
 * @retval MOBILESYNC_E_PLIST_ERROR if the received plist is not of valid form
 * @retval MOBILESYNC_E_SYNC_REFUSED if the device refused to sync
 * @retval MOBILESYNC_E_CANCELLED if the device explicitly cancelled the
 * sync request
 */
mobilesync_error_t mobilesync_start(mobilesync_client_t client, const char *data_class, mobilesync_anchors_t anchors, uint64_t computer_data_class_version, mobilesync_sync_type_t *sync_type, uint64_t *device_data_class_version, char** error_description)
{
	if (!client || client->data_class || !data_class ||
		!anchors || !anchors->computer_anchor) {
		return MOBILESYNC_E_INVALID_ARG;
	}

	mobilesync_error_t err = MOBILESYNC_E_UNKNOWN_ERROR;
	char *response_type = NULL;
	char *sync_type_str = NULL;
	plist_t msg = NULL;
	plist_t response_type_node = NULL;

	*error_description = NULL;

	msg = plist_new_array();
	plist_array_append_item(msg, plist_new_string("SDMessageSyncDataClassWithDevice"));
	plist_array_append_item(msg, plist_new_string(data_class));
	if (anchors->device_anchor) {
		plist_array_append_item(msg, plist_new_string(anchors->device_anchor));
	} else {
		plist_array_append_item(msg, plist_new_string("---"));
	}
	plist_array_append_item(msg, plist_new_string(anchors->computer_anchor));
	plist_array_append_item(msg, plist_new_uint(computer_data_class_version));
	plist_array_append_item(msg, plist_new_string(EMPTY_PARAMETER_STRING));

	err = mobilesync_send(client, msg);

	if (err != MOBILESYNC_E_SUCCESS) {
		goto out;
	}

	plist_free(msg);
	msg = NULL;

	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;
	}

	// did the device refuse to sync with the computer?
	if (!strcmp(response_type, "SDMessageRefuseToSyncDataClassWithComputer")) {
		err = MOBILESYNC_E_SYNC_REFUSED;
		plist_get_string_val(plist_array_get_item(msg, 2), error_description);
		debug_info("Device refused sync: %s", error_description);
		goto out;
	}

	// did the device cancel the session?
	if (!strcmp(response_type, "SDMessageCancelSession")) {
		err = MOBILESYNC_E_CANCELLED;
		plist_get_string_val(plist_array_get_item(msg, 2), error_description);
		debug_info("Device cancelled: %s", error_description);
		goto out;
	}

	if (sync_type != NULL) {
		plist_t sync_type_node = plist_array_get_item(msg, 4);
		if (!sync_type_node) {
			err = MOBILESYNC_E_PLIST_ERROR;
			goto out;
		}

		plist_get_string_val(sync_type_node, &sync_type_str);
		if (!sync_type_str) {
			err = MOBILESYNC_E_PLIST_ERROR;
			goto out;
		}

		if (!strcmp(sync_type_str, "SDSyncTypeFast")) {
			*sync_type = MOBILESYNC_SYNC_TYPE_FAST;
		} else if (!strcmp(sync_type_str, "SDSyncTypeSlow")) {
			*sync_type = MOBILESYNC_SYNC_TYPE_SLOW;
		} else if (!strcmp(sync_type_str, "SDSyncTypeReset")) {
			*sync_type = MOBILESYNC_SYNC_TYPE_RESET;
		} else {
			err = MOBILESYNC_E_PLIST_ERROR;
			goto out;
		}
	}

	if (device_data_class_version != NULL) {
		plist_t device_data_class_version_node = plist_array_get_item(msg, 5);
		if (!device_data_class_version_node) {
			err = MOBILESYNC_E_PLIST_ERROR;
			goto out;
		}

		plist_get_uint_val(device_data_class_version_node, device_data_class_version);
	}

	err = MOBILESYNC_E_SUCCESS;

	out:
	if (sync_type_str) {
		free(sync_type_str);
		sync_type_str = NULL;
	}
	if (response_type) {
		free(response_type);
		response_type = NULL;
	}
	if (msg) {
		plist_free(msg);
		msg = NULL;
	}

	client->data_class = strdup(data_class);
	client->direction = MOBILESYNC_SYNC_DIR_DEVICE_TO_COMPUTER;
	return err;
}
Ejemplo n.º 16
0
int asr_perform_validation(asr_client_t asr, const char* filesystem) {
	FILE* file = NULL;
	uint64_t length = 0;
	char* command = NULL;
	plist_t node = NULL;
	plist_t packet = NULL;
	plist_t packet_info = NULL;
	plist_t payload_info = NULL;
	int attempts = 0;

	file = fopen(filesystem, "rb");
	if (file == NULL) {
		return -1;
	}

	fseek(file, 0, SEEK_END);
	length = ftell(file);
	fseek(file, 0, SEEK_SET);

	payload_info = plist_new_dict();
	plist_dict_set_item(payload_info, "Port", plist_new_uint(1));
	plist_dict_set_item(payload_info, "Size", plist_new_uint(length));

	packet_info = plist_new_dict();
	if (asr->checksum_chunks) {
		plist_dict_set_item(packet_info, "Checksum Chunk Size", plist_new_uint(ASR_CHECKSUM_CHUNK_SIZE));
	}
	plist_dict_set_item(packet_info, "FEC Slice Stride", plist_new_uint(ASR_FEC_SLICE_STRIDE));
	plist_dict_set_item(packet_info, "Packet Payload Size", plist_new_uint(ASR_PAYLOAD_PACKET_SIZE));
	plist_dict_set_item(packet_info, "Packets Per FEC", plist_new_uint(ASR_PACKETS_PER_FEC));
	plist_dict_set_item(packet_info, "Payload", payload_info);
	plist_dict_set_item(packet_info, "Stream ID", plist_new_uint(ASR_STREAM_ID));
	plist_dict_set_item(packet_info, "Version", plist_new_uint(ASR_VERSION));

	if (asr_send(asr, packet_info)) {
		error("ERROR: Unable to sent packet information to ASR\n");
		plist_free(packet_info);
		return -1;
	}
	plist_free(packet_info);

	while (1) {
		if (asr_receive(asr, &packet) < 0) {
			error("ERROR: Unable to receive validation packet\n");
			return -1;
		}

		if (packet == NULL) {
			if (attempts < 5) {
				info("Retrying to receive validation packet... %d\n", attempts);
				attempts++;
				sleep(1);
				continue;
			}
		}

		attempts = 0;

		node = plist_dict_get_item(packet, "Command");
		if (!node || plist_get_node_type(node) != PLIST_STRING) {
			error("ERROR: Unable to find command node in validation request\n");
			return -1;
		}
		plist_get_string_val(node, &command);

		if (!strcmp(command, "OOBData")) {
			asr_handle_oob_data_request(asr, packet, file);
			plist_free(packet);
		} else if(!strcmp(command, "Payload")) {
			plist_free(packet);
			break;

		} else {
			error("ERROR: Unknown command received from ASR\n");
			plist_free(packet);
			return -1;
		}
	}

	return 0;
}
Ejemplo n.º 17
0
int main(int argc, char *argv[])
{
	lockdownd_client_t client = NULL;
	idevice_t phone = NULL;
	idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
	int i;
	char udid[41];
	time_t setdate = 0;
	plist_t node = NULL;
	udid[0] = 0;
	uint64_t datetime = 0;
	time_t rawtime;
	struct tm * tmp;
	char const *format = NULL;
	char buffer[80];

	/* parse cmdline args */
	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
			idevice_set_debug_level(1);
			continue;
		}
		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) != 40)) {
				print_usage(argc, argv);
				return 0;
			}
			strcpy(udid, argv[i]);
			continue;
		}
		else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--set")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) <= 1)) {
				print_usage(argc, argv);
				return 0;
			}
			setdate = atoi(argv[i]);
			if (setdate == 0) {
				printf("ERROR: Invalid timestamp value.\n");
				print_usage(argc, argv);
				return 0;
			}
			continue;
		}
		else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--sync")) {
			i++;
			/* get current time */
			setdate = time(NULL);
			/* convert it to local time which sets timezone/daylight variables */
			tmp = localtime(&setdate);
			/* recalculate to make it UTC */
			setdate = mktime(tmp);
			continue;
		}
		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
			print_usage(argc, argv);
			return 0;
		}
		else {
			print_usage(argc, argv);
			return 0;
		}
	}

	/* determine a date format */
	if (!format) {
		format = DATE_FMT_LANGINFO ();
		if (!*format) {
			format = "%a %b %e %H:%M:%S %Z %Y";
		}
	}

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

	if (LOCKDOWN_E_SUCCESS != lockdownd_client_new_with_handshake(phone, &client, "idevicedate")) {
		idevice_free(phone);
		return -1;
	}

	/* get or set? */
	if (setdate == 0) {
		/* get time value from device */
		if(lockdownd_get_value(client, NULL, "TimeIntervalSince1970", &node) == LOCKDOWN_E_SUCCESS) {
			if (node) {
				plist_get_uint_val(node, &datetime);
				plist_free(node);
				node = NULL;

				/* date/time calculations */
				rawtime = (time_t)datetime;
				tmp = localtime(&rawtime);

				/* finally we format and print the current date */
				strftime(buffer, 80, format, tmp);
				puts(buffer);
			}
		}
	} else {
		datetime = setdate;

		if(lockdownd_set_value(client, NULL, "TimeIntervalSince1970", plist_new_uint(datetime)) == LOCKDOWN_E_SUCCESS) {
			tmp = localtime(&setdate);
			strftime(buffer, 80, format, tmp);
			puts(buffer);
		} else {
			printf("ERROR: Failed to set date on device.\n");
		}
	}

	lockdownd_client_free(client);
	idevice_free(phone);

	return 0;
}
Ejemplo n.º 18
0
int main(int argc, char *argv[])
{
	lockdownd_client_t client = NULL;
	lockdownd_error_t ldret = LOCKDOWN_E_UNKNOWN_ERROR;
	idevice_t device = NULL;
	idevice_error_t ret = IDEVICE_E_UNKNOWN_ERROR;
	int i;
	const char* udid = NULL;
	time_t setdate = 0;
	plist_t node = NULL;
	int node_type = -1;
	uint64_t datetime = 0;
	time_t rawtime;
	struct tm * tmp;
	char const *format = NULL;
	char buffer[80];
	int result = 0;

	/* parse cmdline args */
	for (i = 1; i < argc; i++) {
		if (!strcmp(argv[i], "-d") || !strcmp(argv[i], "--debug")) {
			idevice_set_debug_level(1);
			continue;
		}
		else if (!strcmp(argv[i], "-u") || !strcmp(argv[i], "--udid")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) != 40)) {
				print_usage(argc, argv);
				return 0;
			}
			udid = argv[i];
			continue;
		}
		else if (!strcmp(argv[i], "-s") || !strcmp(argv[i], "--set")) {
			i++;
			if (!argv[i] || (strlen(argv[i]) <= 1)) {
				print_usage(argc, argv);
				return 0;
			}
			setdate = atoi(argv[i]);
			if (setdate == 0) {
				printf("ERROR: Invalid timestamp value.\n");
				print_usage(argc, argv);
				return 0;
			}
			continue;
		}
		else if (!strcmp(argv[i], "-c") || !strcmp(argv[i], "--sync")) {
			i++;
			/* get current time */
			setdate = time(NULL);
			/* convert it to local time which sets timezone/daylight variables */
			tmp = localtime(&setdate);
			/* recalculate to make it UTC */
			setdate = mktime(tmp);
			continue;
		}
		else if (!strcmp(argv[i], "-h") || !strcmp(argv[i], "--help")) {
			print_usage(argc, argv);
			return 0;
		}
		else {
			print_usage(argc, argv);
			return 0;
		}
	}

	/* determine a date format */
	if (!format) {
		format = DATE_FMT_LANGINFO ();
		if (!*format) {
			format = "%a %b %e %H:%M:%S %Z %Y";
		}
	}

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

	if (LOCKDOWN_E_SUCCESS != (ldret = lockdownd_client_new_with_handshake(device, &client, "idevicedate"))) {
		fprintf(stderr, "ERROR: Could not connect to lockdownd, error code %d\n", ldret);
		result = -1;
		goto cleanup;
	}

	if(lockdownd_get_value(client, NULL, "TimeIntervalSince1970", &node) != LOCKDOWN_E_SUCCESS) {
		fprintf(stderr, "ERROR: Unable to retrieve 'TimeIntervalSince1970' node from device.\n");
		result = -1;
		goto cleanup;
	}

	if (node == NULL) {
		fprintf(stderr, "ERROR: Empty node for 'TimeIntervalSince1970' received.\n");
		result = -1;
		goto cleanup;
	}

	node_type = plist_get_node_type(node);

	/* get or set? */
	if (setdate == 0) {
		/* get time value from device */
		switch (node_type) {
			case PLIST_UINT:
				plist_get_uint_val(node, &datetime);
				break;
			case PLIST_REAL:
				{
					double rv = 0;
					plist_get_real_val(node, &rv);
					datetime = rv;
				}
				break;
			default:
				fprintf(stderr, "ERROR: Unexpected node type for 'TimeIntervalSince1970'\n");
				break;
		}
		plist_free(node);
		node = NULL;

		/* date/time calculations */
		rawtime = (time_t)datetime;
		tmp = localtime(&rawtime);

		/* finally we format and print the current date */
		strftime(buffer, 80, format, tmp);
		puts(buffer);
	} else {
		datetime = setdate;

		plist_free(node);
		node = NULL;

		switch (node_type) {
			case PLIST_UINT:
				node = plist_new_uint(datetime);
				break;
			case PLIST_REAL:
				node = plist_new_real((double)datetime);
				break;
			default:
				fprintf(stderr, "ERROR: Unexpected node type for 'TimeIntervalSince1970'\n");
				break;
		}

		if(lockdownd_set_value(client, NULL, "TimeIntervalSince1970", node) == LOCKDOWN_E_SUCCESS) {
			tmp = localtime(&setdate);
			strftime(buffer, 80, format, tmp);
			puts(buffer);
		} else {
			printf("ERROR: Failed to set date on device.\n");
		}
		node = NULL;
	}

cleanup:
	if (client)
		lockdownd_client_free(client);

	if (device)
		idevice_free(device);

	return result;
}
Ejemplo n.º 19
0
/**
 * Uploads an image to the device.
 *
 * @param client The connected mobile_image_mounter client.
 * @param image_type Type of image that is being uploaded.
 * @param image_size Total size of the image.
 * @param upload_cb Callback function that gets the data chunks for uploading
 *    the image.
 * @param userdata User defined data for the upload callback function.
 *
 * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on succes, or a
 *    MOBILE_IMAGE_MOUNTER_E_* error code otherwise.
 */
mobile_image_mounter_error_t mobile_image_mounter_upload_image(mobile_image_mounter_client_t client, const char *image_type, size_t image_size, mobile_image_mounter_upload_cb_t upload_cb, void* userdata)
{
	if (!client || !image_type || (image_size == 0) || !upload_cb) {
		return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG;
	}
	mobile_image_mounter_lock(client);
	plist_t result = NULL;

	plist_t dict = plist_new_dict();
	plist_dict_set_item(dict, "Command", plist_new_string("ReceiveBytes"));
	plist_dict_set_item(dict, "ImageSize", plist_new_uint(image_size));
	plist_dict_set_item(dict, "ImageType", plist_new_string(image_type));

	mobile_image_mounter_error_t res = mobile_image_mounter_error(property_list_service_send_xml_plist(client->parent, dict));
	plist_free(dict);

	if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
		debug_info("Error sending XML plist to device!");
		goto leave_unlock;
	}

	res = mobile_image_mounter_error(property_list_service_receive_plist(client->parent, &result));
	if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
		debug_info("Error receiving response from device!");
		goto leave_unlock;
	}
	res = MOBILE_IMAGE_MOUNTER_E_COMMAND_FAILED;

	char* strval = NULL;
	plist_t node = plist_dict_get_item(result, "Status");
	if (node && plist_get_node_type(node) == PLIST_STRING) {
		plist_get_string_val(node, &strval);
	}
	if (!strval) {
		debug_info("Error: Unexpected response received!");
		goto leave_unlock;
	}
	if (strcmp(strval, "ReceiveBytesAck") != 0) {
		debug_info("Error: didn't get ReceiveBytesAck but %s", strval);
		free(strval);
		goto leave_unlock;
	}
	free(strval);

	size_t tx = 0;
	size_t bufsize = 65536;
	unsigned char *buf = (unsigned char*)malloc(bufsize);
	if (!buf) {
		debug_info("Out of memory");
		res = MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR;
		goto leave_unlock;
	}
	debug_info("uploading image (%d bytes)", (int)image_size);
	while (tx < image_size) {
		size_t remaining = image_size - tx;
		size_t amount = (remaining < bufsize) ? remaining : bufsize;
		ssize_t r = upload_cb(buf, amount, userdata);
		if (r < 0) {
			debug_info("upload_cb returned %d", (int)r);
			break;
		}
		uint32_t sent = 0;
		if (service_send(client->parent->parent, (const char*)buf, (uint32_t)r, &sent) != SERVICE_E_SUCCESS) {
			debug_info("service_send failed");
			break;
		}
		tx += r;
	}
	free(buf);
	if (tx < image_size) {
		debug_info("Error: failed to upload image");
		goto leave_unlock;
	}
	debug_info("image uploaded");

	res = mobile_image_mounter_error(property_list_service_receive_plist(client->parent, &result));
	if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
		debug_info("Error receiving response from device!");
		goto leave_unlock;
	}
	res = MOBILE_IMAGE_MOUNTER_E_COMMAND_FAILED;

	strval = NULL;
	node = plist_dict_get_item(result, "Status");
	if (node && plist_get_node_type(node) == PLIST_STRING) {
		plist_get_string_val(node, &strval);
	}
	if (!strval) {
		debug_info("Error: Unexpected response received!");	
		goto leave_unlock;
	}
	if (strcmp(strval, "Complete") != 0) {
		debug_info("Error: didn't get Complete but %s", strval);
		free(strval);
		goto leave_unlock;
	} else {
		res = MOBILE_IMAGE_MOUNTER_E_SUCCESS;
	}
	free(strval);
	

leave_unlock:
	mobile_image_mounter_unlock(client);
	if (result)
		plist_free(result);
	return res;

}