diff options
Diffstat (limited to 'include/libimobiledevice')
27 files changed, 5823 insertions, 418 deletions
diff --git a/include/libimobiledevice/afc.h b/include/libimobiledevice/afc.h index 8d47696..4ad3dbd 100644 --- a/include/libimobiledevice/afc.h +++ b/include/libimobiledevice/afc.h @@ -1,9 +1,10 @@ /** * @file libimobiledevice/afc.h - * @brief Access the filesystem. + * @brief Access the filesystem on the device. * \internal * - * Copyright (c) 2009 Nikias Bassen All Rights Reserved. + * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. + * Copyright (c) 2009-2010 Nikias Bassen All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,50 +21,51 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef AFC_H -#define AFC_H +#ifndef IAFC_H +#define IAFC_H #ifdef __cplusplus extern "C" { #endif #include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> -/** @name Error Codes */ -/*@{*/ -#define AFC_E_SUCCESS 0 -#define AFC_E_UNKNOWN_ERROR 1 -#define AFC_E_OP_HEADER_INVALID 2 -#define AFC_E_NO_RESOURCES 3 -#define AFC_E_READ_ERROR 4 -#define AFC_E_WRITE_ERROR 5 -#define AFC_E_UNKNOWN_PACKET_TYPE 6 -#define AFC_E_INVALID_ARG 7 -#define AFC_E_OBJECT_NOT_FOUND 8 -#define AFC_E_OBJECT_IS_DIR 9 -#define AFC_E_PERM_DENIED 10 -#define AFC_E_SERVICE_NOT_CONNECTED 11 -#define AFC_E_OP_TIMEOUT 12 -#define AFC_E_TOO_MUCH_DATA 13 -#define AFC_E_END_OF_DATA 14 -#define AFC_E_OP_NOT_SUPPORTED 15 -#define AFC_E_OBJECT_EXISTS 16 -#define AFC_E_OBJECT_BUSY 17 -#define AFC_E_NO_SPACE_LEFT 18 -#define AFC_E_OP_WOULD_BLOCK 19 -#define AFC_E_IO_ERROR 20 -#define AFC_E_OP_INTERRUPTED 21 -#define AFC_E_OP_IN_PROGRESS 22 -#define AFC_E_INTERNAL_ERROR 23 - -#define AFC_E_MUX_ERROR 30 -#define AFC_E_NO_MEM 31 -#define AFC_E_NOT_ENOUGH_DATA 32 -#define AFC_E_DIR_NOT_EMPTY 33 -/*@}*/ - -/** Represents an error code. */ -typedef int16_t afc_error_t; +/** Service identifier passed to lockdownd_start_service() to start the AFC service */ +#define AFC_SERVICE_NAME "com.apple.afc" + +/** Error Codes */ +typedef enum { + AFC_E_SUCCESS = 0, + AFC_E_UNKNOWN_ERROR = 1, + AFC_E_OP_HEADER_INVALID = 2, + AFC_E_NO_RESOURCES = 3, + AFC_E_READ_ERROR = 4, + AFC_E_WRITE_ERROR = 5, + AFC_E_UNKNOWN_PACKET_TYPE = 6, + AFC_E_INVALID_ARG = 7, + AFC_E_OBJECT_NOT_FOUND = 8, + AFC_E_OBJECT_IS_DIR = 9, + AFC_E_PERM_DENIED = 10, + AFC_E_SERVICE_NOT_CONNECTED = 11, + AFC_E_OP_TIMEOUT = 12, + AFC_E_TOO_MUCH_DATA = 13, + AFC_E_END_OF_DATA = 14, + AFC_E_OP_NOT_SUPPORTED = 15, + AFC_E_OBJECT_EXISTS = 16, + AFC_E_OBJECT_BUSY = 17, + AFC_E_NO_SPACE_LEFT = 18, + AFC_E_OP_WOULD_BLOCK = 19, + AFC_E_IO_ERROR = 20, + AFC_E_OP_INTERRUPTED = 21, + AFC_E_OP_IN_PROGRESS = 22, + AFC_E_INTERNAL_ERROR = 23, + AFC_E_MUX_ERROR = 30, + AFC_E_NO_MEM = 31, + AFC_E_NOT_ENOUGH_DATA = 32, + AFC_E_DIR_NOT_EMPTY = 33, + AFC_E_FORCE_SIGNED_TYPE = -1 +} afc_error_t; /** Flags for afc_file_open */ typedef enum { @@ -88,33 +90,293 @@ typedef enum { AFC_LOCK_UN = 8 | 4 /**< unlock */ } afc_lock_op_t; -typedef struct afc_client_private afc_client_private; +typedef struct afc_client_private afc_client_private; /**< \private */ typedef afc_client_private *afc_client_t; /**< The client handle. */ /* Interface */ -afc_error_t afc_client_new_from_connection(idevice_connection_t connection, afc_client_t *client); -afc_error_t afc_client_new(idevice_t device, uint16_t port, afc_client_t *client); -afc_error_t afc_client_free(afc_client_t client); -afc_error_t afc_get_device_info(afc_client_t client, char ***infos); -afc_error_t afc_read_directory(afc_client_t client, const char *dir, char ***list); -afc_error_t afc_get_file_info(afc_client_t client, const char *filename, char ***infolist); -afc_error_t afc_file_open(afc_client_t client, const char *filename, afc_file_mode_t file_mode, uint64_t *handle); -afc_error_t afc_file_close(afc_client_t client, uint64_t handle); -afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation); -afc_error_t afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_read); -afc_error_t afc_file_write(afc_client_t client, uint64_t handle, const char *data, uint32_t length, uint32_t *bytes_written); -afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence); -afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *position); -afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize); -afc_error_t afc_remove_path(afc_client_t client, const char *path); -afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *to); -afc_error_t afc_make_directory(afc_client_t client, const char *dir); -afc_error_t afc_truncate(afc_client_t client, const char *path, uint64_t newsize); -afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const char *target, const char *linkname); -afc_error_t afc_set_file_time(afc_client_t client, const char *path, uint64_t mtime); + +/** + * Makes a connection to the AFC service on the 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 afc_client_t + * upon successful return. + * + * @return AFC_E_SUCCESS on success, AFC_E_INVALID_ARG if device or service is + * invalid, AFC_E_MUX_ERROR if the connection cannot be established, + * or AFC_E_NO_MEM if there is a memory allocation problem. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_client_new(idevice_t device, lockdownd_service_descriptor_t service, afc_client_t *client); + +/** + * Starts a new AFC service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated afc_client_t upon + * successful return. Must be freed using afc_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return AFC_E_SUCCESS on success, or an AFC_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_client_start_service(idevice_t device, afc_client_t* client, const char* label); + +/** + * Frees up an AFC client. If the connection was created by the client itself, + * the connection will be closed. + * + * @param client The client to free. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_client_free(afc_client_t client); + +/** + * Get device information for a connected client. The device information + * returned is the device model as well as the free space, the total capacity + * and blocksize on the accessed disk partition. + * + * @param client The client to get device info for. + * @param device_information A char list of device information terminated by an + * empty string or NULL if there was an error. Free with + * afc_dictionary_free(). + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_get_device_info(afc_client_t client, char ***device_information); + +/** + * Gets a directory listing of the directory requested. + * + * @param client The client to get a directory listing from. + * @param path The directory for listing. (must be a fully-qualified path) + * @param directory_information A char list of files in the directory + * terminated by an empty string or NULL if there was an error. Free with + * afc_dictionary_free(). + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_read_directory(afc_client_t client, const char *path, char ***directory_information); + +/** + * Gets information about a specific file. + * + * @param client The client to use to get the information of the file. + * @param path The fully-qualified path to the file. + * @param file_information Pointer to a buffer that will be filled with a + * NULL-terminated list of strings with the file information. Set to NULL + * before calling this function. Free with afc_dictionary_free(). + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_get_file_info(afc_client_t client, const char *path, char ***file_information); + +/** + * Opens a file on the device. + * + * @param client The client to use to open the file. + * @param filename The file to open. (must be a fully-qualified path) + * @param file_mode The mode to use to open the file. + * @param handle Pointer to a uint64_t that will hold the handle of the file + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_file_open(afc_client_t client, const char *filename, afc_file_mode_t file_mode, uint64_t *handle); + +/** + * Closes a file on the device. + * + * @param client The client to close the file with. + * @param handle File handle of a previously opened file. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_file_close(afc_client_t client, uint64_t handle); + +/** + * Locks or unlocks a file on the device. + * + * Makes use of flock on the device. + * @see http://developer.apple.com/documentation/Darwin/Reference/ManPages/man2/flock.2.html + * + * @param client The client to lock the file with. + * @param handle File handle of a previously opened file. + * @param operation the lock or unlock operation to perform, this is one of + * AFC_LOCK_SH (shared lock), AFC_LOCK_EX (exclusive lock), or + * AFC_LOCK_UN (unlock). + */ +LIBIMOBILEDEVICE_API afc_error_t afc_file_lock(afc_client_t client, uint64_t handle, afc_lock_op_t operation); + +/** + * Attempts to the read the given number of bytes from the given file. + * + * @param client The relevant AFC client + * @param handle File handle of a previously opened file + * @param data The pointer to the memory region to store the read data + * @param length The number of bytes to read + * @param bytes_read The number of bytes actually read. + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_file_read(afc_client_t client, uint64_t handle, char *data, uint32_t length, uint32_t *bytes_read); + +/** + * Writes a given number of bytes to a file. + * + * @param client The client to use to write to the file. + * @param handle File handle of previously opened file. + * @param data The data to write to the file. + * @param length How much data to write. + * @param bytes_written The number of bytes actually written to the file. + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_file_write(afc_client_t client, uint64_t handle, const char *data, uint32_t length, uint32_t *bytes_written); + +/** + * Seeks to a given position of a pre-opened file on the device. + * + * @param client The client to use to seek to the position. + * @param handle File handle of a previously opened. + * @param offset Seek offset. + * @param whence Seeking direction, one of SEEK_SET, SEEK_CUR, or SEEK_END. + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_file_seek(afc_client_t client, uint64_t handle, int64_t offset, int whence); + +/** + * Returns current position in a pre-opened file on the device. + * + * @param client The client to use. + * @param handle File handle of a previously opened file. + * @param position Position in bytes of indicator + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_file_tell(afc_client_t client, uint64_t handle, uint64_t *position); + +/** + * Sets the size of a file on the device. + * + * @param client The client to use to set the file size. + * @param handle File handle of a previously opened file. + * @param newsize The size to set the file to. + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + * + * @note This function is more akin to ftruncate than truncate, and truncate + * calls would have to open the file before calling this, sadly. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_file_truncate(afc_client_t client, uint64_t handle, uint64_t newsize); + +/** + * Deletes a file or directory. + * + * @param client The client to use. + * @param path The path to delete. (must be a fully-qualified path) + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_remove_path(afc_client_t client, const char *path); + +/** + * Renames a file or directory on the device. + * + * @param client The client to have rename. + * @param from The name to rename from. (must be a fully-qualified path) + * @param to The new name. (must also be a fully-qualified path) + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_rename_path(afc_client_t client, const char *from, const char *to); + +/** + * Creates a directory on the device. + * + * @param client The client to use to make a directory. + * @param path The directory's path. (must be a fully-qualified path, I assume + * all other mkdir restrictions apply as well) + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_make_directory(afc_client_t client, const char *path); + +/** + * Sets the size of a file on the device without prior opening it. + * + * @param client The client to use to set the file size. + * @param path The path of the file to be truncated. + * @param newsize The size to set the file to. + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_truncate(afc_client_t client, const char *path, uint64_t newsize); + +/** + * Creates a hard link or symbolic link on the device. + * + * @param client The client to use for making a link + * @param linktype 1 = hard link, 2 = symlink + * @param target The file to be linked. + * @param linkname The name of link. + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_make_link(afc_client_t client, afc_link_type_t linktype, const char *target, const char *linkname); + +/** + * Sets the modification time of a file on the device. + * + * @param client The client to use to set the file size. + * @param path Path of the file for which the modification time should be set. + * @param mtime The modification time to set in nanoseconds since epoch. + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_set_file_time(afc_client_t client, const char *path, uint64_t mtime); + +/** + * Deletes a file or directory including possible contents. + * + * @param client The client to use. + * @param path The path to delete. (must be a fully-qualified path) + * @since libimobiledevice 1.1.7 + * @note Only available in iOS 6 and later. + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_remove_path_and_contents(afc_client_t client, const char *path); /* Helper functions */ -afc_error_t afc_get_device_info_key(afc_client_t client, const char *key, char **value); + +/** + * Get a specific key of the device info list for a client connection. + * Known key values are: Model, FSTotalBytes, FSFreeBytes and FSBlockSize. + * This is a helper function for afc_get_device_info(). + * + * @param client The client to get device info for. + * @param key The key to get the value of. + * @param value The value for the key if successful or NULL otherwise. + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_get_device_info_key(afc_client_t client, const char *key, char **value); + +/** + * Frees up a char dictionary as returned by some AFC functions. + * + * @param dictionary The char array terminated by an empty string. + * + * @return AFC_E_SUCCESS on success or an AFC_E_* error value. + */ +LIBIMOBILEDEVICE_API afc_error_t afc_dictionary_free(char **dictionary); + +/** + * Gets a readable error string for a given AFC error code. + * + * @param err An AFC error code + * + * @returns A readable error string + */ +LIBIMOBILEDEVICE_API const char* afc_strerror(afc_error_t err); #ifdef __cplusplus } diff --git a/include/libimobiledevice/bt_packet_logger.h b/include/libimobiledevice/bt_packet_logger.h new file mode 100644 index 0000000..590e5c1 --- /dev/null +++ b/include/libimobiledevice/bt_packet_logger.h @@ -0,0 +1,156 @@ +/** + * @file libimobiledevice/bt_packet_logger.h + * @brief Capture the Bluetooth HCI trace from a device + * \internal + * + * Copyright (c) 2021 Geoffrey Kruse, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IBT_PACKET_LOGGER_H +#define IBT_PACKET_LOGGER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +#define BT_PACKETLOGGER_SERVICE_NAME "com.apple.bluetooth.BTPacketLogger" +#define BT_MAX_PACKET_SIZE 65535 + +/** Error Codes */ +typedef enum { + BT_PACKET_LOGGER_E_SUCCESS = 0, + BT_PACKET_LOGGER_E_INVALID_ARG = -1, + BT_PACKET_LOGGER_E_MUX_ERROR = -2, + BT_PACKET_LOGGER_E_SSL_ERROR = -3, + BT_PACKET_LOGGER_E_NOT_ENOUGH_DATA = -4, + BT_PACKET_LOGGER_E_TIMEOUT = -5, + BT_PACKET_LOGGER_E_UNKNOWN_ERROR = -256 +} bt_packet_logger_error_t; + +typedef struct { + uint32_t length; + uint32_t ts_secs; + uint32_t ts_usecs; +} bt_packet_logger_header_t; + +typedef struct bt_packet_logger_client_private bt_packet_logger_client_private; +typedef bt_packet_logger_client_private *bt_packet_logger_client_t; /**< The client handle. */ + +/** Receives each hci packet received from the device. */ +typedef void (*bt_packet_logger_receive_cb_t)(uint8_t * data, uint16_t len, void *user_data); + +/* Interface */ + +/** + * Connects to the bt_packet_logger 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 + * bt_packet_logger_client_t upon successful return. Must be freed using + * bt_packet_logger_client_free() after use. + * + * @return BT_PACKET_LOGGER_E_SUCCESS on success, BT_PACKET_LOGGER_E_INVALID_ARG when + * client is NULL, or an BT_PACKET_LOGGER_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_client_new(idevice_t device, lockdownd_service_descriptor_t service, bt_packet_logger_client_t * client); + +/** + * Starts a new bt_packet_logger service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * bt_packet_logger_client_t upon successful return. Must be freed using + * bt_packet_logger_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return BT_PACKET_LOGGER_E_SUCCESS on success, or an BT_PACKET_LOGGER_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_client_start_service(idevice_t device, bt_packet_logger_client_t * client, const char* label); + +/** + * Disconnects a bt_packet_logger client from the device and frees up the + * bt_packet_logger client data. + * + * @param client The bt_packet_logger client to disconnect and free. + * + * @return BT_PACKET_LOGGER_E_SUCCESS on success, BT_PACKET_LOGGER_E_INVALID_ARG when + * client is NULL, or an BT_PACKET_LOGGER_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_client_free(bt_packet_logger_client_t client); + + +/** + * Starts capturing the hci interface from the device using a callback. + * + * Use bt_packet_logger_stop_capture() to stop receiving hci data. + * + * @param client The bt_packet_logger client to use + * @param callback Callback to receive each packet from the hci interface. + * @param user_data Custom pointer passed to the callback function. + * + * @return BT_PACKET_LOGGER_E_SUCCESS on success, + * BT_PACKET_LOGGER_E_INVALID_ARG when one or more parameters are + * invalid or BT_PACKET_LOGGER_E_UNKNOWN_ERROR when an unspecified + * error occurs or an hci capture has already been started. + */ +LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_start_capture(bt_packet_logger_client_t client, bt_packet_logger_receive_cb_t callback, void* user_data); + +/** + * Stops capturing the hci interface from the device. + * + * Use bt_packet_logger_start_capture() to start receiving the hci data. + * + * @param client The bt_packet_logger client to use + * + * @return BT_PACKET_LOGGER_E_SUCCESS on success, + * BT_PACKET_LOGGER_E_INVALID_ARG when one or more parameters are + * invalid or BT_PACKET_LOGGER_E_UNKNOWN_ERROR when an unspecified + * error occurs or an hci capture has already been started. + */ +LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_stop_capture(bt_packet_logger_client_t client); + +/* Receiving */ + +/** + * Receives data using the given bt_packet_logger client with specified timeout. + * + * @param client The bt_packet_logger client to use for receiving + * @param data Buffer that will be filled with the data received + * @param size Number of bytes to receive + * @param received Number of bytes received (can be NULL to ignore) + * @param timeout Maximum time in milliseconds to wait for data. + * + * @return BT_PACKET_LOGGER_E_SUCCESS on success, + * BT_PACKET_LOGGER_E_INVALID_ARG when one or more parameters are + * invalid, BT_PACKET_LOGGER_E_MUX_ERROR when a communication error + * occurs, or BT_PACKET_LOGGER_E_UNKNOWN_ERROR when an unspecified + * error occurs. + */ +LIBIMOBILEDEVICE_API bt_packet_logger_error_t bt_packet_logger_receive_with_timeout(bt_packet_logger_client_t client, char *data, uint32_t size, uint32_t *received, unsigned int timeout); + + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/companion_proxy.h b/include/libimobiledevice/companion_proxy.h new file mode 100644 index 0000000..544322a --- /dev/null +++ b/include/libimobiledevice/companion_proxy.h @@ -0,0 +1,212 @@ +/** + * @file libimobiledevice/companion_proxy.h + * @brief Companion proxy support. + * \internal + * + * Copyright (c) 2019-2020 Nikias Bassen, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ICOMPANION_PROXY_H +#define ICOMPANION_PROXY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +/** Service identifier passed to lockdownd_start_service() to start the companion proxy service */ +#define COMPANION_PROXY_SERVICE_NAME "com.apple.companion_proxy" + +/** Error Codes */ +typedef enum { + COMPANION_PROXY_E_SUCCESS = 0, + COMPANION_PROXY_E_INVALID_ARG = -1, + COMPANION_PROXY_E_PLIST_ERROR = -2, + COMPANION_PROXY_E_MUX_ERROR = -3, + COMPANION_PROXY_E_SSL_ERROR = -4, + COMPANION_PROXY_E_NOT_ENOUGH_DATA = -5, + COMPANION_PROXY_E_TIMEOUT = -6, + COMPANION_PROXY_E_OP_IN_PROGRESS = -7, + COMPANION_PROXY_E_NO_DEVICES = -100, + COMPANION_PROXY_E_UNSUPPORTED_KEY = -101, + COMPANION_PROXY_E_TIMEOUT_REPLY = -102, + COMPANION_PROXY_E_UNKNOWN_ERROR = -256 +} companion_proxy_error_t; + +typedef struct companion_proxy_client_private companion_proxy_client_private; /**< \private */ +typedef companion_proxy_client_private *companion_proxy_client_t; /**< The client handle. */ + +/** Callback for companion device events */ +typedef void (*companion_proxy_device_event_cb_t) (plist_t event, void* userdata); + +/** + * Connects to the companion_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 point to a newly allocated + * companion_proxy_client_t upon successful return. Must be freed using + * companion_proxy_client_free() after use. + * + * @return COMPANION_PROXY_E_SUCCESS on success, COMPANION_PROXY_E_INVALID_ARG when + * the arguments are invalid, or an COMPANION_PROXY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API companion_proxy_error_t companion_proxy_client_new(idevice_t device, lockdownd_service_descriptor_t service, companion_proxy_client_t* client); + +/** + * Starts a new companion_proxy service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * companion_proxy_client_t upon successful return. Must be freed using + * companion_proxy_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return COMPANION_PROXY_E_SUCCESS on success, or an COMPANION_PROXY_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API companion_proxy_error_t companion_proxy_client_start_service(idevice_t device, companion_proxy_client_t* client, const char* label); + +/** + * Disconnects a companion_proxy client from the device and frees up the + * companion_proxy client data. + * + * @param client The companion_proxy client to disconnect and free. + * + * @return COMPANION_PROXY_E_SUCCESS on success, COMPANION_PROXY_E_INVALID_ARG when + * client is NULL, or an COMPANION_PROXY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API companion_proxy_error_t companion_proxy_client_free(companion_proxy_client_t client); + +/** + * Sends a plist to the service. + * + * @param client The companion_proxy client + * @param plist The plist to send + * + * @return COMPANION_PROXY_E_SUCCESS on success, + * COMPANION_PROXY_E_INVALID_ARG when client or plist is NULL + */ +LIBIMOBILEDEVICE_API companion_proxy_error_t companion_proxy_send(companion_proxy_client_t client, plist_t plist); + +/** + * Receives a plist from the service. + * + * @param client The companion_proxy client + * @param plist The plist to store the received data + * + * @return COMPANION_PROXY_E_SUCCESS on success, + * COMPANION_PROXY_E_INVALID_ARG when client or plist is NULL + */ +LIBIMOBILEDEVICE_API companion_proxy_error_t companion_proxy_receive(companion_proxy_client_t client, plist_t * plist); + +/** + * Retrieves a list of paired devices. + * + * @param client The companion_proxy client + * @param paired_devices Point that will receive a PLIST_ARRAY with paired device UDIDs + * + * @note The device closes the connection after sending the reply. + * + * @return COMPANION_PROXY_E_SUCCESS on success, + * COMPANION_PROXY_E_NO_DEVICES if no devices are paired, + * or a COMPANION_PROXY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API companion_proxy_error_t companion_proxy_get_device_registry(companion_proxy_client_t client, plist_t* paired_devices); + +/** + * Starts listening for paired devices. + * + * @param client The companion_proxy client + * @param callback Callback function that will be called when a new device is detected + * @param userdata Pointer that that will be passed to the callback function + * + * @note The event parameter that gets passed to the callback function is + * freed internally after returning from the callback. The consumer needs + * to make a copy if required. + * + * @return COMPANION_PROXY_E_SUCCESS on success, + * or a COMPANION_PROXY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API companion_proxy_error_t companion_proxy_start_listening_for_devices(companion_proxy_client_t client, companion_proxy_device_event_cb_t callback, void* userdata); + +/** + * Stops listening for paired devices + * + * @param client The companion_proxy client + * + * @return COMPANION_PROXY_E_SUCCESS on success, + * or a COMPANION_PROXY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API companion_proxy_error_t companion_proxy_stop_listening_for_devices(companion_proxy_client_t client); + +/** + * Returns a value for the given key. + * + * @param client The companion_proxy client + * @param companion_udid UDID of the (paired) companion device + * @param key The key to retrieve the value for + * @param value A pointer to a plist_t that will receive the value for the given key. + * The consumer is responsible for freeing the value with plist_free() when no longer needed. + * + * @note The device closes the connection after sending the reply. + * + * @return COMPANION_PROXY_E_SUCCESS on success, + * COMPANION_PROXY_E_INVALID_ARG when client or paired_devices is invalid, + * COMPANION_PROXY_E_UNSUPPORTED_KEY if the companion device doesn't support the given key, + * or a COMPANION_PROXY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API companion_proxy_error_t companion_proxy_get_value_from_registry(companion_proxy_client_t client, const char* companion_udid, const char* key, plist_t* value); + +/** + * Start forwarding a service port on the companion device to a port on the idevice. + * + * @see companion_proxy_stop_forwarding_service_port + * + * @param client The companion_proxy client + * @param remote_port remote port + * @param service_name The name of the service that shall be forwarded + * @param forward_port Pointer that will receive the newly-assigned port accessible via USB/Network on the idevice + * @param options PLIST_DICT with additional options. Currently known are + * IsServiceLowPriority (boolean) and PreferWifi (boolean). + * + * @return COMPANION_PROXY_E_SUCCESS on success, + * or a COMPANION_PROXY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API companion_proxy_error_t companion_proxy_start_forwarding_service_port(companion_proxy_client_t client, uint16_t remote_port, const char* service_name, uint16_t* forward_port, plist_t options); + +/** + * Stop forwarding a service port between companion device and idevice. + * + * @see companion_proxy_start_forwarding_service_port + * + * @param client The companion_proxy client + * @param remote_port remote port + * + * @return COMPANION_PROXY_E_SUCCESS on success, + * or a COMPANION_PROXY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API companion_proxy_error_t companion_proxy_stop_forwarding_service_port(companion_proxy_client_t client, uint16_t remote_port); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/debugserver.h b/include/libimobiledevice/debugserver.h new file mode 100644 index 0000000..809b97f --- /dev/null +++ b/include/libimobiledevice/debugserver.h @@ -0,0 +1,272 @@ +/** + * @file libimobiledevice/debugserver.h + * @brief Communicate with debugserver on the device. + * \internal + * + * Copyright (c) 2014 Martin Szulecki All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IDEBUGSERVER_H +#define IDEBUGSERVER_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +/** Service identifier passed to lockdownd_start_service() to start the debugserver service */ +#define DEBUGSERVER_SERVICE_NAME "com.apple.debugserver" +/** Service identifier passed to lockdownd_start_service() to start the secure debugserver service */ +#define DEBUGSERVER_SECURE_SERVICE_NAME DEBUGSERVER_SERVICE_NAME ".DVTSecureSocketProxy" + +/** Error Codes */ +typedef enum { + DEBUGSERVER_E_SUCCESS = 0, + DEBUGSERVER_E_INVALID_ARG = -1, + DEBUGSERVER_E_MUX_ERROR = -2, + DEBUGSERVER_E_SSL_ERROR = -3, + DEBUGSERVER_E_RESPONSE_ERROR = -4, + DEBUGSERVER_E_TIMEOUT = -5, + DEBUGSERVER_E_UNKNOWN_ERROR = -256 +} debugserver_error_t; + +typedef struct debugserver_client_private debugserver_client_private; /**< \private */ +typedef debugserver_client_private *debugserver_client_t; /**< The client handle. */ + +typedef struct debugserver_command_private debugserver_command_private; /**< \private */ +typedef debugserver_command_private *debugserver_command_t; /**< The command handle. */ + +/* Interface */ + +/** + * Connects to the debugserver 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 + * debugserver_client_t upon successful return. Must be freed using + * debugserver_client_free() after use. + * + * @return DEBUGSERVER_E_SUCCESS on success, DEBUGSERVER_E_INVALID_ARG when + * client is NULL, or an DEBUGSERVER_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_new(idevice_t device, lockdownd_service_descriptor_t service, debugserver_client_t * client); + +/** + * Starts a new debugserver service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * debugserver_client_t upon successful return. Must be freed using + * debugserver_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return DEBUGSERVER_E_SUCCESS on success, or an DEBUGSERVER_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_start_service(idevice_t device, debugserver_client_t * client, const char* label); + +/** + * Disconnects a debugserver client from the device and frees up the + * debugserver client data. + * + * @param client The debugserver client to disconnect and free. + * + * @return DEBUGSERVER_E_SUCCESS on success, DEBUGSERVER_E_INVALID_ARG when + * client is NULL, or an DEBUGSERVER_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_free(debugserver_client_t client); + +/** + * Sends raw data using the given debugserver service client. + * + * @param client The debugserver client to use for sending + * @param data Data to send + * @param size Size of the data to send + * @param sent Number of bytes sent (can be NULL to ignore) + * + * @return DEBUGSERVER_E_SUCCESS on success, + * DEBUGSERVER_E_INVALID_ARG when one or more parameters are + * invalid, or DEBUGSERVER_E_UNKNOWN_ERROR when an unspecified + * error occurs. + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_send(debugserver_client_t client, const char* data, uint32_t size, uint32_t *sent); + +/** + * Receives raw data using the given debugserver client with specified timeout. + * + * @param client The debugserver client to use for receiving + * @param data Buffer that will be filled with the data received + * @param size Number of bytes to receive + * @param received Number of bytes received (can be NULL to ignore) + * @param timeout Maximum time in milliseconds to wait for data. + * + * @return DEBUGSERVER_E_SUCCESS on success, + * DEBUGSERVER_E_INVALID_ARG when one or more parameters are + * invalid, DEBUGSERVER_E_MUX_ERROR when a communication error + * occurs, DEBUGSERVER_E_TIMEOUT when the timeout is reached, + * or DEBUGSERVER_E_UNKNOWN_ERROR when an unspecified + * error occurs. + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive_with_timeout(debugserver_client_t client, char *data, uint32_t size, uint32_t *received, unsigned int timeout); + +/** + * Receives raw data from the debugserver service. + * + * @param client The debugserver client + * @param data Buffer that will be filled with the data received + * @param size Number of bytes to receive + * @param received Number of bytes received (can be NULL to ignore) + * @note The default read timeout is 10 seconds. + * + * @return DEBUGSERVER_E_SUCCESS on success, + * DEBUGSERVER_E_INVALID_ARG when client or plist is NULL + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive(debugserver_client_t client, char *data, uint32_t size, uint32_t *received); + +/** + * Sends a command to the debugserver service. + * + * @param client The debugserver client + * @param command Command to process and send + * @param response Response received for the command (can be NULL to ignore) + * @param response_size Pointer to receive response size. Set to NULL to ignore. + * + * @return DEBUGSERVER_E_SUCCESS on success, + * DEBUGSERVER_E_INVALID_ARG when client or command is NULL + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_send_command(debugserver_client_t client, debugserver_command_t command, char** response, size_t* response_size); + +/** + * Receives and parses response of debugserver service. + * + * @param client The debugserver client + * @param response Response received for last command (can be NULL to ignore) + * @param response_size Pointer to receive response size. Set to NULL to ignore. + * + * @return DEBUGSERVER_E_SUCCESS on success, + * DEBUGSERVER_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_receive_response(debugserver_client_t client, char** response, size_t* response_size); + +/** + * Controls status of ACK mode when sending commands or receiving responses. + * + * @see debugserver_client_send_command, debugserver_client_receive_response + * + * @param client The debugserver client + * @param enabled A boolean flag indicating whether the internal ACK mode + * handling should be enabled or disabled. + * + * @return DEBUGSERVER_E_SUCCESS on success, or an DEBUGSERVER_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_set_ack_mode(debugserver_client_t client, int enabled); + +/** + * Sets behavior when awaiting a response from the server. + * + * @see debugserver_client_send_command, debugserver_client_receive_response, + * debugserver_client_receive + * + * @param client The debugserver client + * @param cancel_receive A function pointer that will be called approximately + * every receive_loop_timeout milliseconds; the function should return a + * boolean flag specifying whether to stop waiting for a response. If NULL, + * behaves as if it always returns true. + * @param receive_loop_timeout Time in milliseconds between calls to + * cancel_receive. + * + * @return DEBUGSERVER_E_SUCCESS on success, or an DEBUGSERVER_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_set_receive_params(debugserver_client_t client, int (*cancel_receive)(), int receive_loop_timeout); + +/** + * Sets the argv which launches an app. + * + * @param client The debugserver client + * @param argc Number of arguments + * @param argv Array starting with the executable to be run followed by it's arguments + * @param response Response received for the command (can be NULL to ignore) + * + * @return DEBUGSERVER_E_SUCCESS on success, + * DEBUGSERVER_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_set_argv(debugserver_client_t client, int argc, char* argv[], char** response); + +/** + * Adds or sets an environment variable. + * + * @param client The debugserver client + * @param env The environment variable in "KEY=VALUE" notation + * @param response Response received for the command (can be NULL to ignore) + * + * @return DEBUGSERVER_E_SUCCESS on success, + * DEBUGSERVER_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_client_set_environment_hex_encoded(debugserver_client_t client, const char* env, char** response); + +/** + * Creates and initializes a new command object. + * + * @param name The name of the command which is sent in plain text + * @param argv Array of tokens for the command ment to be encoded + * @param argc Number of items in the token array + * @param command New command object + * + * @return DEBUGSERVER_E_SUCCESS on success, + * DEBUGSERVER_E_INVALID_ARG when name or command is NULL + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_command_new(const char* name, int argc, char* argv[], debugserver_command_t* command); + +/** + * Frees memory of command object. + * + * @param command The command object + * + * @return DEBUGSERVER_E_SUCCESS on success, + * DEBUGSERVER_E_INVALID_ARG when command is NULL + */ +LIBIMOBILEDEVICE_API debugserver_error_t debugserver_command_free(debugserver_command_t command); + +/** + * Encodes a string into hex notation. + * + * @param buffer String to encode into hex notiation + * @param encoded_buffer The buffer receives a hex encoded string + * @param encoded_length Length of the hex encoded string + */ +LIBIMOBILEDEVICE_API void debugserver_encode_string(const char* buffer, char** encoded_buffer, uint32_t* encoded_length); + +/** + * Decodes a hex encoded string. + * + * @param encoded_buffer The buffer with a hex encoded string + * @param encoded_length Length of the encoded buffer + * @param buffer Decoded string to be freed by the caller + */ +LIBIMOBILEDEVICE_API void debugserver_decode_string(const char *encoded_buffer, size_t encoded_length, char** buffer); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/diagnostics_relay.h b/include/libimobiledevice/diagnostics_relay.h new file mode 100644 index 0000000..6ab47a9 --- /dev/null +++ b/include/libimobiledevice/diagnostics_relay.h @@ -0,0 +1,228 @@ +/** + * @file libimobiledevice/diagnostics_relay.h + * @brief Request iOS diagnostic information from device. + * \internal + * + * Copyright (c) 2012-2014 Martin Szulecki, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IDIAGNOSTICS_RELAY_H +#define IDIAGNOSTICS_RELAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +/** Service identifier passed to lockdownd_start_service() to start the diagnostics relay service */ +#define DIAGNOSTICS_RELAY_SERVICE_NAME "com.apple.mobile.diagnostics_relay" + +/** Error Codes */ +typedef enum { + DIAGNOSTICS_RELAY_E_SUCCESS = 0, + DIAGNOSTICS_RELAY_E_INVALID_ARG = -1, + DIAGNOSTICS_RELAY_E_PLIST_ERROR = -2, + DIAGNOSTICS_RELAY_E_MUX_ERROR = -3, + DIAGNOSTICS_RELAY_E_UNKNOWN_REQUEST = -4, + DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR = -256 +} diagnostics_relay_error_t; + +/** Action type for #diagnostics_relay_restart and #diagnostics_relay_shutdown */ +typedef enum { + DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT = 1 << 1, + DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_PASS = 1 << 2, + DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_FAIL = 1 << 3 +} diagnostics_relay_action_t; + +#define DIAGNOSTICS_RELAY_REQUEST_TYPE_ALL "All" /**< Query all available diagnostics */ +#define DIAGNOSTICS_RELAY_REQUEST_TYPE_WIFI "WiFi" /**< Query WiFi diagnostics */ +#define DIAGNOSTICS_RELAY_REQUEST_TYPE_GAS_GAUGE "GasGauge" /**< Query GasGauge diagnostics */ +#define DIAGNOSTICS_RELAY_REQUEST_TYPE_NAND "NAND" /**< Query NAND diagnostics */ + +typedef struct diagnostics_relay_client_private diagnostics_relay_client_private; /**< \private */ +typedef diagnostics_relay_client_private *diagnostics_relay_client_t; /**< The client handle. */ + +/** + * 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. + */ +LIBIMOBILEDEVICE_API diagnostics_relay_error_t diagnostics_relay_client_new(idevice_t device, lockdownd_service_descriptor_t service, diagnostics_relay_client_t *client); + +/** + * Starts a new diagnostics_relay service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * diagnostics_relay_client_t upon successful return. Must be freed using + * diagnostics_relay_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, or an DIAGNOSTICS_RELAY_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API diagnostics_relay_error_t diagnostics_relay_client_start_service(idevice_t device, diagnostics_relay_client_t* client, const char* label); + +/** + * Disconnects a diagnostics_relay client from the device and frees up the + * diagnostics_relay client data. + * + * @param client The diagnostics_relay client to disconnect and free. + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, + * DIAGNOSTICS_RELAY_E_INVALID_ARG when one of client or client->parent + * is invalid, or DIAGNOSTICS_RELAY_E_UNKNOWN_ERROR when the was an + * error freeing the parent property_list_service client. + */ +LIBIMOBILEDEVICE_API diagnostics_relay_error_t diagnostics_relay_client_free(diagnostics_relay_client_t client); + + +/** + * Sends the Goodbye request signaling the end of communication. + * + * @param client The diagnostics_relay client + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, + * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, + * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the + * request + */ +LIBIMOBILEDEVICE_API diagnostics_relay_error_t diagnostics_relay_goodbye(diagnostics_relay_client_t client); + +/** + * Puts the device into deep sleep mode and disconnects from host. + * + * @param client The diagnostics_relay client + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, + * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, + * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the + * request + */ +LIBIMOBILEDEVICE_API diagnostics_relay_error_t diagnostics_relay_sleep(diagnostics_relay_client_t client); + +/** + * Restart the device and optionally show a user notification. + * + * @param client The diagnostics_relay client + * @param flags A binary flag combination of + * DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT to wait until + * diagnostics_relay_client_free() disconnects before execution and + * DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_FAIL to show a "FAIL" dialog + * or DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_PASS to show an "OK" dialog + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, + * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, + * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the + * request + */ +LIBIMOBILEDEVICE_API diagnostics_relay_error_t diagnostics_relay_restart(diagnostics_relay_client_t client, diagnostics_relay_action_t flags); + +/** + * Shutdown of the device and optionally show a user notification. + * + * @param client The diagnostics_relay client + * @param flags A binary flag combination of + * DIAGNOSTICS_RELAY_ACTION_FLAG_WAIT_FOR_DISCONNECT to wait until + * diagnostics_relay_client_free() disconnects before execution and + * DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_FAIL to show a "FAIL" dialog + * or DIAGNOSTICS_RELAY_ACTION_FLAG_DISPLAY_PASS to show an "OK" dialog + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, + * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, + * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the + * request + */ +LIBIMOBILEDEVICE_API diagnostics_relay_error_t diagnostics_relay_shutdown(diagnostics_relay_client_t client, diagnostics_relay_action_t flags); + +/** + * Request diagnostics information for a given type. + * + * @param client The diagnostics_relay client + * @param type The type or domain to query for diagnostics. Some known values + * are "All", "WiFi", "GasGauge", and "NAND". + * @param diagnostics A pointer to plist_t that will receive the diagnostics information. + * The consumer has to free the allocated memory with plist_free() when no longer needed. + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, + * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, + * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the + * request + */ +LIBIMOBILEDEVICE_API diagnostics_relay_error_t diagnostics_relay_request_diagnostics(diagnostics_relay_client_t client, const char* type, plist_t* diagnostics); + +/** + * Query one or multiple MobileGestalt keys. + * + * @param client The diagnostics_relay client + * @param keys A PLIST_ARRAY with the keys to query. + * @param result A pointer to plist_t that will receive the result. The consumer + * has to free the allocated memory with plist_free() when no longer needed. + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, + * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, + * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the + * request + */ +LIBIMOBILEDEVICE_API diagnostics_relay_error_t diagnostics_relay_query_mobilegestalt(diagnostics_relay_client_t client, plist_t keys, plist_t* result); + +/** + * Query an IORegistry entry of a given class. + * + * @param client The diagnostics_relay client + * @param entry_name The IORegistry entry name to query. + * @param entry_class The IORegistry class to query. + * @param result A pointer to plist_t that will receive the result. The consumer + * has to free the allocated memory with plist_free() when no longer needed. + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, + * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, + * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the + * request + */ +LIBIMOBILEDEVICE_API diagnostics_relay_error_t diagnostics_relay_query_ioregistry_entry(diagnostics_relay_client_t client, const char* entry_name, const char* entry_class, plist_t* result); + +/** + * Query an IORegistry plane. + * + * @param client The diagnostics_relay client + * @param plane The IORegistry plane name to query. + * @param result A pointer to plist_t that will receive the result. The consumer + * has to free the allocated memory with plist_free() when no longer needed. + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, + * DIAGNOSTICS_RELAY_E_INVALID_ARG when client is NULL, + * DIAGNOSTICS_RELAY_E_PLIST_ERROR if the device did not acknowledge the + * request + */ +LIBIMOBILEDEVICE_API diagnostics_relay_error_t diagnostics_relay_query_ioregistry_plane(diagnostics_relay_client_t client, const char* plane, plist_t* result); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/file_relay.h b/include/libimobiledevice/file_relay.h index 52d4758..00773b8 100644 --- a/include/libimobiledevice/file_relay.h +++ b/include/libimobiledevice/file_relay.h @@ -3,6 +3,8 @@ * @brief Retrieve compressed CPIO archives. * \internal * + * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. + * Copyright (c) 2014 Aaron Burghardt All Rights Reserved. * Copyright (c) 2010 Nikias Bassen All Rights Reserved. * * This library is free software; you can redistribute it and/or @@ -28,29 +30,134 @@ extern "C" { #endif #include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> -/** @name Error Codes */ -/*@{*/ -#define FILE_RELAY_E_SUCCESS 0 -#define FILE_RELAY_E_INVALID_ARG -1 -#define FILE_RELAY_E_PLIST_ERROR -2 -#define FILE_RELAY_E_MUX_ERROR -3 -#define FILE_RELAY_E_INVALID_SOURCE -4 -#define FILE_RELAY_E_STAGING_EMPTY -5 +/** Service identifier passed to lockdownd_start_service() to start the file relay service */ +#define FILE_RELAY_SERVICE_NAME "com.apple.mobile.file_relay" -#define FILE_RELAY_E_UNKNOWN_ERROR -256 -/*@}*/ +/** Error Codes */ +typedef enum { + FILE_RELAY_E_SUCCESS = 0, + FILE_RELAY_E_INVALID_ARG = -1, + FILE_RELAY_E_PLIST_ERROR = -2, + FILE_RELAY_E_MUX_ERROR = -3, + FILE_RELAY_E_INVALID_SOURCE = -4, + FILE_RELAY_E_STAGING_EMPTY = -5, + FILE_RELAY_E_PERMISSION_DENIED = -6, + FILE_RELAY_E_UNKNOWN_ERROR = -256 +} file_relay_error_t; -/** Represents an error code. */ -typedef int16_t file_relay_error_t; - -typedef struct file_relay_client_private file_relay_client_private; +typedef struct file_relay_client_private file_relay_client_private; /**< \private */ typedef file_relay_client_private *file_relay_client_t; /**< The client handle. */ -file_relay_error_t file_relay_client_new(idevice_t device, uint16_t port, file_relay_client_t *client); -file_relay_error_t file_relay_client_free(file_relay_client_t client); +/** + * Connects to the file_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 + * 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. + */ +LIBIMOBILEDEVICE_API file_relay_error_t file_relay_client_new(idevice_t device, lockdownd_service_descriptor_t service, file_relay_client_t *client); + +/** + * Starts a new file_relay service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * file_relay_client_t upon successful return. Must be freed using + * file_relay_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return FILE_RELAY_E_SUCCESS on success, or an FILE_RELAY_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API file_relay_error_t file_relay_client_start_service(idevice_t device, file_relay_client_t* client, const char* label); + +/** + * Disconnects a file_relay client from the device and frees up the file_relay + * client data. + * + * @param client The file_relay client to disconnect and free. + * + * @return FILE_RELAY_E_SUCCESS on success, + * FILE_RELAY_E_INVALID_ARG when one of client or client->parent + * is invalid, or FILE_RELAY_E_UNKNOWN_ERROR when the was an error + * freeing the parent property_list_service client. + */ +LIBIMOBILEDEVICE_API file_relay_error_t file_relay_client_free(file_relay_client_t client); + -file_relay_error_t file_relay_request_sources(file_relay_client_t client, const char **sources, idevice_connection_t *connection); +/** + * Request data for the given sources. + * + * @param client The connected file_relay client. + * @param sources A NULL-terminated list of sources to retrieve. + * Valid sources are: + * - AppleSupport + * - Network + * - VPN + * - WiFi + * - UserDatabases + * - CrashReporter + * - tmp + * - SystemConfiguration + * @param connection The connection that has to be used for receiving the + * data using idevice_connection_receive(). The connection will be closed + * automatically by the device, but use file_relay_client_free() to clean + * up properly. + * + * @note WARNING: Don't call this function without reading the data afterwards. + * A directory mobile_file_relay.XXXX used for creating the archive will + * remain in the /tmp directory otherwise. + * + * @return FILE_RELAY_E_SUCCESS on succes, FILE_RELAY_E_INVALID_ARG when one or + * more parameters are invalid, FILE_RELAY_E_MUX_ERROR if a communication + * error occurs, FILE_RELAY_E_PLIST_ERROR when the received result is NULL + * or is not a valid plist, FILE_RELAY_E_INVALID_SOURCE if one or more + * sources are invalid, FILE_RELAY_E_STAGING_EMPTY if no data is available + * for the given sources, or FILE_RELAY_E_UNKNOWN_ERROR otherwise. + */ +LIBIMOBILEDEVICE_API file_relay_error_t file_relay_request_sources(file_relay_client_t client, const char **sources, idevice_connection_t *connection); + +/** + * Request data for the given sources. Calls file_relay_request_sources_timeout() with + * a timeout of 60000 milliseconds (60 seconds). + * + * @param client The connected file_relay client. + * @param sources A NULL-terminated list of sources to retrieve. + * Valid sources are: + * - AppleSupport + * - Network + * - VPN + * - WiFi + * - UserDatabases + * - CrashReporter + * - tmp + * - SystemConfiguration + * @param connection The connection that has to be used for receiving the + * data using idevice_connection_receive(). The connection will be closed + * automatically by the device, but use file_relay_client_free() to clean + * up properly. + * @param timeout Maximum time in milliseconds to wait for data. + * + * @note WARNING: Don't call this function without reading the data afterwards. + * A directory mobile_file_relay.XXXX used for creating the archive will + * remain in the /tmp directory otherwise. + * + * @return FILE_RELAY_E_SUCCESS on succes, FILE_RELAY_E_INVALID_ARG when one or + * more parameters are invalid, FILE_RELAY_E_MUX_ERROR if a communication + * error occurs, FILE_RELAY_E_PLIST_ERROR when the received result is NULL + * or is not a valid plist, FILE_RELAY_E_INVALID_SOURCE if one or more + * sources are invalid, FILE_RELAY_E_STAGING_EMPTY if no data is available + * for the given sources, or FILE_RELAY_E_UNKNOWN_ERROR otherwise. + */ +LIBIMOBILEDEVICE_API file_relay_error_t file_relay_request_sources_timeout(file_relay_client_t client, const char **sources, idevice_connection_t *connection, unsigned int timeout); #ifdef __cplusplus } diff --git a/include/libimobiledevice/heartbeat.h b/include/libimobiledevice/heartbeat.h new file mode 100644 index 0000000..4074b8b --- /dev/null +++ b/include/libimobiledevice/heartbeat.h @@ -0,0 +1,137 @@ +/** + * @file libimobiledevice/heartbeat.h + * @brief Send "heartbeat" to device to allow service connections over network. + * \internal + * + * Copyright (c) 2013-2014 Martin Szulecki All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IHEARTBEAT_H +#define IHEARTBEAT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +/** Service identifier passed to lockdownd_start_service() to start the heartbeat service */ +#define HEARTBEAT_SERVICE_NAME "com.apple.mobile.heartbeat" + +/** Error Codes */ +typedef enum { + HEARTBEAT_E_SUCCESS = 0, + HEARTBEAT_E_INVALID_ARG = -1, + HEARTBEAT_E_PLIST_ERROR = -2, + HEARTBEAT_E_MUX_ERROR = -3, + HEARTBEAT_E_SSL_ERROR = -4, + HEARTBEAT_E_NOT_ENOUGH_DATA = -5, + HEARTBEAT_E_TIMEOUT = -6, + HEARTBEAT_E_UNKNOWN_ERROR = -256 +} heartbeat_error_t; + +typedef struct heartbeat_client_private heartbeat_client_private; /**< \private */ +typedef heartbeat_client_private *heartbeat_client_t; /**< The client handle. */ + +/** + * Connects to the heartbeat 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 + * heartbeat_client_t upon successful return. Must be freed using + * heartbeat_client_free() after use. + * + * @return HEARTBEAT_E_SUCCESS on success, HEARTBEAT_E_INVALID_ARG when + * client is NULL, or an HEARTBEAT_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API heartbeat_error_t heartbeat_client_new(idevice_t device, lockdownd_service_descriptor_t service, heartbeat_client_t * client); + +/** + * Starts a new heartbeat service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * heartbeat_client_t upon successful return. Must be freed using + * heartbeat_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return HEARTBEAT_E_SUCCESS on success, or an HEARTBEAT_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API heartbeat_error_t heartbeat_client_start_service(idevice_t device, heartbeat_client_t * client, const char* label); + +/** + * Disconnects a heartbeat client from the device and frees up the + * heartbeat client data. + * + * @param client The heartbeat client to disconnect and free. + * + * @return HEARTBEAT_E_SUCCESS on success, HEARTBEAT_E_INVALID_ARG when + * client is NULL, or an HEARTBEAT_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API heartbeat_error_t heartbeat_client_free(heartbeat_client_t client); + + +/** + * Sends a plist to the service. + * + * @param client The heartbeat client + * @param plist The plist to send + * + * @return HEARTBEAT_E_SUCCESS on success, + * HEARTBEAT_E_INVALID_ARG when client or plist is NULL + */ +LIBIMOBILEDEVICE_API heartbeat_error_t heartbeat_send(heartbeat_client_t client, plist_t plist); + +/** + * Receives a plist from the service. + * + * @param client The heartbeat client + * @param plist The plist to store the received data + * + * @return HEARTBEAT_E_SUCCESS on success, + * HEARTBEAT_E_INVALID_ARG when client or plist is NULL + */ +LIBIMOBILEDEVICE_API heartbeat_error_t heartbeat_receive(heartbeat_client_t client, plist_t * plist); + +/** + * Receives a plist using the given heartbeat client. + * + * @param client The heartbeat client to use for receiving + * @param plist pointer to a plist_t that will point to the received plist + * upon successful return + * @param timeout_ms Maximum time in milliseconds to wait for data. + * + * @return HEARTBEAT_E_SUCCESS on success, + * HEARTBEAT_E_INVALID_ARG when client or *plist is NULL, + * HEARTBEAT_E_NOT_ENOUGH_DATA when not enough data + * received, HEARTBEAT_E_TIMEOUT when the connection times out, + * HEARTBEAT_E_PLIST_ERROR when the received data cannot be + * converted to a plist, HEARTBEAT_E_MUX_ERROR when a + * communication error occurs, or HEARTBEAT_E_UNKNOWN_ERROR + * when an unspecified error occurs. + */ +LIBIMOBILEDEVICE_API heartbeat_error_t heartbeat_receive_with_timeout(heartbeat_client_t client, plist_t * plist, uint32_t timeout_ms); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/house_arrest.h b/include/libimobiledevice/house_arrest.h index 04290f1..f9ba68a 100644 --- a/include/libimobiledevice/house_arrest.h +++ b/include/libimobiledevice/house_arrest.h @@ -1,8 +1,9 @@ /** * @file libimobiledevice/house_arrest.h - * @brief Access AppStore application folders and their contents. + * @brief Access app folders and their contents. * \internal * + * Copyright (c) 2013-2014 Martin Szulecki All Rights Reserved. * Copyright (c) 2010 Nikias Bassen, All Rights Reserved. * * This library is free software; you can redistribute it and/or @@ -20,42 +21,157 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef HOUSE_ARREST_H -#define HOUSE_ARREST_H +#ifndef IHOUSE_ARREST_H +#define IHOUSE_ARREST_H #ifdef __cplusplus extern "C" { #endif #include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> #include <libimobiledevice/afc.h> -/** @name Error Codes */ -/*@{*/ -#define HOUSE_ARREST_E_SUCCESS 0 -#define HOUSE_ARREST_E_INVALID_ARG -1 -#define HOUSE_ARREST_E_PLIST_ERROR -2 -#define HOUSE_ARREST_E_CONN_FAILED -3 -#define HOUSE_ARREST_E_INVALID_MODE -4 +/** Service identifier passed to lockdownd_start_service() to start the house arrest service */ +#define HOUSE_ARREST_SERVICE_NAME "com.apple.mobile.house_arrest" -#define HOUSE_ARREST_E_UNKNOWN_ERROR -256 -/*@}*/ +/** Error Codes */ +typedef enum { + HOUSE_ARREST_E_SUCCESS = 0, + HOUSE_ARREST_E_INVALID_ARG = -1, + HOUSE_ARREST_E_PLIST_ERROR = -2, + HOUSE_ARREST_E_CONN_FAILED = -3, + HOUSE_ARREST_E_INVALID_MODE = -4, + HOUSE_ARREST_E_UNKNOWN_ERROR = -256 +} house_arrest_error_t; -/** Represents an error code. */ -typedef int16_t house_arrest_error_t; - -typedef struct house_arrest_client_private house_arrest_client_private; +typedef struct house_arrest_client_private house_arrest_client_private; /**< \private */ typedef house_arrest_client_private *house_arrest_client_t; /**< The client handle. */ /* Interface */ -house_arrest_error_t house_arrest_client_new(idevice_t device, uint16_t port, house_arrest_client_t *client); -house_arrest_error_t house_arrest_client_free(house_arrest_client_t client); -house_arrest_error_t house_arrest_send_request(house_arrest_client_t client, plist_t dict); -house_arrest_error_t house_arrest_send_command(house_arrest_client_t client, const char *command, const char *appid); -house_arrest_error_t house_arrest_get_result(house_arrest_client_t client, plist_t *dict); +/** + * 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. + */ +LIBIMOBILEDEVICE_API house_arrest_error_t house_arrest_client_new(idevice_t device, lockdownd_service_descriptor_t service, house_arrest_client_t *client); + +/** + * Starts a new house_arrest service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * house_arrest_client_t upon successful return. Must be freed using + * house_arrest_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return HOUSE_ARREST_E_SUCCESS on success, or an HOUSE_ARREST_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API house_arrest_error_t house_arrest_client_start_service(idevice_t device, house_arrest_client_t* client, const char* label); + +/** + * Disconnects an house_arrest client from the device and frees up the + * house_arrest client data. + * + * @note After using afc_client_new_from_house_arrest_client(), make sure + * you call afc_client_free() before calling this function to ensure + * a proper cleanup. Do not call this function if you still need to + * perform AFC operations since it will close the connection. + * + * @param client The house_arrest client to disconnect and free. + * + * @return HOUSE_ARREST_E_SUCCESS on success, HOUSE_ARREST_E_INVALID_ARG when + * client is NULL, or an HOUSE_ARREST_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API house_arrest_error_t house_arrest_client_free(house_arrest_client_t client); + + +/** + * Sends a generic request to the connected house_arrest service. + * + * @param client The house_arrest client to use. + * @param dict The request to send as a plist of type PLIST_DICT. + * + * @note If this function returns HOUSE_ARREST_E_SUCCESS it does not mean + * that the request was successful. To check for success or failure you + * need to call house_arrest_get_result(). + * @see house_arrest_get_result + * + * @return HOUSE_ARREST_E_SUCCESS if the request was successfully sent, + * HOUSE_ARREST_E_INVALID_ARG if client or dict is invalid, + * HOUSE_ARREST_E_PLIST_ERROR if dict is not a plist of type PLIST_DICT, + * HOUSE_ARREST_E_INVALID_MODE if the client is not in the correct mode, + * or HOUSE_ARREST_E_CONN_FAILED if a connection error occurred. + */ +LIBIMOBILEDEVICE_API house_arrest_error_t house_arrest_send_request(house_arrest_client_t client, plist_t dict); + +/** + * Send a command to the connected house_arrest service. + * Calls house_arrest_send_request() internally. + * + * @param client The house_arrest client to use. + * @param command The command to send. Currently, only VendContainer and + * VendDocuments are known. + * @param appid The application identifier to pass along with the . + * + * @note If this function returns HOUSE_ARREST_E_SUCCESS it does not mean + * that the command was successful. To check for success or failure you + * need to call house_arrest_get_result(). + * @see house_arrest_get_result + * + * @return HOUSE_ARREST_E_SUCCESS if the command was successfully sent, + * HOUSE_ARREST_E_INVALID_ARG if client, command, or appid is invalid, + * HOUSE_ARREST_E_INVALID_MODE if the client is not in the correct mode, + * or HOUSE_ARREST_E_CONN_FAILED if a connection error occurred. + */ +LIBIMOBILEDEVICE_API house_arrest_error_t house_arrest_send_command(house_arrest_client_t client, const char *command, const char *appid); + +/** + * Retrieves the result of a previously sent house_arrest_request_* request. + * + * @param client The house_arrest client to use + * @param dict Pointer that will be set to a plist containing the result to + * the last performed operation. It holds a key 'Status' with the value + * 'Complete' on success or a key 'Error' with an error description as + * value. The caller is responsible for freeing the returned plist. + * + * @return HOUSE_ARREST_E_SUCCESS if a result plist was retrieved, + * HOUSE_ARREST_E_INVALID_ARG if client is invalid, + * HOUSE_ARREST_E_INVALID_MODE if the client is not in the correct mode, + * or HOUSE_ARREST_E_CONN_FAILED if a connection error occurred. + */ +LIBIMOBILEDEVICE_API house_arrest_error_t house_arrest_get_result(house_arrest_client_t client, plist_t *dict); + -afc_error_t afc_client_new_from_house_arrest_client(house_arrest_client_t client, afc_client_t *afc_client); +/** + * Creates an AFC client using the given house_arrest client's connection + * allowing file access to a specific application directory requested by + * functions like house_arrest_request_vendor_documents(). + * + * @param client The house_arrest client to use. + * @param afc_client Pointer that will be set to a newly allocated afc_client_t + * upon successful return. + * + * @note After calling this function the house_arrest client will go in an + * AFC mode that will only allow calling house_arrest_client_free(). + * Only call house_arrest_client_free() if all AFC operations have + * completed since it will close the connection. + * + * @return AFC_E_SUCCESS if the afc client was successfully created, + * AFC_E_INVALID_ARG if client is invalid or was already used to create + * an afc client, or an AFC_E_* error code returned by + * afc_client_new_with_service_client(). + */ +LIBIMOBILEDEVICE_API afc_error_t afc_client_new_from_house_arrest_client(house_arrest_client_t client, afc_client_t *afc_client); #ifdef __cplusplus } diff --git a/include/libimobiledevice/installation_proxy.h b/include/libimobiledevice/installation_proxy.h index f5f00e8..44331aa 100644 --- a/include/libimobiledevice/installation_proxy.h +++ b/include/libimobiledevice/installation_proxy.h @@ -3,7 +3,10 @@ * @brief Manage applications on a device. * \internal * - * Copyright (c) 2009 Nikias Bassen All Rights Reserved. + * Copyright (c) 2010-2015 Martin Szulecki All Rights Reserved. + * Copyright (c) 2014 Christophe Fergeau All Rights Reserved. + * Copyright (c) 2009-2012 Nikias Bassen All Rights Reserved. + * Copyright (c) 2010 Bryan Forbes All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,54 +23,480 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef INSTALLATION_PROXY_H -#define INSTALLATION_PROXY_H +#ifndef IINSTALLATION_PROXY_H +#define IINSTALLATION_PROXY_H #ifdef __cplusplus extern "C" { #endif #include <libimobiledevice/libimobiledevice.h> -#include <glib.h> +#include <libimobiledevice/lockdown.h> -/** @name Error Codes */ -/*@{*/ -#define INSTPROXY_E_SUCCESS 0 -#define INSTPROXY_E_INVALID_ARG -1 -#define INSTPROXY_E_PLIST_ERROR -2 -#define INSTPROXY_E_CONN_FAILED -3 -#define INSTPROXY_E_OP_IN_PROGRESS -4 -#define INSTPROXY_E_OP_FAILED -5 +/** Service identifier passed to lockdownd_start_service() to start the installation proxy service */ +#define INSTPROXY_SERVICE_NAME "com.apple.mobile.installation_proxy" -#define INSTPROXY_E_UNKNOWN_ERROR -256 -/*@}*/ +/** Error Codes */ +typedef enum { + /* custom */ + INSTPROXY_E_SUCCESS = 0, + INSTPROXY_E_INVALID_ARG = -1, + INSTPROXY_E_PLIST_ERROR = -2, + INSTPROXY_E_CONN_FAILED = -3, + INSTPROXY_E_OP_IN_PROGRESS = -4, + INSTPROXY_E_OP_FAILED = -5, + INSTPROXY_E_RECEIVE_TIMEOUT = -6, + /* native */ + INSTPROXY_E_ALREADY_ARCHIVED = -7, + INSTPROXY_E_API_INTERNAL_ERROR = -8, + INSTPROXY_E_APPLICATION_ALREADY_INSTALLED = -9, + INSTPROXY_E_APPLICATION_MOVE_FAILED = -10, + INSTPROXY_E_APPLICATION_SINF_CAPTURE_FAILED = -11, + INSTPROXY_E_APPLICATION_SANDBOX_FAILED = -12, + INSTPROXY_E_APPLICATION_VERIFICATION_FAILED = -13, + INSTPROXY_E_ARCHIVE_DESTRUCTION_FAILED = -14, + INSTPROXY_E_BUNDLE_VERIFICATION_FAILED = -15, + INSTPROXY_E_CARRIER_BUNDLE_COPY_FAILED = -16, + INSTPROXY_E_CARRIER_BUNDLE_DIRECTORY_CREATION_FAILED = -17, + INSTPROXY_E_CARRIER_BUNDLE_MISSING_SUPPORTED_SIMS = -18, + INSTPROXY_E_COMM_CENTER_NOTIFICATION_FAILED = -19, + INSTPROXY_E_CONTAINER_CREATION_FAILED = -20, + INSTPROXY_E_CONTAINER_P0WN_FAILED = -21, + INSTPROXY_E_CONTAINER_REMOVAL_FAILED = -22, + INSTPROXY_E_EMBEDDED_PROFILE_INSTALL_FAILED = -23, + INSTPROXY_E_EXECUTABLE_TWIDDLE_FAILED = -24, + INSTPROXY_E_EXISTENCE_CHECK_FAILED = -25, + INSTPROXY_E_INSTALL_MAP_UPDATE_FAILED = -26, + INSTPROXY_E_MANIFEST_CAPTURE_FAILED = -27, + INSTPROXY_E_MAP_GENERATION_FAILED = -28, + INSTPROXY_E_MISSING_BUNDLE_EXECUTABLE = -29, + INSTPROXY_E_MISSING_BUNDLE_IDENTIFIER = -30, + INSTPROXY_E_MISSING_BUNDLE_PATH = -31, + INSTPROXY_E_MISSING_CONTAINER = -32, + INSTPROXY_E_NOTIFICATION_FAILED = -33, + INSTPROXY_E_PACKAGE_EXTRACTION_FAILED = -34, + INSTPROXY_E_PACKAGE_INSPECTION_FAILED = -35, + INSTPROXY_E_PACKAGE_MOVE_FAILED = -36, + INSTPROXY_E_PATH_CONVERSION_FAILED = -37, + INSTPROXY_E_RESTORE_CONTAINER_FAILED = -38, + INSTPROXY_E_SEATBELT_PROFILE_REMOVAL_FAILED = -39, + INSTPROXY_E_STAGE_CREATION_FAILED = -40, + INSTPROXY_E_SYMLINK_FAILED = -41, + INSTPROXY_E_UNKNOWN_COMMAND = -42, + INSTPROXY_E_ITUNES_ARTWORK_CAPTURE_FAILED = -43, + INSTPROXY_E_ITUNES_METADATA_CAPTURE_FAILED = -44, + INSTPROXY_E_DEVICE_OS_VERSION_TOO_LOW = -45, + INSTPROXY_E_DEVICE_FAMILY_NOT_SUPPORTED = -46, + INSTPROXY_E_PACKAGE_PATCH_FAILED = -47, + INSTPROXY_E_INCORRECT_ARCHITECTURE = -48, + INSTPROXY_E_PLUGIN_COPY_FAILED = -49, + INSTPROXY_E_BREADCRUMB_FAILED = -50, + INSTPROXY_E_BREADCRUMB_UNLOCK_FAILED = -51, + INSTPROXY_E_GEOJSON_CAPTURE_FAILED = -52, + INSTPROXY_E_NEWSSTAND_ARTWORK_CAPTURE_FAILED = -53, + INSTPROXY_E_MISSING_COMMAND = -54, + INSTPROXY_E_NOT_ENTITLED = -55, + INSTPROXY_E_MISSING_PACKAGE_PATH = -56, + INSTPROXY_E_MISSING_CONTAINER_PATH = -57, + INSTPROXY_E_MISSING_APPLICATION_IDENTIFIER = -58, + INSTPROXY_E_MISSING_ATTRIBUTE_VALUE = -59, + INSTPROXY_E_LOOKUP_FAILED = -60, + INSTPROXY_E_DICT_CREATION_FAILED = -61, + INSTPROXY_E_INSTALL_PROHIBITED = -62, + INSTPROXY_E_UNINSTALL_PROHIBITED = -63, + INSTPROXY_E_MISSING_BUNDLE_VERSION = -64, + INSTPROXY_E_UNKNOWN_ERROR = -256 +} instproxy_error_t; -/** Represents an error code. */ -typedef int16_t instproxy_error_t; - -typedef struct instproxy_client_private instproxy_client_private; +typedef struct instproxy_client_private instproxy_client_private; /**< \private */ typedef instproxy_client_private *instproxy_client_t; /**< The client handle. */ -/** Reports the status of the given operation */ -typedef void (*instproxy_status_cb_t) (const char *operation, plist_t status, void *user_data); +/** Reports the status response of the given command */ +typedef void (*instproxy_status_cb_t) (plist_t command, plist_t status, void *user_data); /* Interface */ -instproxy_error_t instproxy_client_new(idevice_t device, uint16_t port, instproxy_client_t *client); -instproxy_error_t instproxy_client_free(instproxy_client_t client); - -instproxy_error_t instproxy_browse(instproxy_client_t client, plist_t client_options, plist_t *result); -instproxy_error_t instproxy_install(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); -instproxy_error_t instproxy_upgrade(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); -instproxy_error_t instproxy_uninstall(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); - -instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist_t client_options, plist_t *result); -instproxy_error_t instproxy_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); -instproxy_error_t instproxy_restore(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); -instproxy_error_t instproxy_remove_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); - -plist_t instproxy_client_options_new(); -void instproxy_client_options_add(plist_t client_options, ...) G_GNUC_NULL_TERMINATED; -void instproxy_client_options_free(plist_t client_options); + +/** + * 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 occurred. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_client_new(idevice_t device, lockdownd_service_descriptor_t service, instproxy_client_t *client); + +/** + * Starts a new installation_proxy service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * instproxy_client_t upon successful return. Must be freed using + * instproxy_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return INSTPROXY_E_SUCCESS on success, or an INSTPROXY_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_client_start_service(idevice_t device, instproxy_client_t * client, const char* label); + +/** + * Disconnects an installation_proxy client from the device and frees up the + * installation_proxy client data. + * + * @param client The installation_proxy client to disconnect and free. + * + * @return INSTPROXY_E_SUCCESS on success + * or INSTPROXY_E_INVALID_ARG if client is NULL. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_client_free(instproxy_client_t client); + +/** + * List installed applications. This function runs synchronously. + * + * @param client The connected installation_proxy client + * @param client_options The client options to use, as PLIST_DICT, or NULL. + * Valid client options include: + * "ApplicationType" -> "System" + * "ApplicationType" -> "User" + * "ApplicationType" -> "Internal" + * "ApplicationType" -> "Any" + * @param result Pointer that will be set to a plist that will hold an array + * of PLIST_DICT holding information about the applications found. + * + * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if + * an error occurred. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_browse(instproxy_client_t client, plist_t client_options, plist_t *result); + +/** + * List pages of installed applications in a callback. + * + * @param client The connected installation_proxy client + * @param client_options The client options to use, as PLIST_DICT, or NULL. + * Valid client options include: + * "ApplicationType" -> "System" + * "ApplicationType" -> "User" + * "ApplicationType" -> "Internal" + * "ApplicationType" -> "Any" + * @param status_cb Callback function to process each page of application + * information. Passing a callback is required. + * @param user_data Callback data passed to status_cb. + * + * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if + * an error occurred. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_browse_with_callback(instproxy_client_t client, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); + +/** + * Lookup information about specific applications from the device. + * + * @param client The connected installation_proxy client + * @param appids An array of bundle identifiers that MUST have a terminating + * NULL entry or NULL to lookup all. + * @param client_options The client options to use, as PLIST_DICT, or NULL. + * Currently there are no known client options, so pass NULL here. + * @param result Pointer that will be set to a plist containing a PLIST_DICT + * holding requested information about the application or NULL on errors. + * + * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if + * an error occurred. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_lookup(instproxy_client_t client, const char** appids, plist_t client_options, plist_t *result); + +/** + * Install an application on the device. + * + * @param client The connected installation_proxy client + * @param pkg_path Path of the installation package (inside the AFC jail) + * @param client_options The client options to use, as PLIST_DICT, or NULL. + * Valid options include: + * "iTunesMetadata" -> PLIST_DATA + * "ApplicationSINF" -> PLIST_DATA + * "PackageType" -> "Developer" + * If PackageType -> Developer is specified, then pkg_path points to + * an .app directory instead of an install package. + * @param status_cb Callback function for progress and status information. If + * NULL is passed, this function will run synchronously. + * @param user_data Callback data passed to status_cb. + * + * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if + * an error occurred. + * + * @note If a callback function is given (async mode), this function returns + * INSTPROXY_E_SUCCESS immediately if the status updater thread has been + * created successfully; any error occurring during the command has to be + * handled inside the specified callback function. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_install(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); + +/** + * Upgrade an application on the device. This function is nearly the same as + * instproxy_install; the difference is that the installation progress on the + * device is faster if the application is already installed. + * + * @param client The connected installation_proxy client + * @param pkg_path Path of the installation package (inside the AFC jail) + * @param client_options The client options to use, as PLIST_DICT, or NULL. + * Valid options include: + * "iTunesMetadata" -> PLIST_DATA + * "ApplicationSINF" -> PLIST_DATA + * "PackageType" -> "Developer" + * If PackageType -> Developer is specified, then pkg_path points to + * an .app directory instead of an install package. + * @param status_cb Callback function for progress and status information. If + * NULL is passed, this function will run synchronously. + * @param user_data Callback data passed to status_cb. + * + * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if + * an error occurred. + * + * @note If a callback function is given (async mode), this function returns + * INSTPROXY_E_SUCCESS immediately if the status updater thread has been + * created successfully; any error occurring during the command has to be + * handled inside the specified callback function. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_upgrade(instproxy_client_t client, const char *pkg_path, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); + +/** + * Uninstall an application from the device. + * + * @param client The connected installation proxy client + * @param appid ApplicationIdentifier of the app to uninstall + * @param client_options The client options to use, as PLIST_DICT, or NULL. + * Currently there are no known client options, so pass NULL here. + * @param status_cb Callback function for progress and status information. If + * NULL is passed, this function will run synchronously. + * @param user_data Callback data passed to status_cb. + * + * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if + * an error occurred. + * + * @note If a callback function is given (async mode), this function returns + * INSTPROXY_E_SUCCESS immediately if the status updater thread has been + * created successfully; any error occurring during the command has to be + * handled inside the specified callback function. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_uninstall(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); + +/** + * List archived applications. This function runs synchronously. + * + * @see instproxy_archive + * + * @param client The connected installation_proxy client + * @param client_options The client options to use, as PLIST_DICT, or NULL. + * Currently there are no known client options, so pass NULL here. + * @param result Pointer that will be set to a plist containing a PLIST_DICT + * holding information about the archived applications found. + * + * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if + * an error occurred. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_lookup_archives(instproxy_client_t client, plist_t client_options, plist_t *result); + +/** + * Archive an application on the device. + * This function tells the device to make an archive of the specified + * application. This results in the device creating a ZIP archive in the + * 'ApplicationArchives' directory and uninstalling the application. + * + * @param client The connected installation proxy client + * @param appid ApplicationIdentifier of the app to archive. + * @param client_options The client options to use, as PLIST_DICT, or NULL. + * Valid options include: + * "SkipUninstall" -> Boolean + * "ArchiveType" -> "ApplicationOnly" + * @param status_cb Callback function for progress and status information. If + * NULL is passed, this function will run synchronously. + * @param user_data Callback data passed to status_cb. + * + * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if + * an error occurred. + * + * @note If a callback function is given (async mode), this function returns + * INSTPROXY_E_SUCCESS immediately if the status updater thread has been + * created successfully; any error occurring during the command has to be + * handled inside the specified callback function. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); + +/** + * Restore a previously archived application on the device. + * This function is the counterpart to instproxy_archive. + * @see instproxy_archive + * + * @param client The connected installation proxy client + * @param appid ApplicationIdentifier of the app to restore. + * @param client_options The client options to use, as PLIST_DICT, or NULL. + * Valid options include: + * "ArchiveType" -> "DocumentsOnly" + * @param status_cb Callback function for progress and status information. If + * NULL is passed, this function will run synchronously. + * @param user_data Callback data passed to status_cb. + * + * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if + * an error occurred. + * + * @note If a callback function is given (async mode), this function returns + * INSTPROXY_E_SUCCESS immediately if the status updater thread has been + * created successfully; any error occurring during the command has to be + * handled inside the specified callback function. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_restore(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); + +/** + * Removes a previously archived application from the device. + * This function removes the ZIP archive from the 'ApplicationArchives' + * directory. + * + * @param client The connected installation proxy client + * @param appid ApplicationIdentifier of the archived app to remove. + * @param client_options The client options to use, as PLIST_DICT, or NULL. + * Currently there are no known client options, so passing NULL is fine. + * @param status_cb Callback function for progress and status information. If + * NULL is passed, this function will run synchronously. + * @param user_data Callback data passed to status_cb. + * + * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if + * an error occurred. + * + * @note If a callback function is given (async mode), this function returns + * INSTPROXY_E_SUCCESS immediately if the status updater thread has been + * created successfully; any error occurring during the command has to be + * handled inside the specified callback function. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_remove_archive(instproxy_client_t client, const char *appid, plist_t client_options, instproxy_status_cb_t status_cb, void *user_data); + +/** + * Checks a device for certain capabilities. + * + * @param client The connected installation_proxy client + * @param capabilities An array of char* with capability names that MUST have a + * terminating NULL entry. + * @param client_options The client options to use, as PLIST_DICT, or NULL. + * Currently there are no known client options, so pass NULL here. + * @param result Pointer that will be set to a plist containing a PLIST_DICT + * holding information if the capabilities matched or NULL on errors. + * + * @return INSTPROXY_E_SUCCESS on success or an INSTPROXY_E_* error value if + * an error occurred. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_check_capabilities_match(instproxy_client_t client, const char** capabilities, plist_t client_options, plist_t *result); + +/* Helper */ + +/** + * Gets the name from a command dictionary. + * + * @param command The dictionary describing the command. + * @param name Pointer to store the name of the command. + */ +LIBIMOBILEDEVICE_API void instproxy_command_get_name(plist_t command, char** name); + +/** + * Gets the name of a status. + * + * @param status The dictionary status response to use. + * @param name Pointer to store the name of the status. + */ +LIBIMOBILEDEVICE_API void instproxy_status_get_name(plist_t status, char **name); + +/** + * Gets error name, code and description from a response if available. + * + * @param status The dictionary status response to use. + * @param name Pointer to store the name of an error. + * @param description Pointer to store error description text if available. + * The caller is reponsible for freeing the allocated buffer after use. + * If NULL is passed no description will be returned. + * @param code Pointer to store the returned error code if available. + * If NULL is passed no error code will be returned. + * + * @return INSTPROXY_E_SUCCESS if no error is found or an INSTPROXY_E_* error + * value matching the error that ẃas found in the status. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_status_get_error(plist_t status, char **name, char** description, uint64_t* code); + +/** + * Gets total and current item information from a browse response if available. + * + * @param status The dictionary status response to use. + * @param total Pointer to store the total number of items. + * @param current_index Pointer to store the current index of all browsed items. + * @param current_amount Pointer to store the amount of items in the + * current list. + * @param list Pointer to store a newly allocated plist with items. + * The caller is reponsible for freeing the list after use. + * If NULL is passed no list will be returned. If NULL is returned no + * list was found in the status. + */ +LIBIMOBILEDEVICE_API void instproxy_status_get_current_list(plist_t status, uint64_t* total, uint64_t* current_index, uint64_t* current_amount, plist_t* list); + + +/** + * Gets progress in percentage from a status if available. + * + * @param status The dictionary status response to use. + * @param percent Pointer to an int to store the progress in percent (0-100) + * or -1 if no progress was found in the status. + */ +LIBIMOBILEDEVICE_API void instproxy_status_get_percent_complete(plist_t status, int *percent); + +/** + * Creates a new client_options plist. + * + * @return A new plist_t of type PLIST_DICT. + */ +LIBIMOBILEDEVICE_API plist_t instproxy_client_options_new(void); + +/** + * Adds one or more new key:value pairs to the given client_options. + * + * @param client_options The client options to modify. + * @param ... KEY, VALUE, [KEY, VALUE], NULL + * + * @note The keys and values passed are expected to be strings, except for the + * keys "ApplicationSINF", "iTunesMetadata", "ReturnAttributes" which are + * expecting a plist_t node as value and "SkipUninstall" expects int. + */ +LIBIMOBILEDEVICE_API void instproxy_client_options_add(plist_t client_options, ...); + +/** + * Adds attributes to the given client_options to filter browse results. + * + * @param client_options The client options to modify. + * @param ... VALUE, VALUE, [VALUE], NULL + * + * @note The values passed are expected to be strings. + */ +LIBIMOBILEDEVICE_API void instproxy_client_options_set_return_attributes(plist_t client_options, ...); + +/** + * Frees client_options plist. + * + * @param client_options The client options plist to free. Does nothing if NULL + * is passed. + */ +LIBIMOBILEDEVICE_API void instproxy_client_options_free(plist_t client_options); + +/** + * Queries the device for the path of an application. + * + * @param client The connected installation proxy client. + * @param bundle_id ApplicationIdentifier of app to retrieve the path for. + * @param path Pointer to store the device path for the application + * which is set to NULL if it could not be determined. + * + * @return INSTPROXY_E_SUCCESS on success, INSTPROXY_E_OP_FAILED if + * the path could not be determined or an INSTPROXY_E_* error + * value if an error occurred. + */ +LIBIMOBILEDEVICE_API instproxy_error_t instproxy_client_get_path_for_bundle_identifier(instproxy_client_t client, const char* bundle_id, char** path); #ifdef __cplusplus } diff --git a/include/libimobiledevice/libimobiledevice.h b/include/libimobiledevice/libimobiledevice.h index d0923d6..a9d270b 100644 --- a/include/libimobiledevice/libimobiledevice.h +++ b/include/libimobiledevice/libimobiledevice.h @@ -3,25 +3,28 @@ * @brief Device/Connection handling and communication * \internal * + * Copyright (c) 2010-2019 Nikias Bassen All Rights Reserved. + * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. + * Copyright (c) 2014 Christophe Fergeau All Rights Reserved. * Copyright (c) 2008 Jonathan Beck All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; either * version 2.1 of the License, or (at your option) any later version. - * + * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Lesser General Public License for more details. - * + * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef LIBIMOBILEDEVICE_H -#define LIBIMOBILEDEVICE_H +#ifndef IMOBILEDEVICE_H +#define IMOBILEDEVICE_H #ifdef __cplusplus extern "C" { @@ -32,72 +35,377 @@ extern "C" { #include <sys/stat.h> #include <plist/plist.h> -/** @name Error Codes */ -/*@{*/ -#define IDEVICE_E_SUCCESS 0 -#define IDEVICE_E_INVALID_ARG -1 -#define IDEVICE_E_UNKNOWN_ERROR -2 -#define IDEVICE_E_NO_DEVICE -3 -#define IDEVICE_E_NOT_ENOUGH_DATA -4 -#define IDEVICE_E_BAD_HEADER -5 -#define IDEVICE_E_SSL_ERROR -6 -/*@}*/ - -/** Represents an error code. */ -typedef int16_t idevice_error_t; - -typedef struct idevice_private idevice_private; +#ifndef LIBIMOBILEDEVICE_API + #ifdef LIBIMOBILEDEVICE_STATIC + #define LIBIMOBILEDEVICE_API + #elif defined(_WIN32) + #define LIBIMOBILEDEVICE_API __declspec(dllimport) + #else + #define LIBIMOBILEDEVICE_API + #endif +#endif + +/** Error Codes */ +typedef enum { + IDEVICE_E_SUCCESS = 0, + IDEVICE_E_INVALID_ARG = -1, + IDEVICE_E_UNKNOWN_ERROR = -2, + IDEVICE_E_NO_DEVICE = -3, + IDEVICE_E_NOT_ENOUGH_DATA = -4, + IDEVICE_E_CONNREFUSED = -5, + IDEVICE_E_SSL_ERROR = -6, + IDEVICE_E_TIMEOUT = -7 +} idevice_error_t; + +typedef struct idevice_private idevice_private; /**< \private */ typedef idevice_private *idevice_t; /**< The device handle. */ -typedef struct idevice_connection_private idevice_connection_private; +typedef struct idevice_connection_private idevice_connection_private; /**< \private */ typedef idevice_connection_private *idevice_connection_t; /**< The connection handle. */ -/* generic */ -void idevice_set_debug_level(int level); +/** Options for idevice_new_with_options() */ +enum idevice_options { + IDEVICE_LOOKUP_USBMUX = 1 << 1, /**< include USBMUX devices during lookup */ + IDEVICE_LOOKUP_NETWORK = 1 << 2, /**< include network devices during lookup */ + IDEVICE_LOOKUP_PREFER_NETWORK = 1 << 3 /**< prefer network connection if device is available via USBMUX *and* network */ +}; + +/** Type of connection a device is available on */ +enum idevice_connection_type { + CONNECTION_USBMUXD = 1, /**< device is available via USBMUX */ + CONNECTION_NETWORK /**< device is available via network */ +}; + +/** Device information returned by #idevice_get_device_list_extended API */ +struct idevice_info { + char *udid; /**< UDID of the device */ + enum idevice_connection_type conn_type; /**< Type of connection the device is available on */ + void* conn_data; /**< Connection data, depending on the connection type */ +}; +typedef struct idevice_info* idevice_info_t; /* discovery (events/asynchronous) */ /** The event type for device add or removal */ enum idevice_event_type { - IDEVICE_DEVICE_ADD = 1, - IDEVICE_DEVICE_REMOVE + IDEVICE_DEVICE_ADD = 1, /**< device was added */ + IDEVICE_DEVICE_REMOVE, /**< device was removed */ + IDEVICE_DEVICE_PAIRED /**< device completed pairing process */ }; /* event data structure */ -/** Provides information about the occured event. */ +/** Provides information about the occurred event. */ typedef struct { enum idevice_event_type event; /**< The event type. */ - const char *uuid; /**< The device unique id. */ - int conn_type; /**< The connection type. Currently only 1 for usbmuxd. */ + const char *udid; /**< The device unique id. */ + enum idevice_connection_type conn_type; /**< The connection type. */ } idevice_event_t; /* event callback function prototype */ /** Callback to notifiy if a device was added or removed. */ typedef void (*idevice_event_cb_t) (const idevice_event_t *event, void *user_data); +/** Event subscription context type */ +typedef struct idevice_subscription_context* idevice_subscription_context_t; + /* functions */ -idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data); -idevice_error_t idevice_event_unsubscribe(); + +/** + * Set the level of debugging. + * + * @param level Set to 0 for no debug output or 1 to enable debug output. + */ +LIBIMOBILEDEVICE_API void idevice_set_debug_level(int level); + +/** + * Subscribe a callback function that will be called when device add/remove + * events occur. + * + * @param context A pointer to a idevice_subscription_context_t that will be + * set upon creation of the subscription. The returned context must be + * passed to idevice_events_unsubscribe() to unsubscribe the callback. + * @param callback Callback function to call. + * @param user_data Application-specific data passed as parameter + * to the registered callback function. + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occurred. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_events_subscribe(idevice_subscription_context_t *context, idevice_event_cb_t callback, void *user_data); + +/** + * Unsubscribe the event callback function that has been registered with + * idevice_events_subscribe(). + * + * @param context A valid context as returned from idevice_events_subscribe(). + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occurred. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_events_unsubscribe(idevice_subscription_context_t context); + +/** + * (DEPRECATED) Register a callback function that will be called when device add/remove + * events occur. + * + * @deprecated Use idevice_events_subscribe() instead. + * + * @param callback Callback function to call. + * @param user_data Application-specific data passed as parameter + * to the registered callback function. + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occurred. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_event_subscribe(idevice_event_cb_t callback, void *user_data); + +/** + * (DEPRECATED) Release the event callback function that has been registered with + * idevice_event_subscribe(). + * + * @deprecated Use idevice_events_unsubscribe() instead. + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occurred. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_event_unsubscribe(void); /* discovery (synchronous) */ -idevice_error_t idevice_get_device_list(char ***devices, int *count); -idevice_error_t idevice_device_list_free(char **devices); + +/** + * Get a list of UDIDs of currently available devices (USBMUX devices only). + * + * @param devices List of UDIDs of devices that are currently available. + * This list is terminated by a NULL pointer. + * @param count Number of devices found. + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occurred. + * + * @note This function only returns the UDIDs of USBMUX devices. To also include + * network devices in the list, use idevice_get_device_list_extended(). + * @see idevice_get_device_list_extended + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_get_device_list(char ***devices, int *count); + +/** + * Free a list of device UDIDs. + * + * @param devices List of UDIDs to free. + * + * @return Always returnes IDEVICE_E_SUCCESS. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_device_list_free(char **devices); + +/** + * Get a list of currently available devices + * + * @param devices List of idevice_info_t records with device information. + * This list is terminated by a NULL pointer. + * @param count Number of devices included in the list. + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occurred. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_get_device_list_extended(idevice_info_t **devices, int *count); + +/** + * Free an extended device list retrieved through idevice_get_device_list_extended(). + * + * @param devices Device list to free. + * + * @return IDEVICE_E_SUCCESS on success or an error value when an error occurred. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_device_list_extended_free(idevice_info_t *devices); /* device structure creation and destruction */ -idevice_error_t idevice_new(idevice_t *device, const char *uuid); -idevice_error_t idevice_free(idevice_t device); + +/** + * Creates an idevice_t structure for the device specified by UDID, + * if the device is available (USBMUX devices only). + * + * @note The resulting idevice_t structure has to be freed with + * idevice_free() if it is no longer used. + * If you need to connect to a device available via network, use + * idevice_new_with_options() and include IDEVICE_LOOKUP_NETWORK in options. + * + * @see idevice_new_with_options + * + * @param device Upon calling this function, a pointer to a location of type + * idevice_t. On successful return, this location will be populated. + * @param udid The UDID to match. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_new(idevice_t *device, const char *udid); + +/** + * Creates an idevice_t structure for the device specified by UDID, + * if the device is available, with the given lookup options. + * + * @note The resulting idevice_t structure has to be freed with + * idevice_free() if it is no longer used. + * + * @param device Upon calling this function, a pointer to a location of type + * idevice_t. On successful return, this location will be populated. + * @param udid The UDID to match. + * @param options Specifies what connection types should be considered + * when looking up devices. Accepts bitwise or'ed values of idevice_options. + * If 0 (no option) is specified it will default to IDEVICE_LOOKUP_USBMUX. + * To lookup both USB and network-connected devices, pass + * IDEVICE_LOOKUP_USBMUX | IDEVICE_LOOKUP_NETWORK. If a device is available + * both via USBMUX *and* network, it will select the USB connection. + * This behavior can be changed by adding IDEVICE_LOOKUP_PREFER_NETWORK + * to the options in which case it will select the network connection. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_new_with_options(idevice_t *device, const char *udid, enum idevice_options options); + +/** + * Cleans up an idevice structure, then frees the structure itself. + * + * @param device idevice_t to free. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_free(idevice_t device); /* connection/disconnection */ -idevice_error_t idevice_connect(idevice_t device, uint16_t port, idevice_connection_t *connection); -idevice_error_t idevice_disconnect(idevice_connection_t connection); + +/** + * Set up a connection to the given device. + * + * @param device The device to connect to. + * @param port The destination port to connect to. + * @param connection Pointer to an idevice_connection_t that will be filled + * with the necessary data of the connection. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_connect(idevice_t device, uint16_t port, idevice_connection_t *connection); + +/** + * Disconnect from the device and clean up the connection structure. + * + * @param connection The connection to close. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_disconnect(idevice_connection_t connection); /* communication */ -idevice_error_t idevice_connection_send(idevice_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes); -idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout); -idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes); + +/** + * Send data to a device via the given connection. + * + * @param connection The connection to send data over. + * @param data Buffer with data to send. + * @param len Size of the buffer to send. + * @param sent_bytes Pointer to an uint32_t that will be filled + * with the number of bytes actually sent. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_send(idevice_connection_t connection, const char *data, uint32_t len, uint32_t *sent_bytes); + +/** + * Receive data from a device via the given connection. + * This function will return after the given timeout even if no data has been + * received. + * + * @param connection The connection to receive data from. + * @param data Buffer that will be filled with the received data. + * This buffer has to be large enough to hold len bytes. + * @param len Buffer size or number of bytes to receive. + * @param recv_bytes Number of bytes actually received. + * @param timeout Timeout in milliseconds after which this function should + * return even if no data has been received. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive_timeout(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes, unsigned int timeout); + +/** + * Receive data from a device via the given connection. + * This function is like idevice_connection_receive_timeout, but with a + * predefined reasonable timeout. + * + * @param connection The connection to receive data from. + * @param data Buffer that will be filled with the received data. + * This buffer has to be large enough to hold len bytes. + * @param len Buffer size or number of bytes to receive. + * @param recv_bytes Number of bytes actually received. + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_receive(idevice_connection_t connection, char *data, uint32_t len, uint32_t *recv_bytes); + +/** + * Enables SSL for the given connection. + * + * @param connection The connection to enable SSL for. + * + * @return IDEVICE_E_SUCCESS on success, IDEVICE_E_INVALID_ARG when connection + * is NULL or connection->ssl_data is non-NULL, or IDEVICE_E_SSL_ERROR when + * SSL initialization, setup, or handshake fails. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_enable_ssl(idevice_connection_t connection); + +/** + * Disable SSL for the given connection. + * + * @param connection The connection to disable SSL for. + * + * @return IDEVICE_E_SUCCESS on success, IDEVICE_E_INVALID_ARG when connection + * is NULL. This function also returns IDEVICE_E_SUCCESS when SSL is not + * enabled and does no further error checking on cleanup. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_disable_ssl(idevice_connection_t connection); + +/** + * Disable bypass SSL for the given connection without sending out terminate messages. + * + * @param connection The connection to disable SSL for. + * @param sslBypass if true ssl connection will not be terminated but just cleaned up, allowing + * plain text data going on underlying connection + * + * @return IDEVICE_E_SUCCESS on success, IDEVICE_E_INVALID_ARG when connection + * is NULL. This function also returns IDEVICE_E_SUCCESS when SSL is not + * enabled and does no further error checking on cleanup. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_disable_bypass_ssl(idevice_connection_t connection, uint8_t sslBypass); + + +/** + * Get the underlying file descriptor for a connection + * + * @param connection The connection to get fd of + * @param fd Pointer to an int where the fd is stored + * + * @return IDEVICE_E_SUCCESS if ok, otherwise an error code. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_connection_get_fd(idevice_connection_t connection, int *fd); /* misc */ -idevice_error_t idevice_get_handle(idevice_t device, uint32_t *handle); -idevice_error_t idevice_get_uuid(idevice_t device, char **uuid); + +/** + * Gets the handle or (USBMUX device id) of the device. + * + * @param device The device to get the USBMUX device id for. + * @param handle Pointer to a uint32_t that will be set to the USBMUX handle value. + * + * @return IDEVICE_E_SUCCESS on success, otherwise an error code. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_get_handle(idevice_t device, uint32_t *handle); + +/** + * Gets the Unique Device ID for the device. + * + * @param device The device to get the Unique Device ID for. + * @param udid Pointer that will be set to an allocated buffer with the device UDID. The consumer is responsible for releasing the allocated memory. + * + * @return IDEVICE_E_SUCCESS on success, otherwise an error code. + */ +LIBIMOBILEDEVICE_API idevice_error_t idevice_get_udid(idevice_t device, char **udid); + +/** + * Returns a static string of the libimobiledevice version. + * + * @return The libimobiledevice version as static ascii string + */ +LIBIMOBILEDEVICE_API const char* libimobiledevice_version(); #ifdef __cplusplus } diff --git a/include/libimobiledevice/lockdown.h b/include/libimobiledevice/lockdown.h index 97df6b0..21669ef 100644 --- a/include/libimobiledevice/lockdown.h +++ b/include/libimobiledevice/lockdown.h @@ -3,8 +3,10 @@ * @brief Manage device preferences, start services, pairing and activation. * \internal * + * Copyright (c) 2009-2014 Martin S. All Rights Reserved. + * Copyright (c) 2014 Koby Boyango All Rights Reserved. + * Copyright (c) 2010 Bryan Forbes All Rights Reserved. * Copyright (c) 2008 Zach C. All Rights Reserved. - * Copyright (c) 2009 Martin S. All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -21,8 +23,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef LOCKDOWN_H -#define LOCKDOWN_H +#ifndef ILOCKDOWN_H +#define ILOCKDOWN_H #ifdef __cplusplus extern "C" { @@ -30,74 +32,543 @@ extern "C" { #include <libimobiledevice/libimobiledevice.h> -/** @name Error Codes */ -/*@{*/ -#define LOCKDOWN_E_SUCCESS 0 -#define LOCKDOWN_E_INVALID_ARG -1 -#define LOCKDOWN_E_INVALID_CONF -2 -#define LOCKDOWN_E_PLIST_ERROR -3 -#define LOCKDOWN_E_PAIRING_FAILED -4 -#define LOCKDOWN_E_SSL_ERROR -5 -#define LOCKDOWN_E_DICT_ERROR -6 -#define LOCKDOWN_E_START_SERVICE_FAILED -7 -#define LOCKDOWN_E_NOT_ENOUGH_DATA -8 -#define LOCKDOWN_E_SET_VALUE_PROHIBITED -9 -#define LOCKDOWN_E_GET_VALUE_PROHIBITED -10 -#define LOCKDOWN_E_REMOVE_VALUE_PROHIBITED -11 -#define LOCKDOWN_E_MUX_ERROR -12 -#define LOCKDOWN_E_ACTIVATION_FAILED -13 -#define LOCKDOWN_E_PASSWORD_PROTECTED -14 -#define LOCKDOWN_E_NO_RUNNING_SESSION -15 -#define LOCKDOWN_E_INVALID_HOST_ID -16 -#define LOCKDOWN_E_INVALID_SERVICE -17 -#define LOCKDOWN_E_INVALID_ACTIVATION_RECORD -18 - -#define LOCKDOWN_E_UNKNOWN_ERROR -256 -/*@}*/ - -/** Represents an error code. */ -typedef int16_t lockdownd_error_t; - -typedef struct lockdownd_client_private lockdownd_client_private; +/** Error Codes */ +typedef enum { + /* custom */ + LOCKDOWN_E_SUCCESS = 0, + LOCKDOWN_E_INVALID_ARG = -1, + LOCKDOWN_E_INVALID_CONF = -2, + LOCKDOWN_E_PLIST_ERROR = -3, + LOCKDOWN_E_PAIRING_FAILED = -4, + LOCKDOWN_E_SSL_ERROR = -5, + LOCKDOWN_E_DICT_ERROR = -6, + LOCKDOWN_E_RECEIVE_TIMEOUT = -7, + LOCKDOWN_E_MUX_ERROR = -8, + LOCKDOWN_E_NO_RUNNING_SESSION = -9, + /* native */ + LOCKDOWN_E_INVALID_RESPONSE = -10, + LOCKDOWN_E_MISSING_KEY = -11, + LOCKDOWN_E_MISSING_VALUE = -12, + LOCKDOWN_E_GET_PROHIBITED = -13, + LOCKDOWN_E_SET_PROHIBITED = -14, + LOCKDOWN_E_REMOVE_PROHIBITED = -15, + LOCKDOWN_E_IMMUTABLE_VALUE = -16, + LOCKDOWN_E_PASSWORD_PROTECTED = -17, + LOCKDOWN_E_USER_DENIED_PAIRING = -18, + LOCKDOWN_E_PAIRING_DIALOG_RESPONSE_PENDING = -19, + LOCKDOWN_E_MISSING_HOST_ID = -20, + LOCKDOWN_E_INVALID_HOST_ID = -21, + LOCKDOWN_E_SESSION_ACTIVE = -22, + LOCKDOWN_E_SESSION_INACTIVE = -23, + LOCKDOWN_E_MISSING_SESSION_ID = -24, + LOCKDOWN_E_INVALID_SESSION_ID = -25, + LOCKDOWN_E_MISSING_SERVICE = -26, + LOCKDOWN_E_INVALID_SERVICE = -27, + LOCKDOWN_E_SERVICE_LIMIT = -28, + LOCKDOWN_E_MISSING_PAIR_RECORD = -29, + LOCKDOWN_E_SAVE_PAIR_RECORD_FAILED = -30, + LOCKDOWN_E_INVALID_PAIR_RECORD = -31, + LOCKDOWN_E_INVALID_ACTIVATION_RECORD = -32, + LOCKDOWN_E_MISSING_ACTIVATION_RECORD = -33, + LOCKDOWN_E_SERVICE_PROHIBITED = -34, + LOCKDOWN_E_ESCROW_LOCKED = -35, + LOCKDOWN_E_PAIRING_PROHIBITED_OVER_THIS_CONNECTION = -36, + LOCKDOWN_E_FMIP_PROTECTED = -37, + LOCKDOWN_E_MC_PROTECTED = -38, + LOCKDOWN_E_MC_CHALLENGE_REQUIRED = -39, + LOCKDOWN_E_UNKNOWN_ERROR = -256 +} lockdownd_error_t; + +typedef struct lockdownd_client_private lockdownd_client_private; /**< \private */ typedef lockdownd_client_private *lockdownd_client_t; /**< The client handle. */ struct lockdownd_pair_record { char *device_certificate; /**< The device certificate */ char *host_certificate; /**< The host certificate */ - char *host_id; /**< A unique HostID for the host computer */ char *root_certificate; /**< The root certificate */ + char *host_id; /**< A unique HostID for the host computer */ + char *system_buid; /**< A unique system id */ }; -/** A pair record holding device, host and root certificates along the host_id */ -typedef struct lockdownd_pair_record *lockdownd_pair_record_t; +/** pair record holding device, host and root certificates along the host_id */ +typedef struct lockdownd_pair_record *lockdownd_pair_record_t; /**< pair record */ + +/** service descriptor */ +struct lockdownd_service_descriptor { + uint16_t port; /**< port number the service was started on */ + uint8_t ssl_enabled; /**< an indicator if the service requires SSL */ + char* identifier; /**< identifier of the service */ +}; +typedef struct lockdownd_service_descriptor *lockdownd_service_descriptor_t; + +/** Callback types used in #lockdownd_cu_pairing_cb_t */ +typedef enum { + LOCKDOWN_CU_PAIRING_PIN_REQUESTED, /**< PIN requested: data_ptr is a char* buffer, and data_size points to the size of this buffer that must not be exceeded and has to be updated to the actual number of characters filled into the buffer. */ + LOCKDOWN_CU_PAIRING_DEVICE_INFO, /**< device information available: data_ptr is a plist_t, and data_size is ignored. The plist_t has to be copied if required, since it is freed when the callback function returns. */ + LOCKDOWN_CU_PAIRING_ERROR /**< pairing error message available: data_ptr is a NULL-terminated char* buffer containing the error message, and data_size is ignored. Buffer needs to be copied if it shall persist outside the callback. */ +} lockdownd_cu_pairing_cb_type_t; + +/* CU pairing callback function prototype */ +/** Callback used to supply the pairing PIN during a CU pairing session, + * and to report device information and pairing error messages. */ +typedef void (*lockdownd_cu_pairing_cb_t) (lockdownd_cu_pairing_cb_type_t cb_type, void *user_data, void* data_ptr, unsigned int* data_size); + /* Interface */ -lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, const char *label); -lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, const char *label); -lockdownd_error_t lockdownd_client_free(lockdownd_client_t client); - -lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **type); -lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value); -lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value); -lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key); -lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *service, uint16_t *port); -lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char *host_id, char **session_id, int *ssl_enabled); -lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char *session_id); -lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist); -lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist_t *plist); -lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); -lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); -lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); -lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record); -lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client); -lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client); -lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client); + +/** + * Creates a new lockdownd client for the device. + * + * @note This function does not pair with the device or start a session. This + * has to be done manually by the caller after the client is created. + * The device disconnects automatically if the lockdown connection idles + * for more than 10 seconds. Make sure to call lockdownd_client_free() as soon + * as the connection is no longer needed. + * + * @param device The device to create a lockdownd client for + * @param client The pointer to the location of the new lockdownd_client + * @param label The label to use for communication. Usually the program name. + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_client_new(idevice_t device, lockdownd_client_t *client, const char *label); + +/** + * Creates a new lockdownd client for the device and starts initial handshake. + * The handshake consists out of query_type, validate_pair, pair and + * start_session calls. It uses the internal pairing record management. + * + * @note The device disconnects automatically if the lockdown connection idles + * for more than 10 seconds. Make sure to call lockdownd_client_free() as soon + * as the connection is no longer needed. + * + * @param device The device to create a lockdownd client for + * @param client The pointer to the location of the new lockdownd_client + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL, + * LOCKDOWN_E_INVALID_CONF if configuration data is wrong + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_client_new_with_handshake(idevice_t device, lockdownd_client_t *client, const char *label); + +/** + * Closes the lockdownd client session if one is running and frees up the + * lockdownd_client struct. + * + * @param client The lockdown client + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_client_free(lockdownd_client_t client); + + +/** + * Query the type of the service daemon. Depending on whether the device is + * queried in normal mode or restore mode, different types will be returned. + * + * @param client The lockdownd client + * @param type The type returned by the service daemon. Pass NULL to ignore. + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_query_type(lockdownd_client_t client, char **type); + +/** + * Retrieves a preferences plist using an optional domain and/or key name. + * + * @param client An initialized lockdownd client. + * @param domain The domain to query on or NULL for global domain + * @param key The key name to request or NULL to query for all keys + * @param value A plist node representing the result value node + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_get_value(lockdownd_client_t client, const char *domain, const char *key, plist_t *value); + +/** + * Sets a preferences value using a plist and optional by domain and/or key name. + * + * @param client an initialized lockdownd client. + * @param domain the domain to query on or NULL for global domain + * @param key the key name to set the value or NULL to set a value dict plist + * @param value a plist node of any node type representing the value to set + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client or + * value is NULL + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_set_value(lockdownd_client_t client, const char *domain, const char *key, plist_t value); + +/** + * Removes a preference node by domain and/or key name. + * + * @note: Use with caution as this could remove vital information on the device + * + * @param client An initialized lockdownd client. + * @param domain The domain to query on or NULL for global domain + * @param key The key name to remove or NULL remove all keys for the current domain + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_remove_value(lockdownd_client_t client, const char *domain, const char *key); + +/** + * Requests to start a service and retrieve it's port on success. + * + * @param client The lockdownd client + * @param identifier The identifier of the service to start + * @param service 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 be + * started by the device + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_start_service(lockdownd_client_t client, const char *identifier, lockdownd_service_descriptor_t *service); + +/** + * Requests to start a service and retrieve it's port on success. + * Sends the escrow bag from the device's pair record. + * + * @param client The lockdownd client + * @param identifier The identifier of the service to start + * @param service 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 are + * missing from the device record. + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_start_service_with_escrow_bag(lockdownd_client_t client, const char *identifier, lockdownd_service_descriptor_t *service); + +/** + * Opens a session with lockdownd and switches to SSL mode if device wants it. + * + * @param client The lockdownd client + * @param host_id The HostID of the computer + * @param session_id The new session_id of the created session + * @param ssl_enabled Whether SSL communication is used in the session + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when a client + * or host_id is NULL, LOCKDOWN_E_PLIST_ERROR if the response plist had errors, + * LOCKDOWN_E_INVALID_HOST_ID if the device does not know the supplied HostID, + * LOCKDOWN_E_SSL_ERROR if enabling SSL communication failed + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char *host_id, char **session_id, int *ssl_enabled); + +/** + * Closes the lockdownd session by sending the StopSession request. + * + * @see lockdownd_start_session + * + * @param client The lockdown client + * @param session_id The id of a running session + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char *session_id); + +/** + * Sends a plist to lockdownd. + * + * @note This function is low-level and should only be used if you need to send + * a new type of message. + * + * @param client The lockdownd client + * @param plist The plist to send + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client or + * plist is NULL + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist); + +/** + * Receives a plist from lockdownd. + * + * @param client The lockdownd client + * @param plist The plist to store the received data + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client or + * plist is NULL + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_receive(lockdownd_client_t client, plist_t *plist); + +/** + * Pairs the device using the supplied pair record. + * + * @param client The lockdown client + * @param pair_record The pair record to use for pairing. If NULL is passed, then + * the pair records from the current machine are used. New records will be + * generated automatically when pairing is done for the first time. + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL, + * LOCKDOWN_E_PLIST_ERROR if the pair_record certificates are wrong, + * LOCKDOWN_E_PAIRING_FAILED if the pairing failed, + * LOCKDOWN_E_PASSWORD_PROTECTED if the device is password protected, + * LOCKDOWN_E_INVALID_HOST_ID if the device does not know the caller's host id + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); + + /** + * Pairs the device using the supplied pair record and passing the given options. + * + * @param client The lockdown client + * @param pair_record The pair record to use for pairing. If NULL is passed, then + * the pair records from the current machine are used. New records will be + * generated automatically when pairing is done for the first time. + * @param options The pairing options to pass. Can be NULL for no options. + * @param response If non-NULL a pointer to lockdownd's response dictionary is returned. + * The caller is responsible to free the response dictionary with plist_free(). + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL, + * LOCKDOWN_E_PLIST_ERROR if the pair_record certificates are wrong, + * LOCKDOWN_E_PAIRING_FAILED if the pairing failed, + * LOCKDOWN_E_PASSWORD_PROTECTED if the device is password protected, + * LOCKDOWN_E_INVALID_HOST_ID if the device does not know the caller's host id + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_pair_with_options(lockdownd_client_t client, lockdownd_pair_record_t pair_record, plist_t options, plist_t *response); + +/** + * Validates if the device is paired with the given HostID. If successful the + * specified host will become trusted host of the device indicated by the + * lockdownd preference named TrustedHostAttached. Otherwise the host must be + * paired using lockdownd_pair() first. + * + * @param client The lockdown client + * @param pair_record The pair record to validate pairing with. If NULL is + * passed, then the pair record is read from the internal pairing record + * management. + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL, + * LOCKDOWN_E_PLIST_ERROR if the pair_record certificates are wrong, + * LOCKDOWN_E_PAIRING_FAILED if the pairing failed, + * LOCKDOWN_E_PASSWORD_PROTECTED if the device is password protected, + * LOCKDOWN_E_INVALID_HOST_ID if the device does not know the caller's host id + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_validate_pair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); + +/** + * Unpairs the device with the given HostID and removes the pairing records + * from the device and host if the internal pairing record management is used. + * + * @param client The lockdown client + * @param pair_record The pair record to use for unpair. If NULL is passed, then + * the pair records from the current machine are used. + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL, + * LOCKDOWN_E_PLIST_ERROR if the pair_record certificates are wrong, + * LOCKDOWN_E_PAIRING_FAILED if the pairing failed, + * LOCKDOWN_E_PASSWORD_PROTECTED if the device is password protected, + * LOCKDOWN_E_INVALID_HOST_ID if the device does not know the caller's host id + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_unpair(lockdownd_client_t client, lockdownd_pair_record_t pair_record); + +/** + * Activates the device. Only works within an open session. + * The ActivationRecord plist dictionary must be obtained using the + * activation protocol requesting from Apple's https webservice. + * + * @param client The lockdown client + * @param activation_record The activation record plist dictionary + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client or + * activation_record is NULL, LOCKDOWN_E_NO_RUNNING_SESSION if no session is + * open, LOCKDOWN_E_PLIST_ERROR if the received plist is broken, + * LOCKDOWN_E_ACTIVATION_FAILED if the activation failed, + * LOCKDOWN_E_INVALID_ACTIVATION_RECORD if the device reports that the + * activation_record is invalid + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_activate(lockdownd_client_t client, plist_t activation_record); + +/** + * Deactivates the device, returning it to the locked “Activate with iTunes” + * screen. + * + * @param client The lockdown client + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL, + * LOCKDOWN_E_NO_RUNNING_SESSION if no session is open, + * LOCKDOWN_E_PLIST_ERROR if the received plist is broken + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_deactivate(lockdownd_client_t client); + +/** + * Tells the device to immediately enter recovery mode. + * + * @param client The lockdown client + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_enter_recovery(lockdownd_client_t client); + +/** + * Sends the Goodbye request to lockdownd signaling the end of communication. + * + * @param client The lockdown client + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client + * is NULL, LOCKDOWN_E_PLIST_ERROR if the device did not acknowledge the + * request + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_goodbye(lockdownd_client_t client); + +/** + * Creates a CU pairing session for the current lockdown client. + * This is required to allow lockdownd_cu_send_request_and_get_reply(), + * lockdownd_get_value_cu() and lockdonwd_pair_cu() requests, and eventually + * allows to perform an actual wireless pairing. + * + * Through the callback function, the PIN displayed on the device has to be + * supplied during the process. Currently, only AppleTV devices have this + * capability. + * + * @param client The lockdown client to perform the CU pairing for + * @param pairing_callback Callback function that is used to supply the PIN + * for the pairing process, but also to receive device information or + * pairing error messages. + * @param cb_user_data User data that will be passed as additional argument + * to the callback function. + * @param host_info (Optional) A dictionary containing host information to + * send to the device when finalizing the CU pairing. The supplied + * values will override the default values gathered for the current host. + * @param acl (Optional) A dictionary containing ACL information. Currently + * only com.apple.ScreenCapture:true and com.apple.developer:true are known + * valid ACL values, which are used as default when NULL is passed. + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG if one of the + * parameters is invalid, LOCKDOWN_E_PAIRING_FAILED if the pairing failed, + * or a LOCKDOWN_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_cu_pairing_create(lockdownd_client_t client, lockdownd_cu_pairing_cb_t pairing_callback, void* cb_user_data, plist_t host_info, plist_t acl); + +/** + * Sends a request via lockdown client with established CU pairing session + * and attempts to retrieve a reply. This function is used internally + * by lockdownd_get_value_cu() and lockdownd_pair_cu(), but exposed here to + * allow custom requests being sent and their replies being received. + * + * @param client A lockdown client with an established CU pairing. + * @param request The request to perform. + * @param request_payload The payload for the request. + * @param reply (Optional) If not NULL, the plist_t will be set to the reply + * dictionary that has been received. Consumer is responsible to free it + * using plist_free() when no longer required. + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG if one of the + * parameters is invalid, LOCKDOWN_E_NO_RUNNING_SESSION if the current + * lockdown client does not have an established CU pairing session, + * or a LOCKDOWN_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_cu_send_request_and_get_reply(lockdownd_client_t client, const char* request, plist_t request_payload, plist_t* reply); + +/** + * Retrieves a value using an optional domain and/or key name from a lockdown + * client with established CU pairing session. + * + * This is used to retrieve values that are only accessible after a CU pairing + * has been established, and would otherwise only be accessible with a valid + * device pairing. + * + * @param client A lockdown client with an established CU pairing. + * @param domain The domain to query on or NULL for global domain + * @param key The key name to request or NULL to query for all keys + * @param value A plist node representing the result value node + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG if one of the + * parameters is invalid, LOCKDOWN_E_NO_RUNNING_SESSION if the current + * lockdown client does not have an established CU pairing session, + * or a LOCKDOWN_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_get_value_cu(lockdownd_client_t client, const char* domain, const char* key, plist_t* value); + +/** + * Perform a device pairing with a lockdown client that has an established + * CU pairing session. + * + * @param client A lockdown client with an established CU pairing. + * + * @return LOCKDOWN_E_SUCCESS on success, LOCKDOWN_E_INVALID_ARG when client + * is NULL, LOCKDOWN_E_NO_RUNNING_SESSION if the current lockdown client + * does not have an established CU pairing session, or a LOCKDOWN_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_pair_cu(lockdownd_client_t client); + /* Helper */ -void lockdownd_client_set_label(lockdownd_client_t client, const char *label); -lockdownd_error_t lockdownd_get_device_uuid(lockdownd_client_t control, char **uuid); -lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name); -lockdownd_error_t lockdownd_get_sync_data_classes(lockdownd_client_t client, char ***classes, int *count); -lockdownd_error_t lockdownd_data_classes_free(char **classes); + +/** + * Sets the label to send for requests to lockdownd. + * + * @param client The lockdown client + * @param label The label to set or NULL to disable sending a label + * + */ +LIBIMOBILEDEVICE_API void lockdownd_client_set_label(lockdownd_client_t client, const char *label); + +/** + * Returns the unique id of the device from lockdownd. + * + * @param client An initialized lockdownd client. + * @param udid Holds the unique id of the device. The caller is responsible + * for freeing the memory. + * + * @return LOCKDOWN_E_SUCCESS on success + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_get_device_udid(lockdownd_client_t client, char **udid); + +/** + * Retrieves the name of the device from lockdownd set by the user. + * + * @param client An initialized lockdownd client. + * @param device_name Holds the name of the device. The caller is + * responsible for freeing the memory. + * + * @return LOCKDOWN_E_SUCCESS on success + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_get_device_name(lockdownd_client_t client, char **device_name); + +/** + * Calculates and returns the data classes the device supports from lockdownd. + * + * @param client An initialized lockdownd client. + * @param classes A pointer to store an array of class names. The caller is responsible + * for freeing the memory which can be done using mobilesync_data_classes_free(). + * @param count The number of items in the classes array. + * + * @return LOCKDOWN_E_SUCCESS on success, + * LOCKDOWN_E_INVALID_ARG when client is NULL, + * LOCKDOWN_E_NO_RUNNING_SESSION if no session is open, + * LOCKDOWN_E_PLIST_ERROR if the received plist is broken + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_get_sync_data_classes(lockdownd_client_t client, char ***classes, int *count); + +/** + * Frees memory of an allocated array of data classes as returned by lockdownd_get_sync_data_classes() + * + * @param classes An array of class names to free. + * + * @return LOCKDOWN_E_SUCCESS on success + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_data_classes_free(char **classes); + +/** + * Frees memory of a service descriptor as returned by lockdownd_start_service() + * + * @param service A service descriptor instance to free. + * + * @return LOCKDOWN_E_SUCCESS on success + */ +LIBIMOBILEDEVICE_API lockdownd_error_t lockdownd_service_descriptor_free(lockdownd_service_descriptor_t service); + +/** + * Gets a readable error string for a given lockdown error code. + * + * @param err A lockdownd error code + * + * @returns A readable error string + */ +LIBIMOBILEDEVICE_API const char* lockdownd_strerror(lockdownd_error_t err); #ifdef __cplusplus } diff --git a/include/libimobiledevice/misagent.h b/include/libimobiledevice/misagent.h new file mode 100644 index 0000000..7981a8b --- /dev/null +++ b/include/libimobiledevice/misagent.h @@ -0,0 +1,168 @@ +/** + * @file libimobiledevice/misagent.h + * @brief Manage provisioning profiles. + * \internal + * + * Copyright (c) 2013-2014 Martin Szulecki All Rights Reserved. + * Copyright (c) 2012 Nikias Bassen All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IMISAGENT_H +#define IMISAGENT_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +/** Service identifier passed to lockdownd_start_service() to start the misagent service */ +#define MISAGENT_SERVICE_NAME "com.apple.misagent" + +/** Error Codes */ +typedef enum { + MISAGENT_E_SUCCESS = 0, + MISAGENT_E_INVALID_ARG = -1, + MISAGENT_E_PLIST_ERROR = -2, + MISAGENT_E_CONN_FAILED = -3, + MISAGENT_E_REQUEST_FAILED = -4, + MISAGENT_E_UNKNOWN_ERROR = -256 +} misagent_error_t; + +typedef struct misagent_client_private misagent_client_private; /**< \private */ +typedef misagent_client_private *misagent_client_t; /**< The client handle. */ + +/* Interface */ + +/** + * Connects to the misagent 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 + * misagent_client_t upon successful return. + * + * @return MISAGENT_E_SUCCESS on success, MISAGENT_E_INVALID_ARG when + * client is NULL, or an MISAGENT_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API misagent_error_t misagent_client_new(idevice_t device, lockdownd_service_descriptor_t service, misagent_client_t *client); + +/** + * Starts a new misagent service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * misagent_client_t upon successful return. Must be freed using + * misagent_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return MISAGENT_E_SUCCESS on success, or an MISAGENT_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API misagent_error_t misagent_client_start_service(idevice_t device, misagent_client_t* client, const char* label); + +/** + * Disconnects an misagent client from the device and frees up the + * misagent client data. + * + * @param client The misagent client to disconnect and free. + * + * @return MISAGENT_E_SUCCESS on success, MISAGENT_E_INVALID_ARG when + * client is NULL, or an MISAGENT_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API misagent_error_t misagent_client_free(misagent_client_t client); + + +/** + * Installs the given provisioning profile. Only works with valid profiles. + * + * @param client The connected misagent to use for installation + * @param profile The valid provisioning profile to install. This has to be + * passed as a PLIST_DATA, otherwise the function will fail. + * + * @return MISAGENT_E_SUCCESS on success, MISAGENT_E_INVALID_ARG when + * client is invalid, or an MISAGENT_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API misagent_error_t misagent_install(misagent_client_t client, plist_t profile); + +/** + * Retrieves all installed provisioning profiles (iOS 9.2.1 or below). + * + * @param client The connected misagent to use. + * @param profiles Pointer to a plist_t that will be set to a PLIST_ARRAY + * if the function is successful. + * + * @return MISAGENT_E_SUCCESS on success, MISAGENT_E_INVALID_ARG when + * client is invalid, or an MISAGENT_E_* error code otherwise. + * + * @note This API call only works with iOS 9.2.1 or below. + * For newer iOS versions use misagent_copy_all() instead. + * + * @note If no provisioning profiles are installed on the device, this function + * still returns MISAGENT_E_SUCCESS and profiles will just point to an + * empty array. + */ +LIBIMOBILEDEVICE_API misagent_error_t misagent_copy(misagent_client_t client, plist_t* profiles); + +/** + * Retrieves all installed provisioning profiles (iOS 9.3 or higher). + * + * @param client The connected misagent to use. + * @param profiles Pointer to a plist_t that will be set to a PLIST_ARRAY + * if the function is successful. + * + * @return MISAGENT_E_SUCCESS on success, MISAGENT_E_INVALID_ARG when + * client is invalid, or an MISAGENT_E_* error code otherwise. + * + * @note This API call only works with iOS 9.3 or higher. + * For older iOS versions use misagent_copy() instead. + * + * @note If no provisioning profiles are installed on the device, this function + * still returns MISAGENT_E_SUCCESS and profiles will just point to an + * empty array. + */ +LIBIMOBILEDEVICE_API misagent_error_t misagent_copy_all(misagent_client_t client, plist_t* profiles); + +/** + * Removes a given provisioning profile. + * + * @param client The connected misagent to use. + * @param profileID Identifier of the provisioning profile to remove. + * This is a UUID that can be obtained from the provisioning profile data. + * @see misagent_copy + * + * @return MISAGENT_E_SUCCESS on success, MISAGENT_E_INVALID_ARG when + * client is invalid, or an MISAGENT_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API misagent_error_t misagent_remove(misagent_client_t client, const char* profileID); + +/** + * Retrieves the status code from the last operation. + * + * @param client The misagent to use. + * + * @return -1 if client is invalid, or the status code from the last operation + */ +LIBIMOBILEDEVICE_API int misagent_get_status_code(misagent_client_t client); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/mobile_image_mounter.h b/include/libimobiledevice/mobile_image_mounter.h index 04c65d5..76bb61a 100644 --- a/include/libimobiledevice/mobile_image_mounter.h +++ b/include/libimobiledevice/mobile_image_mounter.h @@ -3,7 +3,8 @@ * @brief Mount developer/debug disk images on the device. * \internal * - * Copyright (c) 2010 Nikias Bassen All Rights Reserved. + * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. + * Copyright (c) 2010-2014 Nikias Bassen All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,37 +21,252 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef MOBILE_IMAGE_MOUNTER_H -#define MOBILE_IMAGE_MOUNTER_H +#ifndef IMOBILE_IMAGE_MOUNTER_H +#define IMOBILE_IMAGE_MOUNTER_H #ifdef __cplusplus extern "C" { #endif #include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> -/** @name Error Codes */ -/*@{*/ -#define MOBILE_IMAGE_MOUNTER_E_SUCCESS 0 -#define MOBILE_IMAGE_MOUNTER_E_INVALID_ARG -1 -#define MOBILE_IMAGE_MOUNTER_E_PLIST_ERROR -2 -#define MOBILE_IMAGE_MOUNTER_E_CONN_FAILED -3 +/** Service identifier passed to lockdownd_start_service() to start the mobile image mounter service */ +#define MOBILE_IMAGE_MOUNTER_SERVICE_NAME "com.apple.mobile.mobile_image_mounter" -#define MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR -256 -/*@}*/ +/** Error Codes */ +typedef enum { + MOBILE_IMAGE_MOUNTER_E_SUCCESS = 0, + MOBILE_IMAGE_MOUNTER_E_INVALID_ARG = -1, + MOBILE_IMAGE_MOUNTER_E_PLIST_ERROR = -2, + MOBILE_IMAGE_MOUNTER_E_CONN_FAILED = -3, + MOBILE_IMAGE_MOUNTER_E_COMMAND_FAILED = -4, + MOBILE_IMAGE_MOUNTER_E_DEVICE_LOCKED = -5, + MOBILE_IMAGE_MOUNTER_E_NOT_SUPPORTED = -6, + MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR = -256 +} mobile_image_mounter_error_t; -/** Represents an error code. */ -typedef int16_t mobile_image_mounter_error_t; - -typedef struct mobile_image_mounter_client_private mobile_image_mounter_client_private; +typedef struct mobile_image_mounter_client_private mobile_image_mounter_client_private; /**< \private */ typedef mobile_image_mounter_client_private *mobile_image_mounter_client_t; /**< The client handle. */ +/** callback for image upload */ +typedef ssize_t (*mobile_image_mounter_upload_cb_t) (void* buffer, size_t length, void *user_data); + /* Interface */ -mobile_image_mounter_error_t mobile_image_mounter_new(idevice_t device, uint16_t port, mobile_image_mounter_client_t *client); -mobile_image_mounter_error_t mobile_image_mounter_free(mobile_image_mounter_client_t client); -mobile_image_mounter_error_t mobile_image_mounter_lookup_image(mobile_image_mounter_client_t client, const char *image_type, plist_t *result); -mobile_image_mounter_error_t mobile_image_mounter_mount_image(mobile_image_mounter_client_t client, const char *image_path, const char *image_signature, uint16_t signature_length, const char *image_type, plist_t *result); -mobile_image_mounter_error_t mobile_image_mounter_hangup(mobile_image_mounter_client_t client); + +/** + * 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. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_new(idevice_t device, lockdownd_service_descriptor_t service, mobile_image_mounter_client_t *client); + +/** + * Starts a new mobile_image_mounter service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * mobile_image_mounter_t upon successful return. Must be freed using + * mobile_image_mounter_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, or an MOBILE_IMAGE_MOUNTER_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_start_service(idevice_t device, mobile_image_mounter_client_t* client, const char* label); + +/** + * Disconnects a mobile_image_mounter client from the device and frees up the + * mobile_image_mounter client data. + * + * @param client The mobile_image_mounter client to disconnect and free. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, + * or MOBILE_IMAGE_MOUNTER_E_INVALID_ARG if client is NULL. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_free(mobile_image_mounter_client_t client); + + +/** + * Tells if the image of ImageType is already mounted. + * + * @param client The client use + * @param image_type The type of the image to look up + * @param result Pointer to a plist that will receive the result of the + * operation. + * + * @note This function may return MOBILE_IMAGE_MOUNTER_E_SUCCESS even if the + * operation has failed. Check the resulting plist for further information. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, or an error code on error + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_lookup_image(mobile_image_mounter_client_t client, const char *image_type, plist_t *result); + +/** + * Uploads an image with an optional signature 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 signature Buffer with a signature of the image being uploaded. If + * NULL, no signature will be used. + * @param signature_size Total size of the image signature buffer. If 0, no + * signature will be used. + * @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. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_upload_image(mobile_image_mounter_client_t client, const char *image_type, size_t image_size, const unsigned char *signature, unsigned int signature_size, mobile_image_mounter_upload_cb_t upload_cb, void* userdata); + +/** + * Mounts an image on the device. + * + * @param client The connected mobile_image_mounter client. + * @param image_path The absolute path of the image to mount. The image must + * be present before calling this function. + * @param signature Pointer to a buffer holding the images' signature + * @param signature_size Length of the signature image_signature points to + * @param image_type Type of image to mount + * @param options A dictionary containing additional key/value pairs to add + * @param result Pointer to a plist that will receive the result of the + * operation. + * + * @note This function may return MOBILE_IMAGE_MOUNTER_E_SUCCESS even if the + * operation has failed. Check the resulting plist for further information. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, + * MOBILE_IMAGE_MOUNTER_E_INVALID_ARG if on ore more parameters are + * invalid, or another error code otherwise. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_mount_image_with_options(mobile_image_mounter_client_t client, const char *image_path, const unsigned char *signature, unsigned int signature_size, const char *image_type, plist_t options, plist_t *result); + +/** + * Mounts an image on the device. + * + * @param client The connected mobile_image_mounter client. + * @param image_path The absolute path of the image to mount. The image must + * be present before calling this function. + * @param signature Pointer to a buffer holding the images' signature + * @param signature_size Length of the signature image_signature points to + * @param image_type Type of image to mount + * @param result Pointer to a plist that will receive the result of the + * operation. + * + * @note This function may return MOBILE_IMAGE_MOUNTER_E_SUCCESS even if the + * operation has failed. Check the resulting plist for further information. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, + * MOBILE_IMAGE_MOUNTER_E_INVALID_ARG if on ore more parameters are + * invalid, or another error code otherwise. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_mount_image(mobile_image_mounter_client_t client, const char *image_path, const unsigned char *signature, unsigned int signature_size, const char *image_type, plist_t *result); + +/** + * Unmount a mounted image at given path on the device. + * + * @param client The connected mobile_image_mounter client. + * @param mount_path The mount path of the mounted image on the device. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, + * or a MOBILE_IMAGE_MOUNTER_E_* error code on error. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_unmount_image(mobile_image_mounter_client_t client, const char *mount_path); + +/** + * Hangs up the connection to the mobile_image_mounter service. + * This functions has to be called before freeing up a mobile_image_mounter + * instance. If not, errors appear in the device's syslog. + * + * @param client The client to hang up + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, + * MOBILE_IMAGE_MOUNTER_E_INVALID_ARG if client is invalid, + * or another error code otherwise. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_hangup(mobile_image_mounter_client_t client); + +/** + * Query the developer mode status of the given device. + * + * @param client The connected mobile_image_mounter client. + * @param result A pointer to a plist_t that will be set to the resulting developer mode status dictionary. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, + * or a MOBILE_IMAGE_MOUNTER_E_* error code on error. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_query_developer_mode_status(mobile_image_mounter_client_t client, plist_t *result); + +/** + * Query a personalization nonce for the given image type, used for personalized disk images (iOS 17+). + * This nonce is supposed to be added to the TSS request for the corresponding image. + * + * @param client The connected mobile_image_mounter client. + * @param image_type The image_type to get the personalization nonce for, usually `DeveloperDiskImage`. + * @param nonce Pointer that will be set to an allocated buffer with the nonce value. + * @param nonce_size Pointer to an unsigned int that will receive the size of the nonce value. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, + * or a MOBILE_IMAGE_MOUNTER_E_* error code on error. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_query_nonce(mobile_image_mounter_client_t client, const char* image_type, unsigned char** nonce, unsigned int* nonce_size); + +/** + * Query personalization identitifers for the given image_type. + * + * @param client The connected mobile_image_mounter client. + * @param image_type The image_type to get the personalization identifiers for. Can be NULL. + * @param result A pointer to a plist_t that will be set to the resulting identifier dictionary. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, + * or a MOBILE_IMAGE_MOUNTER_E_* error code on error. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_query_personalization_identifiers(mobile_image_mounter_client_t client, const char* image_type, plist_t *result); + +/** + * + * @param client The connected mobile_image_mounter client. + * @param image_type The image_type to get the personalization identifiers for. Can be NULL. + * @param signature The signature of the corresponding personalized image. + * @param signature_size The size of signature. + * @param manifest Pointer that will be set to an allocated buffer with the manifest data. + * @param manifest_size Pointer to an unsigned int that will be set to the size of the manifest data. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, + * or a MOBILE_IMAGE_MOUNTER_E_* error code on error. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_query_personalization_manifest(mobile_image_mounter_client_t client, const char* image_type, const unsigned char* signature, unsigned int signature_size, unsigned char** manifest, unsigned int* manifest_size); + +/** + * Roll the personalization nonce. + * + * @param client The connected mobile_image_mounter client. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, + * or a MOBILE_IMAGE_MOUNTER_E_* error code on error. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_roll_personalization_nonce(mobile_image_mounter_client_t client); + +/** + * Roll the Cryptex nonce. + * + * @param client The connected mobile_image_mounter client. + * + * @return MOBILE_IMAGE_MOUNTER_E_SUCCESS on success, + * or a MOBILE_IMAGE_MOUNTER_E_* error code on error. + */ +LIBIMOBILEDEVICE_API mobile_image_mounter_error_t mobile_image_mounter_roll_cryptex_nonce(mobile_image_mounter_client_t client); #ifdef __cplusplus } diff --git a/include/libimobiledevice/mobileactivation.h b/include/libimobiledevice/mobileactivation.h new file mode 100644 index 0000000..8e036a8 --- /dev/null +++ b/include/libimobiledevice/mobileactivation.h @@ -0,0 +1,192 @@ +/** + * @file libimobiledevice/mobileactivation.h + * @brief Handle device activation and deactivation. + * \internal + * + * Copyright (c) 2016-2017 Nikias Bassen, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IMOBILEACTIVATION_H +#define IMOBILEACTIVATION_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +/** Service identifier passed to lockdownd_start_service() to start the mobile activation service */ +#define MOBILEACTIVATION_SERVICE_NAME "com.apple.mobileactivationd" + +/** Error Codes */ +typedef enum { + MOBILEACTIVATION_E_SUCCESS = 0, + MOBILEACTIVATION_E_INVALID_ARG = -1, + MOBILEACTIVATION_E_PLIST_ERROR = -2, + MOBILEACTIVATION_E_MUX_ERROR = -3, + MOBILEACTIVATION_E_UNKNOWN_REQUEST = -4, + MOBILEACTIVATION_E_REQUEST_FAILED = -5, + MOBILEACTIVATION_E_UNKNOWN_ERROR = -256 +} mobileactivation_error_t; + +typedef struct mobileactivation_client_private mobileactivation_client_private; /**< \private */ +typedef mobileactivation_client_private *mobileactivation_client_t; /**< The client handle. */ + +/** + * Connects to the mobileactivation 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 + * mobileactivation_client_t upon successful return. + * + * @return MOBILEACTIVATION_E_SUCCESS on success, + * MOBILEACTIVATION_E_INVALID_ARG when one of the parameters is invalid, + * or MOBILEACTIVATION_E_MUX_ERROR when the connection failed. + */ +LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobileactivation_client_t *client); + +/** + * Starts a new mobileactivation service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * mobileactivation_client_t upon successful return. Must be freed using + * mobileactivation_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_* + * error code otherwise. + */ +LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_client_start_service(idevice_t device, mobileactivation_client_t* client, const char* label); + +/** + * Disconnects a mobileactivation client from the device and frees up the + * mobileactivation client data. + * + * @param client The mobileactivation client to disconnect and free. + * + * @return MOBILEACTIVATION_E_SUCCESS on success, + * MOBILEACTIVATION_E_INVALID_ARG when one of client or client->parent + * is invalid, or MOBILEACTIVATION_E_UNKNOWN_ERROR when the was an + * error freeing the parent property_list_service client. + */ +LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_client_free(mobileactivation_client_t client); + + +/** + * Retrieves the device's activation state. + * + * @param client The mobileactivation client. + * @param state Pointer to a plist_t variable that will be set to the + * activation state reported by the mobileactivation service. The + * consumer is responsible for freeing the returned object using + * plist_free(). + * + * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_* + * error code otherwise. + */ +LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_get_activation_state(mobileactivation_client_t client, plist_t *state); + +/** + * Retrieves a session blob required for 'drmHandshake' via albert.apple.com. + * + * @param client The mobileactivation client + * @param blob Pointer to a plist_t variable that will be set to the + * session blob created by the mobielactivation service. The + * consumer is responsible for freeing the returned object using + * plist_free(). + * + * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_* + * error code otherwise. + */ +LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_create_activation_session_info(mobileactivation_client_t client, plist_t *blob); + +/** + * Retrieves the activation info required for device activation. + * + * @param client The mobileactivation client + * @param info Pointer to a plist_t variable that will be set to the + * activation info created by the mobileactivation service. The + * consumer is responsible for freeing the returned object using + * plist_free(). + * + * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_* + * error code otherwise. + */ +LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_create_activation_info(mobileactivation_client_t client, plist_t *info); + +/** + * Retrieves the activation info required for device activation in 'session' + * mode. This function expects a handshake result retrieved from + * https://albert.apple.com/deviceservies/drmHandshake with a blob + * provided by mobileactivation_create_activation_session_info(). + * + * @param client The mobileactivation client + * @param handshake_response The handshake response returned from drmHandshake + * @param info Pointer to a plist_t variable that will be set to the + * activation info created by the mobileactivation service. The + * consumer is responsible for freeing the returned object using + * plist_free(). + * + * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_* + * error code otherwise. + */ +LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_create_activation_info_with_session(mobileactivation_client_t client, plist_t handshake_response, plist_t *info); + +/** + * Activates the device with the given activation record. + * The activation record plist dictionary must be obtained using the + * activation protocol requesting from Apple's https webservice. + * + * @param client The mobileactivation client + * @param activation_record The activation record plist dictionary + * + * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_* + * error code otherwise. + */ +LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_activate(mobileactivation_client_t client, plist_t activation_record); + +/** + * Activates the device with the given activation record in 'session' mode. + * The activation record plist must be obtained using the + * activation protocol requesting from Apple's https webservice. + * + * @param client The mobileactivation client + * @param activation_record The activation record in plist format + * @param headers A plist dictionary with the activation response headers + * as returned from Apple's https webservice with the activation record + * + * @return MOBILEACTIVATION_E_SUCCESS on success, or an MOBILEACTIVATION_E_* + * error code otherwise. + */ +LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_activate_with_session(mobileactivation_client_t client, plist_t activation_record, plist_t headers); + +/** + * Deactivates the device. + * + * @param client The mobileactivation client + */ +LIBIMOBILEDEVICE_API mobileactivation_error_t mobileactivation_deactivate(mobileactivation_client_t client); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/mobilebackup.h b/include/libimobiledevice/mobilebackup.h index 8f31cc4..2ecb60c 100644 --- a/include/libimobiledevice/mobilebackup.h +++ b/include/libimobiledevice/mobilebackup.h @@ -3,7 +3,8 @@ * @brief Backup and restore of all device data. * \internal * - * Copyright (c) 2009 Martin Szulecki All Rights Reserved. + * Copyright (c) 2010-2019 Nikias Bassen, All Rights Reserved. + * Copyright (c) 2009-2014 Martin Szulecki, All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -28,42 +29,215 @@ extern "C" { #endif #include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> -/** @name Error Codes */ -/*@{*/ -#define MOBILEBACKUP_E_SUCCESS 0 -#define MOBILEBACKUP_E_INVALID_ARG -1 -#define MOBILEBACKUP_E_PLIST_ERROR -2 -#define MOBILEBACKUP_E_MUX_ERROR -3 -#define MOBILEBACKUP_E_BAD_VERSION -4 -#define MOBILEBACKUP_E_REPLY_NOT_OK -5 +/** Service identifier passed to lockdownd_start_service() to start the mobilebackup service */ +#define MOBILEBACKUP_SERVICE_NAME "com.apple.mobilebackup" -#define MOBILEBACKUP_E_UNKNOWN_ERROR -256 -/*@}*/ - -/** Represents an error code. */ -typedef int16_t mobilebackup_error_t; +/** Error Codes */ +typedef enum { + MOBILEBACKUP_E_SUCCESS = 0, + MOBILEBACKUP_E_INVALID_ARG = -1, + MOBILEBACKUP_E_PLIST_ERROR = -2, + MOBILEBACKUP_E_MUX_ERROR = -3, + MOBILEBACKUP_E_SSL_ERROR = -4, + MOBILEBACKUP_E_RECEIVE_TIMEOUT = -5, + MOBILEBACKUP_E_BAD_VERSION = -6, + MOBILEBACKUP_E_REPLY_NOT_OK = -7, + MOBILEBACKUP_E_UNKNOWN_ERROR = -256 +} mobilebackup_error_t; -typedef struct mobilebackup_client_private mobilebackup_client_private; +typedef struct mobilebackup_client_private mobilebackup_client_private; /**< \private */ typedef mobilebackup_client_private *mobilebackup_client_t; /**< The client handle. */ +/** Available flags passed to #mobilebackup_request_restore */ typedef enum { MB_RESTORE_NOTIFY_SPRINGBOARD = 1 << 0, MB_RESTORE_PRESERVE_SETTINGS = 1 << 1, MB_RESTORE_PRESERVE_CAMERA_ROLL = 1 << 2 } mobilebackup_flags_t; -mobilebackup_error_t mobilebackup_client_new(idevice_t device, uint16_t port, mobilebackup_client_t * client); -mobilebackup_error_t mobilebackup_client_free(mobilebackup_client_t client); -mobilebackup_error_t mobilebackup_receive(mobilebackup_client_t client, plist_t *plist); -mobilebackup_error_t mobilebackup_send(mobilebackup_client_t client, plist_t plist); -mobilebackup_error_t mobilebackup_request_backup(mobilebackup_client_t client, plist_t backup_manifest, const char *base_path, const char *proto_version); -mobilebackup_error_t mobilebackup_send_backup_file_received(mobilebackup_client_t client); -mobilebackup_error_t mobilebackup_request_restore(mobilebackup_client_t client, plist_t backup_manifest, mobilebackup_flags_t flags, const char *proto_version); -mobilebackup_error_t mobilebackup_receive_restore_file_received(mobilebackup_client_t client, plist_t *result); -mobilebackup_error_t mobilebackup_receive_restore_application_received(mobilebackup_client_t client, plist_t *result); -mobilebackup_error_t mobilebackup_send_restore_complete(mobilebackup_client_t client); -mobilebackup_error_t mobilebackup_send_error(mobilebackup_client_t client, const char *reason); +/** + * Connects to the mobilebackup 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 + * mobilebackup_client_t upon successful return. + * + * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID ARG if one + * or more parameters are invalid, or DEVICE_LINK_SERVICE_E_BAD_VERSION if + * the mobilebackup version on the device is newer. + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobilebackup_client_t * client); + +/** + * Starts a new mobilebackup service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * mobilebackup_client_t upon successful return. Must be freed using + * mobilebackup_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return MOBILEBACKUP_E_SUCCESS on success, or an MOBILEBACKUP_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_client_start_service(idevice_t device, mobilebackup_client_t* client, const char* label); + +/** + * Disconnects a mobilebackup client from the device and frees up the + * mobilebackup client data. + * + * @param client The mobilebackup client to disconnect and free. + * + * @return MOBILEBACKUP_E_SUCCESS on success, or MOBILEBACKUP_E_INVALID_ARG + * if client is NULL. + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_client_free(mobilebackup_client_t client); + + +/** + * Polls the device for mobilebackup data. + * + * @param client The mobilebackup client + * @param plist A pointer to the location where the plist should be stored + * + * @return an error code + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_receive(mobilebackup_client_t client, plist_t *plist); + +/** + * Sends mobilebackup data to the device + * + * @note This function is low-level and should only be used if you need to send + * a new type of message. + * + * @param client The mobilebackup client + * @param plist The location of the plist to send + * + * @return an error code + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_send(mobilebackup_client_t client, plist_t plist); + +/** + * Request a backup from the connected device. + * + * @param client The connected MobileBackup client to use. + * @param backup_manifest The backup manifest, a plist_t of type PLIST_DICT + * containing the backup state of the last backup. For a first-time backup + * set this parameter to NULL. + * @param base_path The base path on the device to use for the backup + * operation, usually "/". + * @param proto_version A string denoting the version of the backup protocol + * to use. Latest known version is "1.6" + * + * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if + * one of the parameters is invalid, MOBILEBACKUP_E_PLIST_ERROR if + * backup_manifest is not of type PLIST_DICT, MOBILEBACKUP_E_MUX_ERROR + * if a communication error occurs, MOBILEBACKUP_E_REPLY_NOT_OK + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_request_backup(mobilebackup_client_t client, plist_t backup_manifest, const char *base_path, const char *proto_version); + +/** + * Sends a confirmation to the device that a backup file has been received. + * + * @param client The connected MobileBackup client to use. + * + * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if + * client is invalid, or MOBILEBACKUP_E_MUX_ERROR if a communication error + * occurs. + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_send_backup_file_received(mobilebackup_client_t client); + +/** + * Request that a backup should be restored to the connected device. + * + * @param client The connected MobileBackup client to use. + * @param backup_manifest The backup manifest, a plist_t of type PLIST_DICT + * containing the backup state to be restored. + * @param flags Flags to send with the request. Currently this is a combination + * of the following mobilebackup_flags_t: + * MB_RESTORE_NOTIFY_SPRINGBOARD - let SpringBoard show a 'Restore' screen + * MB_RESTORE_PRESERVE_SETTINGS - do not overwrite any settings + * MB_RESTORE_PRESERVE_CAMERA_ROLL - preserve the photos of the camera roll + * @param proto_version A string denoting the version of the backup protocol + * to use. Latest known version is "1.6". Ideally this value should be + * extracted from the given manifest plist. + * + * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if + * one of the parameters is invalid, MOBILEBACKUP_E_PLIST_ERROR if + * backup_manifest is not of type PLIST_DICT, MOBILEBACKUP_E_MUX_ERROR + * if a communication error occurs, or MOBILEBACKUP_E_REPLY_NOT_OK + * if the device did not accept the request. + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_request_restore(mobilebackup_client_t client, plist_t backup_manifest, mobilebackup_flags_t flags, const char *proto_version); + +/** + * Receive a confirmation from the device that it successfully received + * a restore file. + * + * @param client The connected MobileBackup client to use. + * @param result Pointer to a plist_t that will be set to the received plist + * for further processing. The caller has to free it using plist_free(). + * Note that it will be set to NULL if the operation itself fails due to + * a communication or plist error. + * If this parameter is NULL, it will be ignored. + * + * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if + * client is invalid, MOBILEBACKUP_E_REPLY_NOT_OK if the expected + * 'BackupMessageRestoreFileReceived' message could not be received, + * MOBILEBACKUP_E_PLIST_ERROR if the received message is not a valid backup + * message plist, or MOBILEBACKUP_E_MUX_ERROR if a communication error + * occurs. + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_receive_restore_file_received(mobilebackup_client_t client, plist_t *result); + +/** + * Receive a confirmation from the device that it successfully received + * application data file. + * + * @param client The connected MobileBackup client to use. + * @param result Pointer to a plist_t that will be set to the received plist + * for further processing. The caller has to free it using plist_free(). + * Note that it will be set to NULL if the operation itself fails due to + * a communication or plist error. + * If this parameter is NULL, it will be ignored. + * + * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if + * client is invalid, MOBILEBACKUP_E_REPLY_NOT_OK if the expected + * 'BackupMessageRestoreApplicationReceived' message could not be received, + * MOBILEBACKUP_E_PLIST_ERROR if the received message is not a valid backup + * message plist, or MOBILEBACKUP_E_MUX_ERROR if a communication error + * occurs. + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_receive_restore_application_received(mobilebackup_client_t client, plist_t *result); + +/** + * Tells the device that the restore process is complete and waits for the + * device to close the connection. After that, the device should reboot. + * + * @param client The connected MobileBackup client to use. + * + * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if + * client is invalid, MOBILEBACKUP_E_PLIST_ERROR if the received disconnect + * message plist is invalid, or MOBILEBACKUP_E_MUX_ERROR if a communication + * error occurs. + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_send_restore_complete(mobilebackup_client_t client); + +/** + * Sends a backup error message to the device. + * + * @param client The connected MobileBackup client to use. + * @param reason A string describing the reason for the error message. + * + * @return MOBILEBACKUP_E_SUCCESS on success, MOBILEBACKUP_E_INVALID_ARG if + * one of the parameters is invalid, or MOBILEBACKUP_E_MUX_ERROR if a + * communication error occurs. + */ +LIBIMOBILEDEVICE_API mobilebackup_error_t mobilebackup_send_error(mobilebackup_client_t client, const char *reason); #ifdef __cplusplus } diff --git a/include/libimobiledevice/mobilebackup2.h b/include/libimobiledevice/mobilebackup2.h new file mode 100644 index 0000000..2e9222d --- /dev/null +++ b/include/libimobiledevice/mobilebackup2.h @@ -0,0 +1,214 @@ +/** + * @file libimobiledevice/mobilebackup2.h + * @brief Backup and restore of all device data (mobilebackup2, iOS4+ only) + * \internal + * + * Copyright (c) 2010-2019 Nikias Bassen, All Rights Reserved. + * Copyright (c) 2011-2014 Martin Szulecki, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IMOBILEBACKUP2_H +#define IMOBILEBACKUP2_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +/** Service identifier passed to lockdownd_start_service() to start the mobilebackup2 service */ +#define MOBILEBACKUP2_SERVICE_NAME "com.apple.mobilebackup2" + +/** Error Codes */ +typedef enum { + MOBILEBACKUP2_E_SUCCESS = 0, + MOBILEBACKUP2_E_INVALID_ARG = -1, + MOBILEBACKUP2_E_PLIST_ERROR = -2, + MOBILEBACKUP2_E_MUX_ERROR = -3, + MOBILEBACKUP2_E_SSL_ERROR = -4, + MOBILEBACKUP2_E_RECEIVE_TIMEOUT = -5, + MOBILEBACKUP2_E_BAD_VERSION = -6, + MOBILEBACKUP2_E_REPLY_NOT_OK = -7, + MOBILEBACKUP2_E_NO_COMMON_VERSION = -8, + MOBILEBACKUP2_E_UNKNOWN_ERROR = -256 +} mobilebackup2_error_t; + +typedef struct mobilebackup2_client_private mobilebackup2_client_private; /**< \private */ +typedef mobilebackup2_client_private *mobilebackup2_client_t; /**< The client handle. */ + + +/** + * Connects to the mobilebackup2 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 + * mobilebackup2_client_t upon successful return. + * + * @return MOBILEBACKUP2_E_SUCCESS on success, MOBILEBACKUP2_E_INVALID ARG + * if one or more parameter is invalid, or MOBILEBACKUP2_E_BAD_VERSION + * if the mobilebackup2 version on the device is newer. + */ +LIBIMOBILEDEVICE_API mobilebackup2_error_t mobilebackup2_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobilebackup2_client_t * client); + +/** + * Starts a new mobilebackup2 service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * mobilebackup2_client_t upon successful return. Must be freed using + * mobilebackup2_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return MOBILEBACKUP2_E_SUCCESS on success, or an MOBILEBACKUP2_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API mobilebackup2_error_t mobilebackup2_client_start_service(idevice_t device, mobilebackup2_client_t* client, const char* label); + +/** + * Disconnects a mobilebackup2 client from the device and frees up the + * mobilebackup2 client data. + * + * @param client The mobilebackup2 client to disconnect and free. + * + * @return MOBILEBACKUP2_E_SUCCESS on success, or MOBILEBACKUP2_E_INVALID_ARG + * if client is NULL. + */ +LIBIMOBILEDEVICE_API mobilebackup2_error_t mobilebackup2_client_free(mobilebackup2_client_t client); + + +/** + * Sends a backup message plist. + * + * @param client The connected MobileBackup client to use. + * @param message The message to send. This will be inserted into the request + * plist as value for MessageName. If this parameter is NULL, + * the plist passed in the options parameter will be sent directly. + * @param options Additional options as PLIST_DICT to add to the request. + * The MessageName key with the value passed in the message parameter + * will be inserted into this plist before sending it. This parameter + * can be NULL if message is not NULL. + */ +LIBIMOBILEDEVICE_API mobilebackup2_error_t mobilebackup2_send_message(mobilebackup2_client_t client, const char *message, plist_t options); + +/** + * Receives a DL* message plist from the device. + * This function is a wrapper around device_link_service_receive_message. + * + * @param client The connected MobileBackup client to use. + * @param msg_plist Pointer to a plist that will be set to the contents of the + * message plist upon successful return. + * @param dlmessage A pointer that will be set to a newly allocated char* + * containing the DL* string from the given plist. It is up to the caller + * to free the allocated memory. If this parameter is NULL + * it will be ignored. + * + * @return MOBILEBACKUP2_E_SUCCESS if a DL* message was received, + * MOBILEBACKUP2_E_INVALID_ARG if client or message is invalid, + * MOBILEBACKUP2_E_PLIST_ERROR if the received plist is invalid + * or is not a DL* message plist, or MOBILEBACKUP2_E_MUX_ERROR if + * receiving from the device failed. + */ +LIBIMOBILEDEVICE_API mobilebackup2_error_t mobilebackup2_receive_message(mobilebackup2_client_t client, plist_t *msg_plist, char **dlmessage); + +/** + * Send binary data to the device. + * + * @note This function returns MOBILEBACKUP2_E_SUCCESS even if less than the + * requested length has been sent. The fourth parameter is required and + * must be checked to ensure if the whole data has been sent. + * + * @param client The MobileBackup client to send to. + * @param data Pointer to the data to send + * @param length Number of bytes to send + * @param bytes Number of bytes actually sent + * + * @return MOBILEBACKUP2_E_SUCCESS if any data was successfully sent, + * MOBILEBACKUP2_E_INVALID_ARG if one of the parameters is invalid, + * or MOBILEBACKUP2_E_MUX_ERROR if sending of the data failed. + */ +LIBIMOBILEDEVICE_API mobilebackup2_error_t mobilebackup2_send_raw(mobilebackup2_client_t client, const char *data, uint32_t length, uint32_t *bytes); + +/** + * Receive binary from the device. + * + * @note This function returns MOBILEBACKUP2_E_SUCCESS even if no data + * has been received (unless a communication error occurred). + * The fourth parameter is required and must be checked to know how + * many bytes were actually received. + * + * @param client The MobileBackup client to receive from. + * @param data Pointer to a buffer that will be filled with the received data. + * @param length Number of bytes to receive. The data buffer needs to be large + * enough to store this amount of data. + * @param bytes Number of bytes actually received. + * + * @return MOBILEBACKUP2_E_SUCCESS if any or no data was received, + * MOBILEBACKUP2_E_INVALID_ARG if one of the parameters is invalid, + * or MOBILEBACKUP2_E_MUX_ERROR if receiving the data failed. + */ +LIBIMOBILEDEVICE_API mobilebackup2_error_t mobilebackup2_receive_raw(mobilebackup2_client_t client, char *data, uint32_t length, uint32_t *bytes); + +/** + * Performs the mobilebackup2 protocol version exchange. + * + * @param client The MobileBackup client to use. + * @param local_versions An array of supported versions to send to the remote. + * @param count The number of items in local_versions. + * @param remote_version Holds the protocol version of the remote on success. + * + * @return MOBILEBACKUP2_E_SUCCESS on success, or a MOBILEBACKUP2_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API mobilebackup2_error_t mobilebackup2_version_exchange(mobilebackup2_client_t client, double local_versions[], char count, double *remote_version); + +/** + * Send a request to the connected mobilebackup2 service. + * + * @param client + * @param request The request to send to the backup service. + * Currently, this is one of "Backup", "Restore", "Info", or "List". + * @param target_identifier UDID of the target device. + * @param source_identifier UDID of backup data? + * @param options Additional options in a plist of type PLIST_DICT. + * + * @return MOBILEBACKUP2_E_SUCCESS if the request was successfully sent, + * or a MOBILEBACKUP2_E_* error value otherwise. + */ +LIBIMOBILEDEVICE_API mobilebackup2_error_t mobilebackup2_send_request(mobilebackup2_client_t client, const char *request, const char *target_identifier, const char *source_identifier, plist_t options); + +/** + * 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. + */ +LIBIMOBILEDEVICE_API mobilebackup2_error_t mobilebackup2_send_status_response(mobilebackup2_client_t client, int status_code, const char *status1, plist_t status2); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/mobilesync.h b/include/libimobiledevice/mobilesync.h index 7658b7d..c3bc53d 100644 --- a/include/libimobiledevice/mobilesync.h +++ b/include/libimobiledevice/mobilesync.h @@ -3,6 +3,9 @@ * @brief Synchronize data classes with a device and computer. * \internal * + * Copyright (c) 2010-2019 Nikias Bassen, All Rights Reserved. + * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. + * Copyright (c) 2014 Christophe Fergeau All Rights Reserved. * Copyright (c) 2010 Bryan Forbes All Rights Reserved. * Copyright (c) 2009 Jonathan Beck All Rights Reserved. * @@ -29,22 +32,26 @@ extern "C" { #endif #include <libimobiledevice/libimobiledevice.h> -#include <glib.h> - -/** @name Error Codes */ -/*@{*/ -#define MOBILESYNC_E_SUCCESS 0 -#define MOBILESYNC_E_INVALID_ARG -1 -#define MOBILESYNC_E_PLIST_ERROR -2 -#define MOBILESYNC_E_MUX_ERROR -3 -#define MOBILESYNC_E_BAD_VERSION -4 -#define MOBILESYNC_E_SYNC_REFUSED -5 -#define MOBILESYNC_E_CANCELLED -6 -#define MOBILESYNC_E_WRONG_DIRECTION -7 -#define MOBILESYNC_E_NOT_READY -8 - -#define MOBILESYNC_E_UNKNOWN_ERROR -256 -/*@}*/ +#include <libimobiledevice/lockdown.h> + +/** Service identifier passed to lockdownd_start_service() to start the mobilesync service */ +#define MOBILESYNC_SERVICE_NAME "com.apple.mobilesync" + +/** Error Codes */ +typedef enum { + MOBILESYNC_E_SUCCESS = 0, + MOBILESYNC_E_INVALID_ARG = -1, + MOBILESYNC_E_PLIST_ERROR = -2, + MOBILESYNC_E_MUX_ERROR = -3, + MOBILESYNC_E_SSL_ERROR = -4, + MOBILESYNC_E_RECEIVE_TIMEOUT = -5, + MOBILESYNC_E_BAD_VERSION = -6, + MOBILESYNC_E_SYNC_REFUSED = -7, + MOBILESYNC_E_CANCELLED = -8, + MOBILESYNC_E_WRONG_DIRECTION = -9, + MOBILESYNC_E_NOT_READY = -10, + MOBILESYNC_E_UNKNOWN_ERROR = -256 +} mobilesync_error_t; /** The sync type of the current sync session. */ typedef enum { @@ -53,48 +60,297 @@ typedef enum { MOBILESYNC_SYNC_TYPE_RESET /**< Reset-sync signals that the computer should send all data again. */ } mobilesync_sync_type_t; -/** Represents an error code. */ -typedef int16_t mobilesync_error_t; - -typedef struct mobilesync_client_private mobilesync_client_private; +typedef struct mobilesync_client_private mobilesync_client_private; /**< \private */ typedef mobilesync_client_private *mobilesync_client_t; /**< The client handle */ +/** Anchors used by the device and computer (structure) */ typedef struct { - char *device_anchor; - char *computer_anchor; + char *device_anchor; /**< device anchor */ + char *computer_anchor; /**< computer anchor */ } mobilesync_anchors; -typedef mobilesync_anchors *mobilesync_anchors_t; /**< Anchors used by the device and computer. */ +/** Anchors used by the device and computer */ +typedef mobilesync_anchors *mobilesync_anchors_t; /* Interface */ -mobilesync_error_t mobilesync_client_new(idevice_t device, uint16_t port, mobilesync_client_t * client); -mobilesync_error_t mobilesync_client_free(mobilesync_client_t client); -mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist_t *plist); -mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist_t plist); +/** + * Connects to the mobilesync 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 + * #mobilesync_client_t upon successful return. + * + * @retval MOBILESYNC_E_SUCCESS on success + * @retval MOBILESYNC_E_INVALID_ARG if one or more parameters are invalid + * @retval DEVICE_LINK_SERVICE_E_BAD_VERSION if the mobilesync version on + * the device is newer. + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_client_new(idevice_t device, lockdownd_service_descriptor_t service, mobilesync_client_t * client); + +/** + * Starts a new mobilesync service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * mobilesync_client_t upon successful return. Must be freed using + * mobilesync_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return MOBILESYNC_E_SUCCESS on success, or an MOBILESYNC_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_client_start_service(idevice_t device, mobilesync_client_t* client, const char* label); + +/** + * Disconnects a mobilesync client from the device and frees up the + * mobilesync client data. + * + * @param client The mobilesync client to disconnect and free. + * + * @retval MOBILESYNC_E_SUCCESS on success + * @retval MOBILESYNC_E_INVALID_ARG if \a client is NULL. + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_client_free(mobilesync_client_t client); + + +/** + * Polls the device for mobilesync data. + * + * @param client The mobilesync client + * @param plist A pointer to the location where the plist should be stored + * + * @return an error code + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_receive(mobilesync_client_t client, plist_t *plist); + +/** + * Sends mobilesync data to the device + * + * @note This function is low-level and should only be used if you need to send + * a new type of message. + * + * @param client The mobilesync client + * @param plist The location of the plist to send + * + * @return an error code + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_send(mobilesync_client_t client, plist_t plist); + + +/** + * 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 + */ +LIBIMOBILEDEVICE_API 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); + +/** + * Cancels a running synchronization session with a device at any time. + * + * @param client The mobilesync client + * @param reason The reason to supply to the device for cancelling + * + * @retval MOBILESYNC_E_SUCCESS on success + * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_cancel(mobilesync_client_t client, const char* reason); + +/** + * Finish a synchronization session of a data class on the device. + * A session must have previously been started using mobilesync_start(). + * + * @param client The mobilesync client + * + * @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 + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_finish(mobilesync_client_t client); + + +/** + * Requests to receive all records of the currently set data class from the device. + * The actually changes are retrieved using mobilesync_receive_changes() after this + * request has been successful. + * + * @param client The mobilesync client + * + * @retval MOBILESYNC_E_SUCCESS on success + * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_get_all_records_from_device(mobilesync_client_t client); + +/** + * Requests to receive only changed records of the currently set data class from the device. + * The actually changes are retrieved using mobilesync_receive_changes() after this + * request has been successful. + * + * @param client The mobilesync client + * + * @retval MOBILESYNC_E_SUCCESS on success + * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_get_changes_from_device(mobilesync_client_t client); + +/** + * Requests the device to delete all records of the current data class + * + * @note The operation must be called after starting synchronization. + * + * @param client The mobilesync client + * + * @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 + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_clear_all_records_on_device(mobilesync_client_t client); -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); -mobilesync_error_t mobilesync_cancel(mobilesync_client_t client, const char* reason); -mobilesync_error_t mobilesync_finish(mobilesync_client_t client); -mobilesync_error_t mobilesync_get_all_records_from_device(mobilesync_client_t client); -mobilesync_error_t mobilesync_get_changes_from_device(mobilesync_client_t client); -mobilesync_error_t mobilesync_clear_all_records_on_device(mobilesync_client_t client); +/** + * 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 + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_receive_changes(mobilesync_client_t client, plist_t *entities, uint8_t *is_last_record, plist_t *actions); + +/** + * Acknowledges to the device that the changes have been merged on the computer + * + * @param client The mobilesync client + * + * @retval MOBILESYNC_E_SUCCESS on success + * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_acknowledge_changes_from_device(mobilesync_client_t client); -mobilesync_error_t mobilesync_receive_changes(mobilesync_client_t client, plist_t *entities, uint8_t *is_last_record, plist_t *actions); -mobilesync_error_t mobilesync_acknowledge_changes_from_device(mobilesync_client_t client); -mobilesync_error_t mobilesync_ready_to_send_changes_from_computer(mobilesync_client_t client); +/** + * Verifies if the device is ready to receive changes from the computer. + * This call changes the synchronization direction so that mobilesync_send_changes() + * can be used to send changes to the device. + * + * @param client The mobilesync client + * + * @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_WRONG_DIRECTION if the current sync direction does + * not permit this call + * @retval MOBILESYNC_E_CANCELLED if the device explicitly cancelled the + * session + * @retval MOBILESYNC_E_NOT_READY if the device is not ready to start + * receiving any changes + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_ready_to_send_changes_from_computer(mobilesync_client_t client); + + +/** + * Sends changed entities of the currently set data class to the device + * + * @param client The mobilesync client + * @param entities The changed entity records as a PLIST_DICT + * @param is_last_record A flag indicating if this submission is the last one + * @param actions Additional actions for the device created with mobilesync_actions_new() + * or NULL if no actions should be passed + * + * @retval MOBILESYNC_E_SUCCESS on success + * @retval MOBILESYNC_E_INVALID_ARG if one of the parameters is invalid, + * @retval MOBILESYNC_E_WRONG_DIRECTION if the current sync direction does + * not permit this call + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_send_changes(mobilesync_client_t client, plist_t entities, uint8_t is_last_record, plist_t actions); -mobilesync_error_t mobilesync_send_changes(mobilesync_client_t client, plist_t entities, uint8_t is_last_record, plist_t actions); -mobilesync_error_t mobilesync_remap_identifiers(mobilesync_client_t client, plist_t *mapping); +/** + * Receives any remapped identifiers reported after the device merged submitted changes. + * + * @param client The mobilesync client + * @param mapping A pointer to an array plist containing a dict of identifier remappings + * + * @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_WRONG_DIRECTION if the current sync direction does + * not permit this call + * @retval MOBILESYNC_E_CANCELLED if the device explicitly cancelled the + * session + */ +LIBIMOBILEDEVICE_API mobilesync_error_t mobilesync_remap_identifiers(mobilesync_client_t client, plist_t *mapping); /* Helper */ -mobilesync_anchors_t mobilesync_anchors_new(const char *device_anchor, const char *computer_anchor); -void mobilesync_anchors_free(mobilesync_anchors_t anchors); -plist_t mobilesync_actions_new(); -void mobilesync_actions_add(plist_t actions, ...) G_GNUC_NULL_TERMINATED; -void mobilesync_actions_free(plist_t actions); +/** + * Allocates memory for a new anchors struct initialized with the passed anchors. + * + * @param device_anchor An anchor the device reported the last time or NULL + * if none is known yet which for instance is true on first synchronization. + * @param computer_anchor An arbitrary string to use as anchor for the computer. + * + * @return A new #mobilesync_anchors_t struct. Must be freed using mobilesync_anchors_free(). + */ +LIBIMOBILEDEVICE_API mobilesync_anchors_t mobilesync_anchors_new(const char *device_anchor, const char *computer_anchor); + +/** + * Free memory used by anchors. + * + * @param anchors The anchors to free. + */ +LIBIMOBILEDEVICE_API void mobilesync_anchors_free(mobilesync_anchors_t anchors); + + +/** + * Create a new actions plist to use in mobilesync_send_changes(). + * + * @return A new plist_t of type PLIST_DICT. + */ +LIBIMOBILEDEVICE_API plist_t mobilesync_actions_new(void); + +/** + * Add one or more new key:value pairs to the given actions plist. + * + * @param actions The actions to modify. + * @param ... KEY, VALUE, [KEY, VALUE], NULL + * + * @note The known keys so far are "SyncDeviceLinkEntityNamesKey" which expects + * an array of entity names, followed by a count paramter as well as + * "SyncDeviceLinkAllRecordsOfPulledEntityTypeSentKey" which expects an + * integer to use as a boolean value indicating that the device should + * link submitted changes and report remapped identifiers. + */ +LIBIMOBILEDEVICE_API void mobilesync_actions_add(plist_t actions, ...); + +/** + * Free actions plist. + * + * @param actions The actions plist to free. Does nothing if NULL is passed. + */ +LIBIMOBILEDEVICE_API void mobilesync_actions_free(plist_t actions); #ifdef __cplusplus } diff --git a/include/libimobiledevice/notification_proxy.h b/include/libimobiledevice/notification_proxy.h index 43c479d..f4f090b 100644 --- a/include/libimobiledevice/notification_proxy.h +++ b/include/libimobiledevice/notification_proxy.h @@ -3,7 +3,8 @@ * @brief Observe and post notifications. * \internal * - * Copyright (c) 2009 Nikias Bassen All Rights Reserved. + * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. + * Copyright (c) 2009-2010 Nikias Bassen All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,45 +21,49 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef NOTIFICATION_PROXY_H -#define NOTIFICATION_PROXY_H +#ifndef INOTIFICATION_PROXY_H +#define INOTIFICATION_PROXY_H #ifdef __cplusplus extern "C" { #endif #include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> -/** @name Error Codes */ -/*@{*/ -#define NP_E_SUCCESS 0 -#define NP_E_INVALID_ARG -1 -#define NP_E_PLIST_ERROR -2 -#define NP_E_CONN_FAILED -3 +/** Service identifier passed to lockdownd_start_service() to start the notification proxy service */ +#define NP_SERVICE_NAME "com.apple.mobile.notification_proxy" -#define NP_E_UNKNOWN_ERROR -256 -/*@}*/ - -/** Represents an error code. */ -typedef int16_t np_error_t; +/** Error Codes */ +typedef enum { + NP_E_SUCCESS = 0, + NP_E_INVALID_ARG = -1, + NP_E_PLIST_ERROR = -2, + NP_E_CONN_FAILED = -3, + NP_E_UNKNOWN_ERROR = -256 +} np_error_t; /** - * @name Notifications that can be send + * @name Notifications that can be sent * * For use with np_post_notification() (client --> device) */ +/**@{*/ +//! @cond #define NP_SYNC_WILL_START "com.apple.itunes-mobdev.syncWillStart" #define NP_SYNC_DID_START "com.apple.itunes-mobdev.syncDidStart" #define NP_SYNC_DID_FINISH "com.apple.itunes-mobdev.syncDidFinish" #define NP_SYNC_LOCK_REQUEST "com.apple.itunes-mobdev.syncLockRequest" -/*@}*/ +//! @endcond +/**@}*/ /** * @name Notifications that can be received * * For use with np_observe_notification() (device --> client) */ -/*@{*/ +/**@{*/ +//! @cond #define NP_SYNC_CANCEL_REQUEST "com.apple.itunes-client.syncCancelRequest" #define NP_SYNC_SUSPEND_REQUEST "com.apple.itunes-client.syncSuspendRequest" #define NP_SYNC_RESUME_REQUEST "com.apple.itunes-client.syncResumeRequest" @@ -81,21 +86,114 @@ typedef int16_t np_error_t; #define NP_ITDBPREP_DID_END "com.apple.itdbprep.notification.didEnd" #define NP_LANGUAGE_CHANGED "com.apple.language.changed" #define NP_ADDRESS_BOOK_PREF_CHANGED "com.apple.AddressBook.PreferenceChanged" -/*@}*/ +//! @endcond +/**@}*/ -typedef struct np_client_private np_client_private; +typedef struct np_client_private np_client_private; /**< \private */ typedef np_client_private *np_client_t; /**< The client handle. */ -/** Reports which notification was received. */ +/** Callback function that reports which notification was received. */ typedef void (*np_notify_cb_t) (const char *notification, void *user_data); /* Interface */ -np_error_t np_client_new(idevice_t device, uint16_t port, np_client_t *client); -np_error_t np_client_free(np_client_t client); -np_error_t np_post_notification(np_client_t client, const char *notification); -np_error_t np_observe_notification(np_client_t client, const char *notification); -np_error_t np_observe_notifications(np_client_t client, const char **notification_spec); -np_error_t np_set_notify_callback(np_client_t client, np_notify_cb_t notify_cb, void *userdata); + +/** + * 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. + */ +LIBIMOBILEDEVICE_API np_error_t np_client_new(idevice_t device, lockdownd_service_descriptor_t service, np_client_t *client); + +/** + * Starts a new notification proxy service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * np_client_t upon successful return. Must be freed using + * np_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return NP_E_SUCCESS on success, or an NP_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API np_error_t np_client_start_service(idevice_t device, np_client_t* client, const char* label); + +/** + * Disconnects a notification_proxy client from the device and frees up the + * notification_proxy client data. + * + * @param client The notification_proxy client to disconnect and free. + * + * @return NP_E_SUCCESS on success, or NP_E_INVALID_ARG when client is NULL. + */ +LIBIMOBILEDEVICE_API np_error_t np_client_free(np_client_t client); + + +/** + * Sends a notification to the device's notification_proxy. + * + * @param client The client to send to + * @param notification The notification message to send + * + * @return NP_E_SUCCESS on success, or an error returned by np_plist_send + */ +LIBIMOBILEDEVICE_API np_error_t np_post_notification(np_client_t client, const char *notification); + +/** + * Tells the device to send a notification on the specified event. + * + * @param client The client to send to + * @param notification The notifications that should be observed. + * + * @return NP_E_SUCCESS on success, NP_E_INVALID_ARG when client or + * notification are NULL, or an error returned by np_plist_send. + */ +LIBIMOBILEDEVICE_API np_error_t np_observe_notification(np_client_t client, const char *notification); + +/** + * Tells the device to send a notification on specified events. + * + * @param client The client to send to + * @param notification_spec Specification of the notifications that should be + * observed. This is expected to be an array of const char* that MUST have a + * terminating NULL entry. + * + * @return NP_E_SUCCESS on success, NP_E_INVALID_ARG when client is null, + * or an error returned by np_observe_notification. + */ +LIBIMOBILEDEVICE_API np_error_t np_observe_notifications(np_client_t client, const char **notification_spec); + +/** + * This function allows an application to define a callback function that will + * be called when a notification has been received. + * It will start a thread that polls for notifications and calls the callback + * function if a notification has been received. + * In case of an error condition when polling for notifications - e.g. device + * disconnect - the thread will call the callback function with an empty + * notification "" and terminate itself. + * + * @param client the NP client + * @param notify_cb pointer to a callback function or NULL to de-register a + * previously set callback function. + * @param user_data Pointer that will be passed to the callback function as + * user data. If notify_cb is NULL, this parameter is ignored. + * + * @note Only one callback function can be registered at the same time; + * any previously set callback function will be removed automatically. + * + * @return NP_E_SUCCESS when the callback was successfully registered, + * NP_E_INVALID_ARG when client is NULL, or NP_E_UNKNOWN_ERROR when + * the callback thread could no be created. + */ +LIBIMOBILEDEVICE_API np_error_t np_set_notify_callback(np_client_t client, np_notify_cb_t notify_cb, void *user_data); #ifdef __cplusplus } diff --git a/include/libimobiledevice/preboard.h b/include/libimobiledevice/preboard.h new file mode 100644 index 0000000..0d89eb4 --- /dev/null +++ b/include/libimobiledevice/preboard.h @@ -0,0 +1,187 @@ +/** + * @file libimobiledevice/preboard.h + * @brief Service to 'preboard' a device, which allows to ask for passcode during firmware updates. + * \internal + * + * Copyright (c) 2019 Nikias Bassen, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IPREBOARD_H +#define IPREBOARD_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +/** Service identifier passed to lockdownd_start_service() to start the preboard service */ +#define PREBOARD_SERVICE_NAME "com.apple.preboardservice_v2" + +/** Error Codes */ +typedef enum { + PREBOARD_E_SUCCESS = 0, + PREBOARD_E_INVALID_ARG = -1, + PREBOARD_E_PLIST_ERROR = -2, + PREBOARD_E_MUX_ERROR = -3, + PREBOARD_E_SSL_ERROR = -4, + PREBOARD_E_NOT_ENOUGH_DATA = -5, + PREBOARD_E_TIMEOUT = -6, + PREBOARD_E_OP_IN_PROGRESS = -10, + PREBOARD_E_UNKNOWN_ERROR = -256 +} preboard_error_t; + +typedef struct preboard_client_private preboard_client_private; /**< \private */ +typedef preboard_client_private *preboard_client_t; /**< The client handle. */ + +/** Reports the status response of the given command */ +typedef void (*preboard_status_cb_t) (plist_t message, void *user_data); + +/** + * Connects to the preboard 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 + * preboard_client_t upon successful return. Must be freed using + * preboard_client_free() after use. + * + * @return PREBOARD_E_SUCCESS on success, PREBOARD_E_INVALID_ARG when + * client is NULL, or an PREBOARD_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API preboard_error_t preboard_client_new(idevice_t device, lockdownd_service_descriptor_t service, preboard_client_t * client); + +/** + * Starts a new preboard service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * preboard_client_t upon successful return. Must be freed using + * preboard_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return PREBOARD_E_SUCCESS on success, or a PREBOARD_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API preboard_error_t preboard_client_start_service(idevice_t device, preboard_client_t * client, const char* label); + +/** + * Disconnects a preboard client from the device and frees up the + * preboard client data. + * + * @param client The preboard client to disconnect and free. + * + * @return PREBOARD_E_SUCCESS on success, PREBOARD_E_INVALID_ARG when + * client is NULL, or a PREBOARD_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API preboard_error_t preboard_client_free(preboard_client_t client); + +/** + * Sends a plist to the service. + * + * @param client The preboard client + * @param plist The plist to send + * + * @return PREBOARD_E_SUCCESS on success, + * PREBOARD_E_INVALID_ARG when client or plist is NULL, + * or a PREBOARD_E_* error code on error + */ +LIBIMOBILEDEVICE_API preboard_error_t preboard_send(preboard_client_t client, plist_t plist); + +/** + * Receives a plist from the service. + * + * @param client The preboard client + * @param plist Pointer to a plist_t what will be set to the received plist + * + * @return PREBOARD_E_SUCCESS on success, + * PREBOARD_E_INVALID_ARG when client or plist is NULL, + * PREBOARD_E_TIMEOUT when no data was received after 5 seconds, + * or a PREBOARD_E_* error code on error + */ +LIBIMOBILEDEVICE_API preboard_error_t preboard_receive(preboard_client_t client, plist_t * plist); + +/** + * Receives a plist from the service with the specified timeout. + * + * @param client The preboard client + * @param plist Pointer to a plist_t what will be set to the received plist + * @param timeout_ms Timeout in milliseconds + * + * @return PREBOARD_E_SUCCESS on success, + * PREBOARD_E_INVALID_ARG when client or plist is NULL, + * PREBOARD_E_TIMEOUT when no data was received after the given timeout, + * or a PREBOARD_E_* error code on error. + */ +LIBIMOBILEDEVICE_API preboard_error_t preboard_receive_with_timeout(preboard_client_t client, plist_t * plist, uint32_t timeout_ms); + +/** + * Tells the preboard service to create a stashbag. This will make the device + * show a passcode entry so it can generate and store a token that is later + * used during restore. + * + * @param client The preboard client + * @param manifest An optional manifest + * @param status_cb Callback function that will receive status and error messages. + * Can be NULL if you want to handle receiving messages in your own code. + * @param user_data User data for callback function or NULL. + * + * The callback or following preboard_receive* invocations will usually + * receive a dictionary with: + * { ShowDialog: true } + * If the user does not enter a passcode, after 2 minutes a timeout is reached + * and the device sends a dictionary with: + * { Timeout: true } + * followed by { HideDialog: true } + * If the user aborts the passcode entry, the device sends a dictionary: + * { Error: 1, ErrorString: \<error string\> } + * followed by { HideDialog: true } + * + * @return PREBOARD_E_SUCCESS if the command was successfully submitted, + * PREBOARD_E_INVALID_ARG when client is invalid, + * or a PREBOARD_E_* error code on error. + */ +LIBIMOBILEDEVICE_API preboard_error_t preboard_create_stashbag(preboard_client_t client, plist_t manifest, preboard_status_cb_t status_cb, void *user_data); + +/** + * Instructs the preboard service to commit a previously created stashbag. + * + * @param client The preboard client to use for receiving + * @param manifest An optional manifest + * @param status_cb Callback function that will receive status and error messages + * Can be NULL if you want to handle receiving messages in your own code. + * @param user_data User data for callback function or NULL. + * + * The callback or following preboard_receive* invocations will usually + * receive a dictionary with: + * { StashbagCommitComplete: true } + * or in case of an error: + * { StashbagCommitComplete: 0, Error: 1, \<optional\> ErrorString: \<error string\> } + * + * @return PREBOARD_E_SUCCESS if the command was successfully submitted, + * PREBOARD_E_INVALID_ARG when client is invalid, + * or a PREBOARD_E_* error code on error. + */ +LIBIMOBILEDEVICE_API preboard_error_t preboard_commit_stashbag(preboard_client_t client, plist_t manifest, preboard_status_cb_t status_cb, void *user_data); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/property_list_service.h b/include/libimobiledevice/property_list_service.h new file mode 100644 index 0000000..e6b26a3 --- /dev/null +++ b/include/libimobiledevice/property_list_service.h @@ -0,0 +1,184 @@ +/** + * @file libimobiledevice/property_list_service.h + * @brief Definitions for the PropertyList service + * \internal + * + * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. + * Copyright (c) 2010-2014 Nikias Bassen, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IPROPERTY_LIST_SERVICE_H +#define IPROPERTY_LIST_SERVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/lockdown.h> +#include <libimobiledevice/service.h> + +/** Error Codes */ +typedef enum { + PROPERTY_LIST_SERVICE_E_SUCCESS = 0, + PROPERTY_LIST_SERVICE_E_INVALID_ARG = -1, + PROPERTY_LIST_SERVICE_E_PLIST_ERROR = -2, + PROPERTY_LIST_SERVICE_E_MUX_ERROR = -3, + PROPERTY_LIST_SERVICE_E_SSL_ERROR = -4, + PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT = -5, + PROPERTY_LIST_SERVICE_E_NOT_ENOUGH_DATA = -6, + PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR = -256 +} property_list_service_error_t; + +typedef struct property_list_service_client_private property_list_service_private; /**< \private */ +typedef property_list_service_private* property_list_service_client_t; /**< The client handle. */ + +/* Interface */ + +/** + * Creates a new property list service for the specified port. + * + * @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 + * property_list_service_client_t upon successful return. + * + * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, + * PROPERTY_LIST_SERVICE_E_INVALID_ARG when one of the arguments is invalid, + * or PROPERTY_LIST_SERVICE_E_MUX_ERROR when connecting to the device failed. + */ +LIBIMOBILEDEVICE_API property_list_service_error_t property_list_service_client_new(idevice_t device, lockdownd_service_descriptor_t service, property_list_service_client_t *client); + +/** + * Frees a PropertyList service. + * + * @param client The property list service to free. + * + * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, + * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client is invalid, or a + * PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when another error occurred. + */ +LIBIMOBILEDEVICE_API property_list_service_error_t property_list_service_client_free(property_list_service_client_t client); + +/** + * Sends an XML plist. + * + * @param client The property list service client to use for sending. + * @param plist plist to send + * + * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, + * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or plist is NULL, + * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when dict is not a valid plist, + * or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified error occurs. + */ +LIBIMOBILEDEVICE_API property_list_service_error_t property_list_service_send_xml_plist(property_list_service_client_t client, plist_t plist); + +/** + * Sends a binary plist. + * + * @param client The property list service client to use for sending. + * @param plist plist to send + * + * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, + * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or plist is NULL, + * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when dict is not a valid plist, + * or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified error occurs. + */ +LIBIMOBILEDEVICE_API property_list_service_error_t property_list_service_send_binary_plist(property_list_service_client_t client, plist_t plist); + +/** + * Receives a plist using the given property list service client with specified + * timeout. + * Binary or XML plists are automatically handled. + * + * @param client The property list service client to use for receiving + * @param plist pointer to a plist_t that will point to the received plist + * upon successful return + * @param timeout Maximum time in milliseconds to wait for data. + * + * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, + * PROPERTY_LIST_SERVICE_E_INVALID_ARG when connection or *plist is NULL, + * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be + * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a + * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when + * an unspecified error occurs. + */ +LIBIMOBILEDEVICE_API property_list_service_error_t property_list_service_receive_plist_with_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout); + +/** + * Receives a plist using the given property list service client. + * Binary or XML plists are automatically handled. + * + * This function is like property_list_service_receive_plist_with_timeout + * using a timeout of 10 seconds. + * @see property_list_service_receive_plist_with_timeout + * + * @param client The property list service client to use for receiving + * @param plist pointer to a plist_t that will point to the received plist + * upon successful return + * + * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, + * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or *plist is NULL, + * PROPERTY_LIST_SERVICE_E_NOT_ENOUGH_DATA when not enough data + * received, PROPERTY_LIST_SERVICE_E_RECEIVE_TIMEOUT when the connection times out, + * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be + * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a + * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when + * an unspecified error occurs. + */ +LIBIMOBILEDEVICE_API property_list_service_error_t property_list_service_receive_plist(property_list_service_client_t client, plist_t *plist); + +/** + * Enable SSL for the given property list service client. + * + * @param client The connected property list service client for which SSL + * should be enabled. + * + * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, + * PROPERTY_LIST_SERVICE_E_INVALID_ARG if one or more of the arguments are invalid, + * PROPERTY_LIST_SERVICE_E_SSL_ERROR when SSL could not be enabled, + * or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR otherwise. + */ +LIBIMOBILEDEVICE_API property_list_service_error_t property_list_service_enable_ssl(property_list_service_client_t client); + +/** + * Disable SSL for the given property list service client. + * + * @param client The connected property list service client for which SSL + * should be disabled. + * + * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, + * PROPERTY_LIST_SERVICE_E_INVALID_ARG if one or more of the arguments are invalid, + * or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR otherwise. + */ +LIBIMOBILEDEVICE_API property_list_service_error_t property_list_service_disable_ssl(property_list_service_client_t client); + +/** + * Return a handle to the parent #service_client_t of the given property list service client. + * + * @param client The property list service client + * @param service_client Pointer to be assigned to the parent #service_client_t + * + * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, + * PROPERTY_LIST_SERVICE_E_INVALID_ARG if one or more of the arguments are invalid. + */ +LIBIMOBILEDEVICE_API property_list_service_error_t property_list_service_get_service_client(property_list_service_client_t client, service_client_t *service_client); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/restore.h b/include/libimobiledevice/restore.h index 9c30b03..859dc98 100644 --- a/include/libimobiledevice/restore.h +++ b/include/libimobiledevice/restore.h @@ -1,8 +1,10 @@ /** * @file libimobiledevice/restore.h * @brief Initiate restore process or reboot device. + * @note This service is only available if the device is in restore mode. * \internal * + * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. * Copyright (c) 2010 Joshua Hill. All Rights Reserved. * * This library is free software; you can redistribute it and/or @@ -20,8 +22,8 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef RESTORE_H -#define RESTORE_H +#ifndef IRESTORE_H +#define IRESTORE_H #ifdef __cplusplus extern "C" { @@ -29,41 +31,146 @@ extern "C" { #include <libimobiledevice/libimobiledevice.h> -/** @name Error Codes */ -/*@{*/ -#define RESTORE_E_SUCCESS 0 -#define RESTORE_E_INVALID_ARG -1 -#define RESTORE_E_INVALID_CONF -2 -#define RESTORE_E_PLIST_ERROR -3 -#define RESTORE_E_DICT_ERROR -4 -#define RESTORE_E_NOT_ENOUGH_DATA -5 -#define RESTORE_E_MUX_ERROR -6 -#define RESTORE_E_START_RESTORE_FAILED -7 +/** Error Codes */ +typedef enum { + RESTORE_E_SUCCESS = 0, + RESTORE_E_INVALID_ARG = -1, + RESTORE_E_PLIST_ERROR = -2, + RESTORE_E_MUX_ERROR = -3, + RESTORE_E_NOT_ENOUGH_DATA = -4, + RESTORE_E_RECEIVE_TIMEOUT = -5, + RESTORE_E_UNKNOWN_ERROR = -256 +} restored_error_t; -#define RESTORE_E_UNKNOWN_ERROR -256 -/*@}*/ - -/** Represents an error code. */ -typedef int16_t restored_error_t; - -typedef struct restored_client_private restored_client_private; +typedef struct restored_client_private restored_client_private; /**< \private */ typedef restored_client_private *restored_client_t; /**< The client handle. */ /* Interface */ -restored_error_t restored_client_new(idevice_t device, restored_client_t *client, const char *label); -restored_error_t restored_client_free(restored_client_t client); -restored_error_t restored_query_type(restored_client_t client, char **type, uint64_t *version); -restored_error_t restored_get_value(restored_client_t client, const char *key, plist_t *value) ; -restored_error_t restored_send(restored_client_t client, plist_t plist); -restored_error_t restored_receive(restored_client_t client, plist_t *plist); -restored_error_t restored_goodbye(restored_client_t client); +/** + * 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, RESTORE_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API restored_error_t restored_client_new(idevice_t device, restored_client_t *client, const char *label); + +/** + * Closes the restored client session if one is running and frees up the + * restored_client struct. + * + * @param client The restore client + * + * @return RESTORE_E_SUCCESS on success, RESTORE_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API restored_error_t restored_client_free(restored_client_t client); + + +/** + * Query the type of the service daemon. Depending on whether the device is + * queried in normal mode or restore mode, different types will be returned. + * + * @param client The restored client + * @param type The type returned by the service daemon. Pass NULL to ignore. + * @param version The restore protocol version. Pass NULL to ignore. + * + * @return RESTORE_E_SUCCESS on success, RESTORE_E_INVALID_ARG when client is NULL + */ +LIBIMOBILEDEVICE_API restored_error_t restored_query_type(restored_client_t client, char **type, uint64_t *version); + +/** + * Queries a value from the device specified by a key. + * + * @param client An initialized restored client. + * @param key The key name to request + * @param value A plist node representing the result value node + * + * @return RESTORE_E_SUCCESS on success, RESTORE_E_INVALID_ARG when client is NULL, RESTORE_E_PLIST_ERROR if value for key can't be found + */ +LIBIMOBILEDEVICE_API restored_error_t restored_query_value(restored_client_t client, const char *key, plist_t *value); + +/** + * Retrieves a value from information plist specified by a key. + * + * @param client An initialized restored client. + * @param key The key name to request or NULL to query for all keys + * @param value A plist node representing the result value node + * + * @return RESTORE_E_SUCCESS on success, RESTORE_E_INVALID_ARG when client is NULL, RESTORE_E_PLIST_ERROR if value for key can't be found + */ +LIBIMOBILEDEVICE_API restored_error_t restored_get_value(restored_client_t client, const char *key, plist_t *value) ; + +/** + * Sends a plist to restored. + * + * @note This function is low-level and should only be used if you need to send + * a new type of message. + * + * @param client The restored client + * @param plist The plist to send + * + * @return RESTORE_E_SUCCESS on success, RESTORE_E_INVALID_ARG when client or + * plist is NULL + */ +LIBIMOBILEDEVICE_API restored_error_t restored_send(restored_client_t client, plist_t plist); + +/** + * Receives a plist from restored. + * + * @param client The restored client + * @param plist The plist to store the received data + * + * @return RESTORE_E_SUCCESS on success, RESTORE_E_INVALID_ARG when client or + * plist is NULL + */ +LIBIMOBILEDEVICE_API restored_error_t restored_receive(restored_client_t client, plist_t *plist); + +/** + * Sends the Goodbye request to restored signaling the end of communication. + * + * @param client The restore client + * + * @return RESTORE_E_SUCCESS on success, RESTORE_E_INVALID_ARG when client is NULL, + * RESTORE_E_PLIST_ERROR if the device did not acknowledge the request + */ +LIBIMOBILEDEVICE_API restored_error_t restored_goodbye(restored_client_t client); -restored_error_t restored_start_restore(restored_client_t client); -restored_error_t restored_reboot(restored_client_t client); + +/** + * 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, RESTORE_E_INVALID_ARG if a parameter + * is NULL, RESTORE_E_START_RESTORE_FAILED if the request fails + */ +LIBIMOBILEDEVICE_API restored_error_t restored_start_restore(restored_client_t client, plist_t options, uint64_t version); + +/** + * Requests device to reboot. + * + * @param client The restored client + * + * @return RESTORE_E_SUCCESS on success, RESTORE_E_INVALID_ARG if a parameter + * is NULL + */ +LIBIMOBILEDEVICE_API restored_error_t restored_reboot(restored_client_t client); /* Helper */ -void restored_client_set_label(restored_client_t client, const char *label); + +/** + * Sets the label to send for requests to restored. + * + * @param client The restore client + * @param label The label to set or NULL to disable sending a label + * + */ +LIBIMOBILEDEVICE_API void restored_client_set_label(restored_client_t client, const char *label); #ifdef __cplusplus } diff --git a/include/libimobiledevice/reverse_proxy.h b/include/libimobiledevice/reverse_proxy.h new file mode 100644 index 0000000..5e2f54b --- /dev/null +++ b/include/libimobiledevice/reverse_proxy.h @@ -0,0 +1,213 @@ +/** + * @file libimobiledevice/reverse_proxy.h + * @brief Provide a reverse proxy to allow the device to communicate through, + * which is used during firmware restore. + * \internal + * + * Copyright (c) 2021 Nikias Bassen, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IREVERSE_PROXY_H +#define IREVERSE_PROXY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> + +#define REVERSE_PROXY_DEFAULT_PORT 1082 /**< default port the reverse proxy is listening on */ + +/** Error Codes */ +typedef enum { + REVERSE_PROXY_E_SUCCESS = 0, + REVERSE_PROXY_E_INVALID_ARG = -1, + REVERSE_PROXY_E_PLIST_ERROR = -2, + REVERSE_PROXY_E_MUX_ERROR = -3, + REVERSE_PROXY_E_SSL_ERROR = -4, + REVERSE_PROXY_E_NOT_ENOUGH_DATA = -5, + REVERSE_PROXY_E_TIMEOUT = -6, + REVERSE_PROXY_E_UNKNOWN_ERROR = -256 +} reverse_proxy_error_t; + +typedef struct reverse_proxy_client_private reverse_proxy_client_private; /**< \private */ +typedef reverse_proxy_client_private *reverse_proxy_client_t; /**< The client handle. */ + +/** reverse proxy client type */ +typedef enum { + RP_TYPE_CTRL = 1, /**< control connection */ + RP_TYPE_CONN /**< proxy connection */ +} reverse_proxy_client_type_t; + +/** reverse proxy status for reverse_proxy_status_cb_t callback */ +typedef enum { + RP_STATUS_READY = 1, /**< proxy is ready */ + RP_STATUS_TERMINATE, /**< proxy terminated */ + RP_STATUS_CONNECT_REQ, /**< connection request received (only RP_TYPE_CTRL) */ + RP_STATUS_SHUTDOWN_REQ, /**< shutdown request received (only RP_TYPE_CTRL) */ + RP_STATUS_CONNECTED, /**< connection established (only RP_TYPE_CONN) */ + RP_STATUS_DISCONNECTED, /**< connection closed (only RP_TYPE_CONN) */ +} reverse_proxy_status_t; + +/** reverse proxy data direction passed to reverse_proxy_data_cb_t callback */ +typedef enum { + RP_DATA_DIRECTION_OUT = 1, /**< data going out to remote host */ + RP_DATA_DIRECTION_IN /**< data coming in from remote host */ +} reverse_proxy_data_direction_t; + +/** + * Log callback function prototype. + * + * @param client The client that called the callback function + * @param log_msg The log message + * @param user_data The user_data pointer that was set when registering the callback + */ +typedef void (*reverse_proxy_log_cb_t) (reverse_proxy_client_t client, const char* log_msg, void* user_data); + +/** + * Data callback function prototype. + * + * @param client The client that called the callback function + * @param direction The direction of the data, either RP_DATA_DIRECTION_OUT or RP_DATA_DIRECTION_IN + * @param buffer The data buffer + * @param length The length of the data buffer + * @param user_data The user_data pointer that was set when registering the callback + */ +typedef void (*reverse_proxy_data_cb_t) (reverse_proxy_client_t client, reverse_proxy_data_direction_t direction, const char* buffer, uint32_t length, void* user_data); + +/** + * Status callback function prototype. + * + * @param client The client that called the callback function + * @param status The status the client is reporting + * @param status_msg A status message the client reports along with the status + * @param user_data The user_data pointer that was set when registering the callback + */ +typedef void (*reverse_proxy_status_cb_t) (reverse_proxy_client_t client, reverse_proxy_status_t status, const char* status_msg, void* user_data); + +/** + * Create a reverse proxy client using com.apple.PurpleReverseProxy.Ctrl and + * com.apple.PurpleReverseProxy.Conn lockdown services. This will open a port + * 1083 on the device that iOS apps could connect to; \b however that is + * only allowed if an app has the com.apple.private.PurpleReverseProxy.allowed + * entitlement, which currently only \c /usr/libexec/fdrhelper holds. + * + * @note This function only creates and initializes the reverse proxy; + * to make it operational, call reverse_proxy_client_start_proxy(). + * + * @param device The device to connect to. + * @param client Pointer that will be set to a newly allocated #reverse_proxy_client_t + * upon successful return. + * @param label A label to pass to lockdownd when creating the service + * connections, usually the program name. + * + * @return REVERSE_PROXY_E_SUCCESS on success, + * or a REVERSE_PROXY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API reverse_proxy_error_t reverse_proxy_client_create_with_service(idevice_t device, reverse_proxy_client_t* client, const char* label); + +/** + * Create a reverse proxy client using an open port on the device. This is + * used during firmware restores with the default port REVERSE_PROXY_DEFAULT_PORT (1082). + * + * @note This function only creates and initializes the reverse proxy; + * to make it operational, call reverse_proxy_client_start_proxy(). + * + * @param device The device to connect to. + * @param client Pointer that will be set to a newly allocated reverse_proxy_client_t + * upon successful return. + * @param device_port An open port on the device. Unless it's being used for + * a custom implementation, pass REVERSE_PROXY_DEFAULT_PORT here. + * + * @return REVERSE_PROXY_E_SUCCESS on success, + * or a REVERSE_PROXY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API reverse_proxy_error_t reverse_proxy_client_create_with_port(idevice_t device, reverse_proxy_client_t* client, uint16_t device_port); + +/** + * Disconnects a reverse proxy client and frees up the client data. + * + * @param client The reverse proxy client to disconnect and free. + */ +LIBIMOBILEDEVICE_API reverse_proxy_error_t reverse_proxy_client_free(reverse_proxy_client_t client); + +/** + * Make an initialized reverse proxy client operational, i.e. start the actual proxy. + * + * @param client The reverse proxy client to start. + * @param control_protocol_version The control protocol version to use. + * This is either 1 or 2. Recent devices use 2. + * + * @return REVERSE_PROXY_E_SUCCESS on success, + * or a REVERSE_PROXY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API reverse_proxy_error_t reverse_proxy_client_start_proxy(reverse_proxy_client_t client, int control_protocol_version); + +/** + * Set a status callback function. This allows to report the status of the + * reverse proxy, like Ready, Connect Request, Connected, etc. + * + * @note Set the callback before calling reverse_proxy_client_start_proxy(). + * + * @param client The reverse proxy client + * @param callback The status callback function that will be called + * when the status of the reverse proxy changes. + * @param user_data A pointer that will be passed to the callback function. + */ +LIBIMOBILEDEVICE_API void reverse_proxy_client_set_status_callback(reverse_proxy_client_t client, reverse_proxy_status_cb_t callback, void* user_data); + +/** + * Set a log callback function. Useful for debugging or verbosity. + * + * @note Set the callback before calling reverse_proxy_client_start_proxy(). + * + * @param client The reverse proxy client + * @param callback The log callback function that will be called + * when the reverse proxy logs something. + * @param user_data A pointer that will be passed to the callback function. + */ +LIBIMOBILEDEVICE_API void reverse_proxy_client_set_log_callback(reverse_proxy_client_t client, reverse_proxy_log_cb_t callback, void* user_data); + +/** + * Set a data callback function. Useful for debugging or extra verbosity. + * + * @note Set the callback before calling reverse_proxy_client_start_proxy(). + * + * @param client The reverse proxy client + * @param callback The status callback function that will be called + * when the status of the reverse proxy changes. + * @param user_data A pointer that will be passed to the callback function. + */ + +LIBIMOBILEDEVICE_API void reverse_proxy_client_set_data_callback(reverse_proxy_client_t client, reverse_proxy_data_cb_t callback, void* user_data); + +/** + * Helper function to return the type of a given reverse proxy client, which + * is either RP_TYPE_CTRL or RP_TYPE_CONN. Useful for callback functions. + * @see reverse_proxy_client_type_t + * + * @param client The reverse proxy client + * + * @return The type of the rerverse proxy client + */ +LIBIMOBILEDEVICE_API reverse_proxy_client_type_t reverse_proxy_get_type(reverse_proxy_client_t client); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/sbservices.h b/include/libimobiledevice/sbservices.h index 616168e..7435947 100644 --- a/include/libimobiledevice/sbservices.h +++ b/include/libimobiledevice/sbservices.h @@ -3,7 +3,8 @@ * @brief Manage SpringBoard icons and retrieve icon images. * \internal * - * Copyright (c) 2009 Nikias Bassen All Rights Reserved. + * Copyright (c) 2010-2014 Martin Szulecki All Rights Reserved. + * Copyright (c) 2009-2010 Nikias Bassen All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -20,38 +21,152 @@ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -#ifndef SB_SERVICES_H -#define SB_SERVICES_H +#ifndef ISB_SERVICES_H +#define ISB_SERVICES_H #ifdef __cplusplus extern "C" { #endif #include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> -/** @name Error Codes */ -/*@{*/ -#define SBSERVICES_E_SUCCESS 0 -#define SBSERVICES_E_INVALID_ARG -1 -#define SBSERVICES_E_PLIST_ERROR -2 -#define SBSERVICES_E_CONN_FAILED -3 +/** Service identifier passed to lockdownd_start_service() to start the springboardservices service */ +#define SBSERVICES_SERVICE_NAME "com.apple.springboardservices" -#define SBSERVICES_E_UNKNOWN_ERROR -256 -/*@}*/ +/** Error Codes */ +typedef enum { + SBSERVICES_E_SUCCESS = 0, + SBSERVICES_E_INVALID_ARG = -1, + SBSERVICES_E_PLIST_ERROR = -2, + SBSERVICES_E_CONN_FAILED = -3, + SBSERVICES_E_UNKNOWN_ERROR = -256 +} sbservices_error_t; -/** Represents an error code. */ -typedef int16_t sbservices_error_t; +/** Orientation of the user interface on the device */ +typedef enum { + SBSERVICES_INTERFACE_ORIENTATION_UNKNOWN = 0, + SBSERVICES_INTERFACE_ORIENTATION_PORTRAIT = 1, + SBSERVICES_INTERFACE_ORIENTATION_PORTRAIT_UPSIDE_DOWN = 2, + SBSERVICES_INTERFACE_ORIENTATION_LANDSCAPE_RIGHT = 3, + SBSERVICES_INTERFACE_ORIENTATION_LANDSCAPE_LEFT = 4 +} sbservices_interface_orientation_t; -typedef struct sbservices_client_private sbservices_client_private; +typedef struct sbservices_client_private sbservices_client_private; /**< \private */ typedef sbservices_client_private *sbservices_client_t; /**< The client handle. */ /* Interface */ -sbservices_error_t sbservices_client_new(idevice_t device, uint16_t port, sbservices_client_t *client); -sbservices_error_t sbservices_client_free(sbservices_client_t client); -sbservices_error_t sbservices_get_icon_state(sbservices_client_t client, plist_t *state, const char *format_version); -sbservices_error_t sbservices_set_icon_state(sbservices_client_t client, plist_t newstate); -sbservices_error_t sbservices_get_icon_pngdata(sbservices_client_t client, const char *bundleId, char **pngdata, uint64_t *pngsize); -sbservices_error_t sbservices_get_home_screen_wallpaper_pngdata(sbservices_client_t client, char **pngdata, uint64_t *pngsize); + +/** + * 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. + */ +LIBIMOBILEDEVICE_API sbservices_error_t sbservices_client_new(idevice_t device, lockdownd_service_descriptor_t service, sbservices_client_t *client); + +/** + * Starts a new sbservices service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * sbservices_client_t upon successful return. Must be freed using + * sbservices_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return SBSERVICES_E_SUCCESS on success, or an SBSERVICES_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API sbservices_error_t sbservices_client_start_service(idevice_t device, sbservices_client_t* client, const char* label); + +/** + * Disconnects an sbservices client from the device and frees up the + * sbservices client data. + * + * @param client The sbservices client to disconnect and free. + * + * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when + * client is NULL, or an SBSERVICES_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API sbservices_error_t sbservices_client_free(sbservices_client_t client); + + +/** + * Gets the icon state of the connected device. + * + * @param client The connected sbservices client to use. + * @param state Pointer that will point to a newly allocated plist containing + * the current icon state. It is up to the caller to free the memory. + * @param format_version A string to be passed as formatVersion along with + * the request, or NULL if no formatVersion should be passed. This is only + * supported since iOS 4.0 so for older firmware versions this must be set + * to NULL. + * + * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when + * client or state is invalid, or an SBSERVICES_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API sbservices_error_t sbservices_get_icon_state(sbservices_client_t client, plist_t *state, const char *format_version); + +/** + * Sets the icon state of the connected device. + * + * @param client The connected sbservices client to use. + * @param newstate A plist containing the new iconstate. + * + * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when + * client or newstate is NULL, or an SBSERVICES_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API sbservices_error_t sbservices_set_icon_state(sbservices_client_t client, plist_t newstate); + +/** + * Get the icon of the specified app as PNG data. + * + * @param client The connected sbservices client to use. + * @param bundleId The bundle identifier of the app to retrieve the icon for. + * @param pngdata Pointer that will point to a newly allocated buffer + * containing the PNG data upon successful return. It is up to the caller + * to free the memory. + * @param pngsize Pointer to a uint64_t that will be set to the size of the + * buffer pngdata points to upon successful return. + * + * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when + * client, bundleId, or pngdata are invalid, or an SBSERVICES_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API sbservices_error_t sbservices_get_icon_pngdata(sbservices_client_t client, const char *bundleId, char **pngdata, uint64_t *pngsize); + +/** + * Gets the interface orientation of the device. + * + * @param client The connected sbservices client to use. + * @param interface_orientation The interface orientation upon successful return. + * + * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when + * client or state is invalid, or an SBSERVICES_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API sbservices_error_t sbservices_get_interface_orientation(sbservices_client_t client, sbservices_interface_orientation_t* interface_orientation); + +/** + * Get the home screen wallpaper as PNG data. + * + * @param client The connected sbservices client to use. + * @param pngdata Pointer that will point to a newly allocated buffer + * containing the PNG data upon successful return. It is up to the caller + * to free the memory. + * @param pngsize Pointer to a uint64_t that will be set to the size of the + * buffer pngdata points to upon successful return. + * + * @return SBSERVICES_E_SUCCESS on success, SBSERVICES_E_INVALID_ARG when + * client or pngdata are invalid, or an SBSERVICES_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API sbservices_error_t sbservices_get_home_screen_wallpaper_pngdata(sbservices_client_t client, char **pngdata, uint64_t *pngsize); #ifdef __cplusplus } diff --git a/include/libimobiledevice/screenshotr.h b/include/libimobiledevice/screenshotr.h index b3669ee..db3c969 100644 --- a/include/libimobiledevice/screenshotr.h +++ b/include/libimobiledevice/screenshotr.h @@ -4,7 +4,8 @@ * @note Requires a mounted developer image. * \internal * - * Copyright (c) 2010 Nikias Bassen All Rights Reserved. + * Copyright (c) 2010-2019 Nikias Bassen, All Rights Reserved. + * Copyright (c) 2010-2014 Martin Szulecki, All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -29,27 +30,86 @@ extern "C" { #endif #include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> -/** @name Error Codes */ -/*@{*/ -#define SCREENSHOTR_E_SUCCESS 0 -#define SCREENSHOTR_E_INVALID_ARG -1 -#define SCREENSHOTR_E_PLIST_ERROR -2 -#define SCREENSHOTR_E_MUX_ERROR -3 -#define SCREENSHOTR_E_BAD_VERSION -4 +/** Service identifier passed to lockdownd_start_service() to start the screenshotr service */ +#define SCREENSHOTR_SERVICE_NAME "com.apple.mobile.screenshotr" -#define SCREENSHOTR_E_UNKNOWN_ERROR -256 -/*@}*/ +/** Error Codes */ +typedef enum { + SCREENSHOTR_E_SUCCESS = 0, + SCREENSHOTR_E_INVALID_ARG = -1, + SCREENSHOTR_E_PLIST_ERROR = -2, + SCREENSHOTR_E_MUX_ERROR = -3, + SCREENSHOTR_E_SSL_ERROR = -4, + SCREENSHOTR_E_RECEIVE_TIMEOUT = -5, + SCREENSHOTR_E_BAD_VERSION = -6, + SCREENSHOTR_E_UNKNOWN_ERROR = -256 +} screenshotr_error_t; -/** Represents an error code. */ -typedef int16_t screenshotr_error_t; - -typedef struct screenshotr_client_private screenshotr_client_private; +typedef struct screenshotr_client_private screenshotr_client_private; /**< \private */ typedef screenshotr_client_private *screenshotr_client_t; /**< The client handle. */ -screenshotr_error_t screenshotr_client_new(idevice_t device, uint16_t port, screenshotr_client_t * client); -screenshotr_error_t screenshotr_client_free(screenshotr_client_t client); -screenshotr_error_t screenshotr_take_screenshot(screenshotr_client_t client, char **imgdata, uint64_t *imgsize); + +/** + * Connects to the screenshotr 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 + * screenshotr_client_t upon successful return. + * + * @note This service is only available if a developer disk image has been + * mounted. + * + * @return SCREENSHOTR_E_SUCCESS on success, SCREENSHOTR_E_INVALID ARG if one + * or more parameters are invalid, or SCREENSHOTR_E_CONN_FAILED if the + * connection to the device could not be established. + */ +LIBIMOBILEDEVICE_API screenshotr_error_t screenshotr_client_new(idevice_t device, lockdownd_service_descriptor_t service, screenshotr_client_t * client); + +/** + * Starts a new screenshotr service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * screenshotr_client_t upon successful return. Must be freed using + * screenshotr_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return SCREENSHOTR_E_SUCCESS on success, or an SCREENSHOTR_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API screenshotr_error_t screenshotr_client_start_service(idevice_t device, screenshotr_client_t* client, const char* label); + +/** + * Disconnects a screenshotr client from the device and frees up the + * screenshotr client data. + * + * @param client The screenshotr client to disconnect and free. + * + * @return SCREENSHOTR_E_SUCCESS on success, or SCREENSHOTR_E_INVALID_ARG + * if client is NULL. + */ +LIBIMOBILEDEVICE_API screenshotr_error_t screenshotr_client_free(screenshotr_client_t client); + + +/** + * Get a screen shot from the connected device. + * + * @param client The connection screenshotr service client. + * @param imgdata Pointer that will point to a newly allocated buffer + * containing TIFF image data upon successful return. It is up to the + * caller to free the memory. + * @param imgsize Pointer to a uint64_t that will be set to the size of the + * buffer imgdata points to upon successful return. + * + * @return SCREENSHOTR_E_SUCCESS on success, SCREENSHOTR_E_INVALID_ARG if + * one or more parameters are invalid, or another error code if an + * error occurred. + */ +LIBIMOBILEDEVICE_API screenshotr_error_t screenshotr_take_screenshot(screenshotr_client_t client, char **imgdata, uint64_t *imgsize); #ifdef __cplusplus } diff --git a/include/libimobiledevice/service.h b/include/libimobiledevice/service.h new file mode 100644 index 0000000..f31ada4 --- /dev/null +++ b/include/libimobiledevice/service.h @@ -0,0 +1,202 @@ +/** + * @file libimobiledevice/service.h + * @brief Generic basic service implementation to inherit. + * \internal + * + * Copyright (c) 2013-2014 Martin Szulecki All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ISERVICE_H +#define ISERVICE_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +/** Error Codes */ +typedef enum { + SERVICE_E_SUCCESS = 0, + SERVICE_E_INVALID_ARG = -1, + SERVICE_E_MUX_ERROR = -3, + SERVICE_E_SSL_ERROR = -4, + SERVICE_E_START_SERVICE_ERROR = -5, + SERVICE_E_NOT_ENOUGH_DATA = -6, + SERVICE_E_TIMEOUT = -7, + SERVICE_E_UNKNOWN_ERROR = -256 +} service_error_t; + +typedef struct service_client_private service_client_private; /**< \private */ +typedef service_client_private* service_client_t; /**< The client handle. */ + +/** service constructor cast */ +#define SERVICE_CONSTRUCTOR(x) (int32_t (*)(idevice_t, lockdownd_service_descriptor_t, void**))(x) + +/* Interface */ + +/** + * Creates a new service for the specified service descriptor. + * + * @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 + * service_client_t upon successful return. + * + * @return SERVICE_E_SUCCESS on success, + * SERVICE_E_INVALID_ARG when one of the arguments is invalid, + * or SERVICE_E_MUX_ERROR when connecting to the device failed. + */ +LIBIMOBILEDEVICE_API service_error_t service_client_new(idevice_t device, lockdownd_service_descriptor_t service, service_client_t *client); + +/** + * Starts a new service on the specified device with given name and + * connects to it. + * + * @param device The device to connect to. + * @param service_name The name of the service to start. + * @param client Pointer that will point to a newly allocated service_client_t + * upon successful return. Must be freed using service_client_free() after + * use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * @param constructor_func Constructor function for the service client to create (e.g. afc_client_new()) + * @param error_code Pointer to an int32_t that will receive the service start error code. + * + * @return SERVICE_E_SUCCESS on success, or a SERVICE_E_* error code + * otherwise. + */ +LIBIMOBILEDEVICE_API service_error_t service_client_factory_start_service(idevice_t device, const char* service_name, void **client, const char* label, int32_t (*constructor_func)(idevice_t, lockdownd_service_descriptor_t, void**), int32_t *error_code); + +/** + * Frees a service instance. + * + * @param client The service instance to free. + * + * @return SERVICE_E_SUCCESS on success, + * SERVICE_E_INVALID_ARG when client is invalid, or a + * SERVICE_E_UNKNOWN_ERROR when another error occurred. + */ +LIBIMOBILEDEVICE_API service_error_t service_client_free(service_client_t client); + + +/** + * Sends data using the given service client. + * + * @param client The service client to use for sending. + * @param data Data to send + * @param size Size of the data to send + * @param sent Number of bytes sent (can be NULL to ignore) + * + * @return SERVICE_E_SUCCESS on success, + * SERVICE_E_INVALID_ARG when one or more parameters are + * invalid, or SERVICE_E_UNKNOWN_ERROR when an unspecified + * error occurs. + */ +LIBIMOBILEDEVICE_API service_error_t service_send(service_client_t client, const char *data, uint32_t size, uint32_t *sent); + +/** + * Receives data using the given service client with specified timeout. + * + * @param client The service client to use for receiving + * @param data Buffer that will be filled with the data received + * @param size Number of bytes to receive + * @param received Number of bytes received (can be NULL to ignore) + * @param timeout Maximum time in milliseconds to wait for data. + * + * @return SERVICE_E_SUCCESS on success, + * SERVICE_E_INVALID_ARG when one or more parameters are + * invalid, SERVICE_E_MUX_ERROR when a communication error + * occurs, or SERVICE_E_UNKNOWN_ERROR when an unspecified + * error occurs. + */ +LIBIMOBILEDEVICE_API service_error_t service_receive_with_timeout(service_client_t client, char *data, uint32_t size, uint32_t *received, unsigned int timeout); + +/** + * Receives data using the given service client. + * + * @param client The service client to use for receiving + * @param data Buffer that will be filled with the data received + * @param size Number of bytes to receive + * @param received Number of bytes received (can be NULL to ignore) + * + * @return SERVICE_E_SUCCESS on success, + * SERVICE_E_INVALID_ARG when one or more parameters are + * invalid, SERVICE_E_NOT_ENOUGH_DATA when not enough data + * received, SERVICE_E_TIMEOUT when the connection times out, + * SERVICE_E_MUX_ERROR when a communication error + * occurs, or SERVICE_E_UNKNOWN_ERROR when an unspecified + * error occurs. + */ +LIBIMOBILEDEVICE_API service_error_t service_receive(service_client_t client, char *data, uint32_t size, uint32_t *received); + + +/** + * Enable SSL for the given service client. + * + * @param client The connected service client for that SSL should be enabled. + * + * @return SERVICE_E_SUCCESS on success, + * SERVICE_E_INVALID_ARG if client or client->connection is + * NULL, SERVICE_E_NOT_ENOUGH_DATA when not enough data + * received, SERVICE_E_TIMEOUT when the connection times out, + * SERVICE_E_SSL_ERROR when SSL could not be enabled, + * or SERVICE_E_UNKNOWN_ERROR otherwise. + */ +LIBIMOBILEDEVICE_API service_error_t service_enable_ssl(service_client_t client); + +/** + * Disable SSL for the given service client. + * + * @param client The connected service client for which SSL should be disabled. + * + * @return SERVICE_E_SUCCESS on success, + * SERVICE_E_INVALID_ARG if client or client->connection is + * NULL, or SERVICE_E_UNKNOWN_ERROR otherwise. + */ +LIBIMOBILEDEVICE_API service_error_t service_disable_ssl(service_client_t client); + +/** + * Disable SSL for the given service client, optionally without sending SSL terminate messages. + * + * @param client The connected service client for which SSL should be disabled. + * @param sslBypass A boolean value indicating wether to disable SSL with a proper + * SSL shutdown (0), or bypass the shutdown (1). + * + * @return SERVICE_E_SUCCESS on success, + * SERVICE_E_INVALID_ARG if client or client->connection is + * NULL, or SERVICE_E_UNKNOWN_ERROR otherwise. + */ +LIBIMOBILEDEVICE_API service_error_t service_disable_bypass_ssl(service_client_t client, uint8_t sslBypass); + +/** + * Return a handle to the parent #idevice_connection_t of the given service client. + * + * @param client The service client + * @param connection Pointer to be assigned to the #idevice_connection_t. + * + * @return SERVICE_E_SUCCESS on success, + * SERVICE_E_INVALID_ARG if one or more of the arguments are invalid. + */ +LIBIMOBILEDEVICE_API service_error_t service_get_connection(service_client_t client, idevice_connection_t *connection); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/syslog_relay.h b/include/libimobiledevice/syslog_relay.h new file mode 100644 index 0000000..0f6487a --- /dev/null +++ b/include/libimobiledevice/syslog_relay.h @@ -0,0 +1,184 @@ +/** + * @file libimobiledevice/syslog_relay.h + * @brief Capture the syslog output from a device. + * \internal + * + * Copyright (c) 2019-2020 Nikias Bassen, All Rights Reserved. + * Copyright (c) 2013-2014 Martin Szulecki, All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef ISYSLOG_RELAY_H +#define ISYSLOG_RELAY_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +/** Service identifier passed to lockdownd_start_service() to start the syslog relay service */ +#define SYSLOG_RELAY_SERVICE_NAME "com.apple.syslog_relay" + +/** Error Codes */ +typedef enum { + SYSLOG_RELAY_E_SUCCESS = 0, + SYSLOG_RELAY_E_INVALID_ARG = -1, + SYSLOG_RELAY_E_MUX_ERROR = -2, + SYSLOG_RELAY_E_SSL_ERROR = -3, + SYSLOG_RELAY_E_NOT_ENOUGH_DATA = -4, + SYSLOG_RELAY_E_TIMEOUT = -5, + SYSLOG_RELAY_E_UNKNOWN_ERROR = -256 +} syslog_relay_error_t; + +typedef struct syslog_relay_client_private syslog_relay_client_private; /**< \private */ +typedef syslog_relay_client_private *syslog_relay_client_t; /**< The client handle. */ + +/** Receives each character received from the device. */ +typedef void (*syslog_relay_receive_cb_t)(char c, void *user_data); + +/* Interface */ + +/** + * Connects to the syslog_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 Pointer that will point to a newly allocated + * syslog_relay_client_t upon successful return. Must be freed using + * syslog_relay_client_free() after use. + * + * @return SYSLOG_RELAY_E_SUCCESS on success, SYSLOG_RELAY_E_INVALID_ARG when + * client is NULL, or an SYSLOG_RELAY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_client_new(idevice_t device, lockdownd_service_descriptor_t service, syslog_relay_client_t * client); + +/** + * Starts a new syslog_relay service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * syslog_relay_client_t upon successful return. Must be freed using + * syslog_relay_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return SYSLOG_RELAY_E_SUCCESS on success, or an SYSLOG_RELAY_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_client_start_service(idevice_t device, syslog_relay_client_t * client, const char* label); + +/** + * Disconnects a syslog_relay client from the device and frees up the + * syslog_relay client data. + * + * @param client The syslog_relay client to disconnect and free. + * + * @return SYSLOG_RELAY_E_SUCCESS on success, SYSLOG_RELAY_E_INVALID_ARG when + * client is NULL, or an SYSLOG_RELAY_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_client_free(syslog_relay_client_t client); + + +/** + * Starts capturing the syslog of the device using a callback. + * + * Use syslog_relay_stop_capture() to stop receiving the syslog. + * + * @param client The syslog_relay client to use + * @param callback Callback to receive each character from the syslog. + * @param user_data Custom pointer passed to the callback function. + * + * @return SYSLOG_RELAY_E_SUCCESS on success, + * SYSLOG_RELAY_E_INVALID_ARG when one or more parameters are + * invalid or SYSLOG_RELAY_E_UNKNOWN_ERROR when an unspecified + * error occurs or a syslog capture has already been started. + */ +LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_start_capture(syslog_relay_client_t client, syslog_relay_receive_cb_t callback, void* user_data); + +/** + * Starts capturing the *raw* syslog of the device using a callback. + * This function is like syslog_relay_start_capture with the difference that + * it will neither check nor process the received data before passing it to + * the callback function. + * + * Use syslog_relay_stop_capture() to stop receiving the syslog. + * + * @note Use syslog_relay_start_capture for a safer implementation. + * + * @param client The syslog_relay client to use + * @param callback Callback to receive each character from the syslog. + * @param user_data Custom pointer passed to the callback function. + * + * @return SYSLOG_RELAY_E_SUCCESS on success, + * SYSLOG_RELAY_E_INVALID_ARG when one or more parameters are + * invalid or SYSLOG_RELAY_E_UNKNOWN_ERROR when an unspecified + * error occurs or a syslog capture has already been started. + */ +LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_start_capture_raw(syslog_relay_client_t client, syslog_relay_receive_cb_t callback, void* user_data); + +/** + * Stops capturing the syslog of the device. + * + * Use syslog_relay_start_capture() to start receiving the syslog. + * + * @param client The syslog_relay client to use + * + * @return SYSLOG_RELAY_E_SUCCESS on success, + * SYSLOG_RELAY_E_INVALID_ARG when one or more parameters are + * invalid or SYSLOG_RELAY_E_UNKNOWN_ERROR when an unspecified + * error occurs or a syslog capture has already been started. + */ +LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_stop_capture(syslog_relay_client_t client); + +/* Receiving */ + +/** + * Receives data using the given syslog_relay client with specified timeout. + * + * @param client The syslog_relay client to use for receiving + * @param data Buffer that will be filled with the data received + * @param size Number of bytes to receive + * @param received Number of bytes received (can be NULL to ignore) + * @param timeout Maximum time in milliseconds to wait for data. + * + * @return SYSLOG_RELAY_E_SUCCESS on success, + * SYSLOG_RELAY_E_INVALID_ARG when one or more parameters are + * invalid, SYSLOG_RELAY_E_MUX_ERROR when a communication error + * occurs, or SYSLOG_RELAY_E_UNKNOWN_ERROR when an unspecified + * error occurs. + */ +LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_receive_with_timeout(syslog_relay_client_t client, char *data, uint32_t size, uint32_t *received, unsigned int timeout); + +/** + * Receives data from the service. + * + * @param client The syslog_relay client + * @param data Buffer that will be filled with the data received + * @param size Number of bytes to receive + * @param received Number of bytes received (can be NULL to ignore) + * + * @return SYSLOG_RELAY_E_SUCCESS on success, + * SYSLOG_RELAY_E_INVALID_ARG when client or plist is NULL + */ +LIBIMOBILEDEVICE_API syslog_relay_error_t syslog_relay_receive(syslog_relay_client_t client, char *data, uint32_t size, uint32_t *received); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/include/libimobiledevice/webinspector.h b/include/libimobiledevice/webinspector.h new file mode 100644 index 0000000..16d2ca2 --- /dev/null +++ b/include/libimobiledevice/webinspector.h @@ -0,0 +1,137 @@ +/** + * @file libimobiledevice/webinspector.h + * @brief WebKit Remote Debugging. + * \internal + * + * Copyright (c) 2013-2014 Martin Szulecki All Rights Reserved. + * Copyright (c) 2013 Yury Melnichek All Rights Reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA + */ + +#ifndef IWEBINSPECTOR_H +#define IWEBINSPECTOR_H + +#ifdef __cplusplus +extern "C" { +#endif + +#include <libimobiledevice/libimobiledevice.h> +#include <libimobiledevice/lockdown.h> + +/** Service identifier passed to lockdownd_start_service() to start the webinspector service */ +#define WEBINSPECTOR_SERVICE_NAME "com.apple.webinspector" + +/** Error Codes */ +typedef enum { + WEBINSPECTOR_E_SUCCESS = 0, + WEBINSPECTOR_E_INVALID_ARG = -1, + WEBINSPECTOR_E_PLIST_ERROR = -2, + WEBINSPECTOR_E_MUX_ERROR = -3, + WEBINSPECTOR_E_SSL_ERROR = -4, + WEBINSPECTOR_E_RECEIVE_TIMEOUT = -5, + WEBINSPECTOR_E_NOT_ENOUGH_DATA = -6, + WEBINSPECTOR_E_UNKNOWN_ERROR = -256 +} webinspector_error_t; + +typedef struct webinspector_client_private webinspector_client_private; /**< \private */ +typedef webinspector_client_private *webinspector_client_t; /**< The client handle. */ + + +/** + * Connects to the webinspector 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 + * webinspector_client_t upon successful return. Must be freed using + * webinspector_client_free() after use. + * + * @return WEBINSPECTOR_E_SUCCESS on success, WEBINSPECTOR_E_INVALID_ARG when + * client is NULL, or an WEBINSPECTOR_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API webinspector_error_t webinspector_client_new(idevice_t device, lockdownd_service_descriptor_t service, webinspector_client_t * client); + +/** + * Starts a new webinspector service on the specified device and connects to it. + * + * @param device The device to connect to. + * @param client Pointer that will point to a newly allocated + * webinspector_client_t upon successful return. Must be freed using + * webinspector_client_free() after use. + * @param label The label to use for communication. Usually the program name. + * Pass NULL to disable sending the label in requests to lockdownd. + * + * @return WEBINSPECTOR_E_SUCCESS on success, or an WEBINSPECTOR_E_* error + * code otherwise. + */ +LIBIMOBILEDEVICE_API webinspector_error_t webinspector_client_start_service(idevice_t device, webinspector_client_t * client, const char* label); + +/** + * Disconnects a webinspector client from the device and frees up the + * webinspector client data. + * + * @param client The webinspector client to disconnect and free. + * + * @return WEBINSPECTOR_E_SUCCESS on success, WEBINSPECTOR_E_INVALID_ARG when + * client is NULL, or an WEBINSPECTOR_E_* error code otherwise. + */ +LIBIMOBILEDEVICE_API webinspector_error_t webinspector_client_free(webinspector_client_t client); + + +/** + * Sends a plist to the service. + * + * @param client The webinspector client + * @param plist The plist to send + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, + * DIAGNOSTICS_RELAY_E_INVALID_ARG when client or plist is NULL + */ +LIBIMOBILEDEVICE_API webinspector_error_t webinspector_send(webinspector_client_t client, plist_t plist); + +/** + * Receives a plist from the service. + * + * @param client The webinspector client + * @param plist The plist to store the received data + * + * @return DIAGNOSTICS_RELAY_E_SUCCESS on success, + * DIAGNOSTICS_RELAY_E_INVALID_ARG when client or plist is NULL + */ +LIBIMOBILEDEVICE_API webinspector_error_t webinspector_receive(webinspector_client_t client, plist_t * plist); + +/** + * Receives a plist using the given webinspector client. + * + * @param client The webinspector client to use for receiving + * @param plist pointer to a plist_t that will point to the received plist + * upon successful return + * @param timeout_ms Maximum time in milliseconds to wait for data. + * + * @return WEBINSPECTOR_E_SUCCESS on success, + * WEBINSPECTOR_E_INVALID_ARG when client or *plist is NULL, + * WEBINSPECTOR_E_PLIST_ERROR when the received data cannot be + * converted to a plist, WEBINSPECTOR_E_MUX_ERROR when a + * communication error occurs, or WEBINSPECTOR_E_UNKNOWN_ERROR + * when an unspecified error occurs. + */ +LIBIMOBILEDEVICE_API webinspector_error_t webinspector_receive_with_timeout(webinspector_client_t client, plist_t * plist, uint32_t timeout_ms); + +#ifdef __cplusplus +} +#endif + +#endif |