summaryrefslogtreecommitdiffstats
path: root/include
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2021-11-24 03:46:42 +0100
committerGravatar Nikias Bassen2021-11-24 03:46:42 +0100
commit2c6121db9ad84b8aad05b937e071ff7dcc9c8867 (patch)
treea255055506781da1bd6c0d3cf42f5996189d23a2 /include
parentfa8bfb65c70edd4d2617fbbf970302beb9a4ced2 (diff)
downloadlibimobiledevice-2c6121db9ad84b8aad05b937e071ff7dcc9c8867.tar.gz
libimobiledevice-2c6121db9ad84b8aad05b937e071ff7dcc9c8867.tar.bz2
Add Reverse Proxy implementation
Diffstat (limited to 'include')
-rw-r--r--include/Makefile.am1
-rw-r--r--include/endianness.h12
-rw-r--r--include/libimobiledevice/reverse_proxy.h209
3 files changed, 222 insertions, 0 deletions
diff --git a/include/Makefile.am b/include/Makefile.am
index e23b2a9..2abaf49 100644
--- a/include/Makefile.am
+++ b/include/Makefile.am
@@ -26,5 +26,6 @@ nobase_include_HEADERS = \
libimobiledevice/mobileactivation.h \
libimobiledevice/preboard.h \
libimobiledevice/companion_proxy.h \
+ libimobiledevice/reverse_proxy.h \
libimobiledevice/property_list_service.h \
libimobiledevice/service.h
diff --git a/include/endianness.h b/include/endianness.h
index 2d6ad0e..1d414b3 100644
--- a/include/endianness.h
+++ b/include/endianness.h
@@ -31,6 +31,18 @@
#define htobe16 be16toh
#endif
+#ifndef le16toh
+#if __BYTE_ORDER == __BIG_ENDIAN
+#define le16toh(x) ((((x) & 0xFF00) >> 8) | (((x) & 0x00FF) << 8))
+#else
+#define le16toh(x) (x)
+#endif
+#endif
+
+#ifndef htole16
+#define htole16 le16toh
+#endif
+
#ifndef __bswap_32
#define __bswap_32(x) ((((x) & 0xFF000000) >> 24) \
| (((x) & 0x00FF0000) >> 8) \
diff --git a/include/libimobiledevice/reverse_proxy.h b/include/libimobiledevice/reverse_proxy.h
new file mode 100644
index 0000000..2539bd9
--- /dev/null
+++ b/include/libimobiledevice/reverse_proxy.h
@@ -0,0 +1,209 @@
+/**
+ * @file libimobiledevice/reverse_proxy.h
+ * @brief Provide a reverse proxy to allow the device to communicate through,
+ * which is used during firmware restore.
+ *
+ * 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
+
+/** 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;
+typedef reverse_proxy_client_private *reverse_proxy_client_t; /**< The client handle. */
+
+typedef enum {
+ RP_TYPE_CTRL = 1, /**< control connection */
+ RP_TYPE_CONN /**< proxy connection */
+} reverse_proxy_client_type_t;
+
+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;
+
+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.
+ */
+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.
+ */
+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.
+ */
+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.
+ */
+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.
+ */
+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.
+ */
+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.
+ */
+
+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
+ */
+reverse_proxy_client_type_t reverse_proxy_get_type(reverse_proxy_client_t client);
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif