Example #1
0
LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, const char *label)
{
	if (!client)
		return LOCKDOWN_E_INVALID_ARG;

	static struct lockdownd_service_descriptor service = {
		0xf27e,
		0
	};

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

	lockdownd_client_t client_loc = (lockdownd_client_t) malloc(sizeof(struct lockdownd_client_private));
	client_loc->parent = plistclient;
	client_loc->ssl_enabled = 0;
	client_loc->session_id = NULL;

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

	client_loc->label = label ? strdup(label) : NULL;

	*client = client_loc;

	return LOCKDOWN_E_SUCCESS;
}
webinspector_error_t webinspector_client_new(idevice_t device, lockdownd_service_descriptor_t service, webinspector_client_t * client)
{
	*client = NULL;

	if (!device || !service || service->port == 0 || !client || *client) {
		debug_info("Incorrect parameter passed to webinspector_client_new.");
		return WEBINSPECTOR_E_INVALID_ARG;
	}

	debug_info("Creating webinspector_client, port = %d.", service->port);

	property_list_service_client_t plclient = NULL;
	webinspector_error_t ret = webinspector_error(property_list_service_client_new(device, service, &plclient));
	if (ret != WEBINSPECTOR_E_SUCCESS) {
		debug_info("Creating a property list client failed. Error: %i", ret);
		return ret;
	}

	webinspector_client_t client_loc = (webinspector_client_t) malloc(sizeof(struct webinspector_client_private));
	client_loc->parent = plclient;

	*client = client_loc;

	debug_info("webinspector_client successfully created.");
	return 0;
}
Example #3
0
heartbeat_error_t heartbeat_client_new(idevice_t device, lockdownd_service_descriptor_t service, heartbeat_client_t * client)
{
	*client = NULL;

	if (!device || !service || service->port == 0 || !client || *client) {
		debug_info("Incorrect parameter passed to heartbeat_client_new.");
		return HEARTBEAT_E_INVALID_ARG;
	}

	debug_info("Creating heartbeat_client, port = %d.", service->port);

	property_list_service_client_t plclient = NULL;
	heartbeat_error_t ret = heartbeat_error(property_list_service_client_new(device, service, &plclient));
	if (ret != HEARTBEAT_E_SUCCESS) {
		debug_info("Creating a property list client failed. Error: %i", ret);
		return ret;
	}

	heartbeat_client_t client_loc = (heartbeat_client_t) malloc(sizeof(struct heartbeat_client_private));
	client_loc->parent = plclient;

	*client = client_loc;

	debug_info("heartbeat_client successfully created.");
	return 0;
}
Example #4
0
LIBIMOBILEDEVICE_API misagent_error_t misagent_client_new(idevice_t device, lockdownd_service_descriptor_t service, misagent_client_t *client)
{
	property_list_service_client_t plistclient = NULL;
	misagent_error_t err = misagent_error(property_list_service_client_new(device, service, &plistclient));
	if (err != MISAGENT_E_SUCCESS) {
		return err;
	}

	misagent_client_t client_loc = (misagent_client_t) malloc(sizeof(struct misagent_client_private));
	client_loc->parent = plistclient;
	client_loc->last_error = 0;

	*client = client_loc;
	return MISAGENT_E_SUCCESS;
}
Example #5
0
LIBIMOBILEDEVICE_API sbservices_error_t sbservices_client_new(idevice_t device, lockdownd_service_descriptor_t service, sbservices_client_t *client)
{
	property_list_service_client_t plistclient = NULL;
	sbservices_error_t err = sbservices_error(property_list_service_client_new(device, service, &plistclient));
	if (err != SBSERVICES_E_SUCCESS) {
		return err;
	}

	sbservices_client_t client_loc = (sbservices_client_t) malloc(sizeof(struct sbservices_client_private));
	client_loc->parent = plistclient;
	mutex_init(&client_loc->mutex);

	*client = client_loc;
	return SBSERVICES_E_SUCCESS;
}
Example #6
0
/**
 * Connects to the house_arrest service on the specified device.
 *
 * @param device The device to connect to.
 * @param service The service descriptor returned by lockdownd_start_service.
 * @param client Pointer that will point to a newly allocated
 *     housearrest_client_t upon successful return.
 *
 * @return HOUSE_ARREST_E_SUCCESS on success, HOUSE_ARREST_E_INVALID_ARG when
 *     client is NULL, or an HOUSE_ARREST_E_* error code otherwise.
 */
house_arrest_error_t house_arrest_client_new(idevice_t device, lockdownd_service_descriptor_t service, house_arrest_client_t *client)
{
	property_list_service_client_t plistclient = NULL;
	house_arrest_error_t err = house_arrest_error(property_list_service_client_new(device, service, &plistclient));
	if (err != HOUSE_ARREST_E_SUCCESS) {
		return err;
	}

	house_arrest_client_t client_loc = (house_arrest_client_t) malloc(sizeof(struct house_arrest_client_private));
	client_loc->parent = plistclient;
	client_loc->mode = HOUSE_ARREST_CLIENT_MODE_NORMAL;

	*client = client_loc;
	return HOUSE_ARREST_E_SUCCESS;
}
/**
 * Connects to the mobile_image_mounter service on the specified device.
 * 
 * @param device The device to connect to.
 * @param service The service descriptor returned by lockdownd_start_service.
 * @param client Pointer that will be set to a newly allocated
 *    mobile_image_mounter_client_t upon successful return.
 * 
 * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success,
 *    MOBILE_IMAGE_MOUNTER_E_INVALID_ARG if device is NULL,
 *    or MOBILE_IMAGE_MOUNTER_E_CONN_FAILED if the connection to the
 *    device could not be established.
 */
mobile_image_mounter_error_t mobile_image_mounter_new(idevice_t device, lockdownd_service_descriptor_t service, mobile_image_mounter_client_t *client)
{
	property_list_service_client_t plistclient = NULL;
	mobile_image_mounter_error_t err = mobile_image_mounter_error(property_list_service_client_new(device, service, &plistclient));
	if (err != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
		return err;
	}

	mobile_image_mounter_client_t client_loc = (mobile_image_mounter_client_t) malloc(sizeof(struct mobile_image_mounter_client_private));
	client_loc->parent = plistclient;

	mutex_init(&client_loc->mutex);

	*client = client_loc;
	return MOBILE_IMAGE_MOUNTER_E_SUCCESS;
}
/**
 * Connects to the installation_proxy service on the specified device.
 *
 * @param device The device to connect to
 * @param service The service descriptor returned by lockdownd_start_service.
 * @param client Pointer that will be set to a newly allocated
 *     instproxy_client_t upon successful return.
 *
 * @return INSTPROXY_E_SUCCESS on success, or an INSTPROXY_E_* error value
 *     when an error occured.
 */
instproxy_error_t instproxy_client_new(idevice_t device, lockdownd_service_descriptor_t service, instproxy_client_t *client)
{
	property_list_service_client_t plistclient = NULL;
	instproxy_error_t err = instproxy_error(property_list_service_client_new(device, service, &plistclient));
	if (err != INSTPROXY_E_SUCCESS) {
		return err;
	}

	instproxy_client_t client_loc = (instproxy_client_t) malloc(sizeof(struct instproxy_client_private));
	client_loc->parent = plistclient;
	mutex_init(&client_loc->mutex);
	client_loc->status_updater = (thread_t)NULL;

	*client = client_loc;
	return INSTPROXY_E_SUCCESS;
}
LIBIMOBILEDEVICE_API np_error_t np_client_new(idevice_t device, lockdownd_service_descriptor_t service, np_client_t *client)
{
	property_list_service_client_t plistclient = NULL;
	np_error_t err = np_error(property_list_service_client_new(device, service, &plistclient));
	if (err != NP_E_SUCCESS) {
		return err;
	}

	np_client_t client_loc = (np_client_t) malloc(sizeof(struct np_client_private));
	client_loc->parent = plistclient;

	mutex_init(&client_loc->mutex);
	client_loc->notifier = (thread_t)NULL;

	*client = client_loc;
	return NP_E_SUCCESS;
}
Example #10
0
LIBIMOBILEDEVICE_API restored_error_t restored_client_new(idevice_t device, restored_client_t *client, const char *label)
{
	if (!client)
		return RESTORE_E_INVALID_ARG;

	restored_error_t ret = RESTORE_E_SUCCESS;
	idevice_error_t idev_ret;

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

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

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

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

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

	return ret;
}
Example #11
0
/**
 * Connects to the house_arrest service on the specified device.
 *
 * @param device The device to connect to.
 * @param port Destination port (usually given by lockdownd_start_service).
 * @param client Pointer that will point to a newly allocated
 *     housearrest_client_t upon successful return.
 *
 * @return HOUSE_ARREST_E_SUCCESS on success, HOUSE_ARREST_E_INVALID_ARG when
 *     client is NULL, or an HOUSE_ARREST_E_* error code otherwise.
 */
