summaryrefslogtreecommitdiffstats
path: root/include/libimobiledevice/reverse_proxy.h
blob: b7a93ffcb4dd253110ecffad7bdaf0402678a3ba (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
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.
 */
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