house_arrest_error_t house_arrest_client_new(idevice_t device, uint16_t port, house_arrest_client_t *client)
{
	if (!device)
		return HOUSE_ARREST_E_INVALID_ARG;

	property_list_service_client_t plistclient = NULL;
	house_arrest_error_t err = house_arrest_error(property_list_service_client_new(device, port, &plistclient));
	if (err != HOUSE_ARREST_E_SUCCESS) {
		return err;
	}

	house_arrest_client_t client_loc = (house_arrest_client_t) malloc(sizeof(struct house_arrest_client_private));
	client_loc->parent = plistclient;
	client_loc->mode = HOUSE_ARREST_CLIENT_MODE_NORMAL;

	*client = client_loc;
	return HOUSE_ARREST_E_SUCCESS;
}
Example #12
0
LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobileactivation_client_t *client)
{
	if (!device || !service || service->port == 0 || !client || *client) {
		return MOBILEACTIVATION_E_INVALID_ARG;
	}

	property_list_service_client_t plistclient = NULL;
	if (property_list_service_client_new(device, service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		return MOBILEACTIVATION_E_MUX_ERROR;
	}

	/* create client object */
	mobileactivation_client_t client_loc = (mobileactivation_client_t) malloc(sizeof(struct mobileactivation_client_private));
	client_loc->parent = plistclient;

	/* all done, return success */
	*client = client_loc;
	return MOBILEACTIVATION_E_SUCCESS;
}
/**
 * Connects to the diagnostics_relay service on the specified device.
 *
 * @param device The device to connect to.
 * @param service The service descriptor returned by lockdownd_start_service.
 * @param client Reference that will point to a newly allocated
 *     diagnostics_relay_client_t upon successful return.
 *
 * @return DIAGNOSTICS_RELAY_E_SUCCESS on success,
 *     DIAGNOSTICS_RELAY_E_INVALID_ARG when one of the parameters is invalid,
 *     or DIAGNOSTICS_RELAY_E_MUX_ERROR when the connection failed.
 */
diagnostics_relay_error_t diagnostics_relay_client_new(idevice_t device, lockdownd_service_descriptor_t service, diagnostics_relay_client_t *client)
{
	if (!device || !service || service->port == 0 || !client || *client) {
		return DIAGNOSTICS_RELAY_E_INVALID_ARG;
	}

	property_list_service_client_t plistclient = NULL;
	if (property_list_service_client_new(device, service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		return DIAGNOSTICS_RELAY_E_MUX_ERROR;
	}

	/* create client object */
	diagnostics_relay_client_t client_loc = (diagnostics_relay_client_t) malloc(sizeof(struct diagnostics_relay_client_private));
	client_loc->parent = plistclient;

	/* all done, return success */
	*client = client_loc;
	return DIAGNOSTICS_RELAY_E_SUCCESS;
}
Example #14
0
/**
 * Connects to the file_relay service on the specified device.
 *
 * @param device The device to connect to.
 * @param port Destination port (usually given by lockdownd_start_service).
 * @param client Reference that will point to a newly allocated
 *     file_relay_client_t upon successful return.
 *
 * @return FILE_RELAY_E_SUCCESS on success,
 *     FILE_RELAY_E_INVALID_ARG when one of the parameters is invalid,
 *     or FILE_RELAY_E_MUX_ERROR when the connection failed.
 */
file_relay_error_t file_relay_client_new(idevice_t device, uint16_t port, file_relay_client_t *client)
{
	if (!device || port == 0 || !client || *client) {
		return FILE_RELAY_E_INVALID_ARG;
	}

	property_list_service_client_t plistclient = NULL;
	if (property_list_service_client_new(device, port, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		return FILE_RELAY_E_MUX_ERROR;
	}

	/* create client object */
	file_relay_client_t client_loc = (file_relay_client_t) malloc(sizeof(struct file_relay_client_private));
	client_loc->parent = plistclient;

	/* all done, return success */
	*client = client_loc;
	return FILE_RELAY_E_SUCCESS;
}
/**
 * Connects to the mobile_image_mounter service on the specified device.
 * 
 * @param device The device to connect to.
 * @param port Destination port (usually given by lockdownd_start_service).
 * @param client Pointer that will be set to a newly allocated
 *    mobile_image_mounter_client_t upon successful return.
 * 
 * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success,
 *    MOBILE_IMAGE_MOUNTER_E_INVALID_ARG if device is NULL,
 *    or MOBILE_IMAGE_MOUNTER_E_CONN_FAILED if the connection to the
 *    device could not be established.
 */
mobile_image_mounter_error_t mobile_image_mounter_new(idevice_t device, uint16_t port, mobile_image_mounter_client_t *client)
{
	/* makes sure thread environment is available */
	if (!g_thread_supported())
		g_thread_init(NULL);

	if (!device)
		return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG;

	property_list_service_client_t plistclient = NULL;
	if (property_list_service_client_new(device, port, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		return MOBILE_IMAGE_MOUNTER_E_CONN_FAILED;
	}

	mobile_image_mounter_client_t client_loc = (mobile_image_mounter_client_t) malloc(sizeof(struct mobile_image_mounter_client_private));
	client_loc->parent = plistclient;

	client_loc->mutex = g_mutex_new();

	*client = client_loc;
	return MOBILE_IMAGE_MOUNTER_E_SUCCESS;
}
/**
 * Connects to the springboardservices service on the specified device.
 *
 * @param device The device to connect to.
 * @param service The service descriptor returned by lockdownd_start_service.
 * @param client Pointer that will point to a newly allocated
 *     sbservices_client_t upon successful return.
 *
 * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when
 *     client is NULL, or an SBSERVICES_E_* error code otherwise.
 */
sbservices_error_t sbservices_client_new(idevice_t device, lockdownd_service_descriptor_t service, sbservices_client_t *client)
{
	if (!device)
		return SBSERVICES_E_INVALID_ARG;

	property_list_service_client_t plistclient = NULL;
	sbservices_error_t err = sbservices_error(property_list_service_client_new(device, service, &plistclient));
	if (err != SBSERVICES_E_SUCCESS) {
		return err;
	}

	sbservices_client_t client_loc = (sbservices_client_t) malloc(sizeof(struct sbservices_client_private));
	client_loc->parent = plistclient;
#ifdef WIN32
	InitializeCriticalSection(&client_loc->mutex);
#else
	pthread_mutex_init(&client_loc->mutex, NULL);
#endif

	*client = client_loc;
	return SBSERVICES_E_SUCCESS;
}
Example #17
0
/**
 * Connects to the installation_proxy service on the specified device.
 *
 * @param device The device to connect to
 * @param port Destination port (usually given by lockdownd_start_service).
 * @param client Pointer that will be set to a newly allocated
 *     instproxy_client_t upon successful return.
 *
 * @return INSTPROXY_E_SUCCESS on success, or an INSTPROXY_E_* error value
 *     when an error occured.
 */
instproxy_error_t instproxy_client_new(idevice_t device, uint16_t port, instproxy_client_t *client)
{
	/* makes sure thread environment is available */
	if (!g_thread_supported())
		g_thread_init(NULL);

	if (!device)
		return INSTPROXY_E_INVALID_ARG;

	property_list_service_client_t plistclient = NULL;
	if (property_list_service_client_new(device, port, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		return INSTPROXY_E_CONN_FAILED;
	}

	instproxy_client_t client_loc = (instproxy_client_t) malloc(sizeof(struct instproxy_client_private));
	client_loc->parent = plistclient;
	client_loc->mutex = g_mutex_new();
	client_loc->status_updater = NULL;

	*client = client_loc;
	return INSTPROXY_E_SUCCESS;
}
Example #18
0
/**
 * Connects to the notification_proxy on the specified device.
 * 
 * @param device The device to connect to.
 * @param service The service descriptor returned by lockdownd_start_service.
 * @param client Pointer that will be set to a newly allocated np_client_t
 *    upon successful return.
 * 
 * @return NP_E_SUCCESS on success, NP_E_INVALID_ARG when device is NULL,
 *   or NP_E_CONN_FAILED when the connection to the device could not be
 *   established.
 */
np_error_t np_client_new(idevice_t device, lockdownd_service_descriptor_t service, np_client_t *client)
{
	property_list_service_client_t plistclient = NULL;
	np_error_t err = np_error(property_list_service_client_new(device, service, &plistclient));
	if (err != NP_E_SUCCESS) {
		return err;
	}

	np_client_t client_loc = (np_client_t) malloc(sizeof(struct np_client_private));
	client_loc->parent = plistclient;

#ifdef WIN32
	InitializeCriticalSection(&client_loc->mutex);
	client_loc->notifier = NULL;
#else
	pthread_mutex_init(&client_loc->mutex, NULL);
	client_loc->notifier = (pthread_t)NULL;
#endif

	*client = client_loc;
	return NP_E_SUCCESS;
}
/**
 * Connects to the installation_proxy service on the specified device.
 *
 * @param device The device to connect to
 * @param port Destination port (usually given by lockdownd_start_service).
 * @param client Pointer that will be set to a newly allocated
 *     instproxy_client_t upon successful return.
 *
 * @return INSTPROXY_E_SUCCESS on success, or an INSTPROXY_E_* error value
 *     when an error occured.
 */
instproxy_error_t instproxy_client_new(idevice_t device, uint16_t port, instproxy_client_t *client)
{
	if (!device)
		return INSTPROXY_E_INVALID_ARG;

	property_list_service_client_t plistclient = NULL;
	if (property_list_service_client_new(device, port, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		return INSTPROXY_E_CONN_FAILED;
	}

	instproxy_client_t client_loc = (instproxy_client_t) malloc(sizeof(struct instproxy_client_private));
	client_loc->parent = plistclient;
#ifdef WIN32
	InitializeCriticalSection(&client_loc->mutex);
	client_loc->status_updater = NULL;
#else
	pthread_mutex_init(&client_loc->mutex, NULL);
	client_loc->status_updater = (pthread_t)NULL;
#endif

	*client = client_loc;
	return INSTPROXY_E_SUCCESS;
}
/**
 * Creates a new device link service client.
 *
 * @param device The device to connect to.
 * @param service The service descriptor returned by lockdownd_start_service.
 * @param client Reference that will point to a newly allocated
 *     device_link_service_client_t upon successful return.
 *
 * @return DEVICE_LINK_SERVICE_E_SUCCESS on success,
 *     DEVICE_LINK_SERVICE_E_INVALID_ARG when one of the parameters is invalid,
 *     or DEVICE_LINK_SERVICE_E_MUX_ERROR when the connection failed.
 */
device_link_service_error_t device_link_service_client_new(idevice_t device, lockdownd_service_descriptor_t service, device_link_service_client_t *client)
{
	if (!device || !service || service->port == 0 || !client || *client) {
		return DEVICE_LINK_SERVICE_E_INVALID_ARG;
	}

	property_list_service_client_t plistclient = NULL;
	if (property_list_service_client_new(device, service, &plistclient) != PROPERTY_LIST_SERVICE_E_SUCCESS) {
		return DEVICE_LINK_SERVICE_E_MUX_ERROR;
	}

	/* create client object */
	device_link_service_client_t client_loc = (device_link_service_client_t) malloc(sizeof(struct device_link_service_client_private));
	client_loc->parent = plistclient;

	/* enable SSL if requested */
	if (service->ssl_enabled)
		property_list_service_enable_ssl(client_loc->parent);

	/* all done, return success */
	*client = client_loc;
	return DEVICE_LINK_SERVICE_E_SUCCESS;
}
/**
 * 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;
}
Example #22
0
LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, const char *label)
{
	if (!client)
		return LOCKDOWN_E_INVALID_ARG;

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

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

	lockdownd_client_t client_loc = (lockdownd_client_t) malloc(sizeof(struct lockdownd_client_private));
	client_loc->parent = plistclient;
	client_loc->ssl_enabled = 0;
	client_loc->session_id = NULL;

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

	client_loc->label = label ? strdup(label) : NULL;

	*client = client_loc;

	return LOCKDOWN_E_SUCCESS;
}

LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, const char *label)
{
	if (!client)
		return LOCKDOWN_E_INVALID_ARG;

	lockdownd_error_t ret = LOCKDOWN_E_SUCCESS;
	lockdownd_client_t client_loc = NULL;
	char *host_id = NULL;
	char *type = NULL;

	ret = lockdownd_client_new(device, &client_loc, label);
	if (LOCKDOWN_E_SUCCESS != ret) {
		debug_info("failed to create lockdownd client.");
		return ret;
	}

	/* perform handshake */
	if (LOCKDOWN_E_SUCCESS != lockdownd_query_type(client_loc, &type)) {
		debug_info("QueryType failed in the lockdownd client.");
		ret = LOCKDOWN_E_NOT_ENOUGH_DATA;
	} else {
		if (strcmp("com.apple.mobile.lockdown", type)) {
			debug_info("Warning QueryType request returned \"%s\".", type);
		}
	}
	if (type)
		free(type);

	plist_t pair_record = NULL;
	userpref_read_pair_record(client_loc->udid, &pair_record);
	if (pair_record) {
		pair_record_get_host_id(pair_record, &host_id);
	}
	if (LOCKDOWN_E_SUCCESS == ret && !host_id) {
		ret = LOCKDOWN_E_INVALID_CONF;
	}

	if (LOCKDOWN_E_SUCCESS == ret && !pair_record) {
		/* attempt pairing */
		ret = lockdownd_pair(client_loc, NULL);
	}

	plist_free(pair_record);
	pair_record = NULL;

	/* in any case, we need to validate pairing to receive trusted host status */
	ret = lockdownd_validate_pair(client_loc, NULL);

	/* if not paired yet, let's do it now */
	if (LOCKDOWN_E_INVALID_HOST_ID == ret) {
		ret = lockdownd_pair(client_loc, NULL);

		if (LOCKDOWN_E_SUCCESS == ret) {
			ret = lockdownd_validate_pair(client_loc, NULL);
		} else if (LOCKDOWN_E_PAIRING_DIALOG_PENDING == ret) {
			debug_info("Device shows the pairing dialog.");
		}
	}

	if (LOCKDOWN_E_SUCCESS == ret) {
		if (!host_id) {
			userpref_read_pair_record(client_loc->udid, &pair_record);
			if (pair_record) {
				pair_record_get_host_id(pair_record, &host_id);
				plist_free(pair_record);
			}
		}

		ret = lockdownd_start_session(client_loc, host_id, NULL, NULL);
		if (LOCKDOWN_E_SUCCESS != ret) {
			debug_info("Session opening failed.");
		}

		if (host_id) {
			free(host_id);
			host_id = NULL;
		}
	}
	
	if (LOCKDOWN_E_SUCCESS == ret) {
		*client = client_loc;
	} else {
		lockdownd_client_free(client_loc);
	}

	return ret;
}

/**
 * Returns a new plist from the supplied lockdownd pair record. The caller is
 * responsible for freeing the plist.
 *
 * @param pair_record The pair record to create a plist from.
 *
 * @return A pair record plist from the device, NULL if pair_record is not set
 */
static plist_t lockdownd_pair_record_to_plist(lockdownd_pair_record_t pair_record)
{
	if (!pair_record)
		return NULL;

	/* setup request plist */
	plist_t dict = plist_new_dict();
	plist_dict_set_item(dict, "DeviceCertificate", plist_new_data(pair_record->device_certificate, strlen(pair_record->device_certificate)));
	plist_dict_set_item(dict, "HostCertificate", plist_new_data(pair_record->host_certificate, strlen(pair_record->host_certificate)));
	plist_dict_set_item(dict, "HostID", plist_new_string(pair_record->host_id));
	plist_dict_set_item(dict, "RootCertificate", plist_new_data(pair_record->root_certificate, strlen(pair_record->root_certificate)));
	plist_dict_set_item(dict, "SystemBUID", plist_new_string(pair_record->system_buid));

	return dict;
}

/**
 * Generates a pair record plist with required certificates for a specific
 * device. If a pairing exists, it is loaded from the computer instead of being
 * generated.
 *
 * @param pair_record_plist Holds the pair record.
 *
 * @return LOCKDOWN_E_SUCCESS on success
 */
static lockdownd_error_t pair_record_generate(lockdownd_client_t client, plist_t *pair_record)
{
	lockdownd_error_t ret = LOCKDOWN_E_UNKNOWN_ERROR;

	key_data_t public_key = { NULL, 0 };
	char* host_id = NULL;
	char* system_buid = NULL;

	/* retrieve device public key */
	ret = lockdownd_get_device_public_key_as_key_data(client, &public_key);
	if (ret != LOCKDOWN_E_SUCCESS) {
		debug_info("device refused to send public key.");
		goto leave;
	}
	debug_info("device public key follows:\n%.*s", public_key.size, public_key.data);

	*pair_record = plist_new_dict();

	/* generate keys and certificates into pair record */
	userpref_error_t uret = USERPREF_E_SUCCESS;
	uret = pair_record_generate_keys_and_certs(*pair_record, public_key);
	switch(uret) {
		case USERPREF_E_INVALID_ARG:
			ret = LOCKDOWN_E_INVALID_ARG;
			break;
		case USERPREF_E_INVALID_CONF:
			ret = LOCKDOWN_E_INVALID_CONF;
			break;
		case USERPREF_E_SSL_ERROR:
			ret = LOCKDOWN_E_SSL_ERROR;
		default:
			break;
	}

	/* set SystemBUID */
	userpref_read_system_buid(&system_buid);
	if (system_buid) {
		plist_dict_set_item(*pair_record, USERPREF_SYSTEM_BUID_KEY, plist_new_string(system_buid));
	}

	/* set HostID */
	host_id = generate_uuid();
	pair_record_set_host_id(*pair_record, host_id);

leave:
	if (host_id)
		free(host_id);
	if (system_buid)
		free(system_buid);
	if (public_key.data)
		free(public_key.data);

	return ret;
}
Example #23
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;
}