summaryrefslogtreecommitdiffstats
path: root/src/lockdown.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lockdown.c')
-rw-r--r--src/lockdown.c586
1 files changed, 343 insertions, 243 deletions
diff --git a/src/lockdown.c b/src/lockdown.c
index e5420a3..80974d2 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -32,16 +32,17 @@
32 32
33extern int debug; 33extern int debug;
34 34
35const ASN1_ARRAY_TYPE pkcs1_asn1_tab[]={ 35const ASN1_ARRAY_TYPE pkcs1_asn1_tab[] = {
36 {"PKCS1",536872976,0}, 36 {"PKCS1", 536872976, 0},
37 {0,1073741836,0}, 37 {0, 1073741836, 0},
38 {"RSAPublicKey",536870917,0}, 38 {"RSAPublicKey", 536870917, 0},
39 {"modulus",1073741827,0}, 39 {"modulus", 1073741827, 0},
40 {"publicExponent",3,0}, 40 {"publicExponent", 3, 0},
41 {0,0,0} 41 {0, 0, 0}
42}; 42};
43 43
44int get_rand(int min, int max) { 44int get_rand(int min, int max)
45{
45 int retval = (rand() % (max - min)) + min; 46 int retval = (rand() % (max - min)) + min;
46 return retval; 47 return retval;
47} 48}
@@ -50,21 +51,22 @@ int get_rand(int min, int max) {
50 * 51 *
51 * @param A null terminated string containing a valid HostID. 52 * @param A null terminated string containing a valid HostID.
52 */ 53 */
53char *lockdownd_generate_hostid() { 54char *lockdownd_generate_hostid()
54 char *hostid = (char*)malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long 55{
56 char *hostid = (char *) malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long
55 const char *chars = "ABCDEF0123456789"; 57 const char *chars = "ABCDEF0123456789";
56 srand(time(NULL)); 58 srand(time(NULL));
57 int i = 0; 59 int i = 0;
58 60
59 for (i = 0; i < 36; i++) { 61 for (i = 0; i < 36; i++) {
60 if (i == 8 || i == 13 || i == 18 || i == 23) { 62 if (i == 8 || i == 13 || i == 18 || i == 23) {
61 hostid[i] = '-'; 63 hostid[i] = '-';
62 continue; 64 continue;
63 } else { 65 } else {
64 hostid[i] = chars[get_rand(0,16)]; 66 hostid[i] = chars[get_rand(0, 16)];
65 } 67 }
66 } 68 }
67 hostid[36] = '\0'; // make it a real string 69 hostid[36] = '\0'; // make it a real string
68 return hostid; 70 return hostid;
69} 71}
70 72
@@ -74,16 +76,18 @@ char *lockdownd_generate_hostid() {
74 * 76 *
75 * @return The lockdownd client. 77 * @return The lockdownd client.
76 */ 78 */
77iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone) { 79iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone)
78 if (!phone) return NULL; 80{
79 iphone_lckd_client_t control = (iphone_lckd_client_t)malloc(sizeof(struct iphone_lckd_client_int)); 81 if (!phone)
82 return NULL;
83 iphone_lckd_client_t control = (iphone_lckd_client_t) malloc(sizeof(struct iphone_lckd_client_int));
80 84
81 if (IPHONE_E_SUCCESS != iphone_mux_new_client ( phone, 0x0a00, 0xf27e, &control->connection)) { 85 if (IPHONE_E_SUCCESS != iphone_mux_new_client(phone, 0x0a00, 0xf27e, &control->connection)) {
82 free(control); 86 free(control);
83 return NULL; 87 return NULL;
84 } 88 }
85 89
86 control->ssl_session = (gnutls_session_t*)malloc(sizeof(gnutls_session_t)); 90 control->ssl_session = (gnutls_session_t *) malloc(sizeof(gnutls_session_t));
87 control->in_SSL = 0; 91 control->in_SSL = 0;
88 control->gtls_buffer_hack_len = 0; 92 control->gtls_buffer_hack_len = 0;
89 return control; 93 return control;
@@ -94,15 +98,18 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone) {
94 * 98 *
95 * @param control The lockdown client 99 * @param control The lockdown client
96 */ 100 */
97iphone_error_t iphone_lckd_free_client( iphone_lckd_client_t client ) { 101iphone_error_t iphone_lckd_free_client(iphone_lckd_client_t client)
98 if (!client) return IPHONE_E_INVALID_ARG; 102{
103 if (!client)
104 return IPHONE_E_INVALID_ARG;
99 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 105 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
100 106
101 if (client->connection) { 107 if (client->connection) {
102 ret = iphone_mux_free_client(client->connection); 108 ret = iphone_mux_free_client(client->connection);
103 } 109 }
104 110
105 if (client->ssl_session) gnutls_deinit(*client->ssl_session); 111 if (client->ssl_session)
112 gnutls_deinit(*client->ssl_session);
106 free(client->ssl_session); 113 free(client->ssl_session);
107 free(client); 114 free(client);
108 return ret; 115 return ret;
@@ -116,24 +123,30 @@ iphone_error_t iphone_lckd_free_client( iphone_lckd_client_t client ) {
116 * 123 *
117 * @return The number of bytes received 124 * @return The number of bytes received
118 */ 125 */
119iphone_error_t iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data, uint32_t *recv_bytes ) { 126iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, char **dump_data, uint32_t * recv_bytes)
120 if (!client || !dump_data || !recv_bytes) return IPHONE_E_INVALID_ARG; 127{
128 if (!client || !dump_data || !recv_bytes)
129 return IPHONE_E_INVALID_ARG;
121 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 130 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
122 char *receive; 131 char *receive;
123 uint32 datalen = 0, bytes = 0; 132 uint32 datalen = 0, bytes = 0;
124 133
125 if (!client->in_SSL) ret = iphone_mux_recv(client->connection, (char *)&datalen, sizeof(datalen), &bytes); 134 if (!client->in_SSL)
135 ret = iphone_mux_recv(client->connection, (char *) &datalen, sizeof(datalen), &bytes);
126 else { 136 else {
127 bytes = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen)); 137 bytes = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen));
128 if (bytes > 0) ret = IPHONE_E_SUCCESS; 138 if (bytes > 0)
139 ret = IPHONE_E_SUCCESS;
129 } 140 }
130 datalen = ntohl(datalen); 141 datalen = ntohl(datalen);
131 142
132 receive = (char*)malloc(sizeof(char) * datalen); 143 receive = (char *) malloc(sizeof(char) * datalen);
133 if (!client->in_SSL) ret = iphone_mux_recv(client->connection, receive, datalen, &bytes); 144 if (!client->in_SSL)
145 ret = iphone_mux_recv(client->connection, receive, datalen, &bytes);
134 else { 146 else {
135 bytes = gnutls_record_recv(*client->ssl_session, receive, datalen); 147 bytes = gnutls_record_recv(*client->ssl_session, receive, datalen);
136 if (bytes > 0) ret = IPHONE_E_SUCCESS; 148 if (bytes > 0)
149 ret = IPHONE_E_SUCCESS;
137 } 150 }
138 *dump_data = receive; 151 *dump_data = receive;
139 *recv_bytes = bytes; 152 *recv_bytes = bytes;
@@ -151,30 +164,34 @@ iphone_error_t iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data,
151 * 164 *
152 * @return The number of bytes sent 165 * @return The number of bytes sent
153 */ 166 */
154iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t length, uint32_t *sent_bytes ) { 167iphone_error_t iphone_lckd_send(iphone_lckd_client_t client, char *raw_data, uint32_t length, uint32_t * sent_bytes)
155 if (!client || !raw_data || length == 0 || !sent_bytes) return IPHONE_E_INVALID_ARG; 168{
169 if (!client || !raw_data || length == 0 || !sent_bytes)
170 return IPHONE_E_INVALID_ARG;
156 char *real_query; 171 char *real_query;
157 int bytes; 172 int bytes;
158 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 173 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
159 174
160 real_query = (char*)malloc(sizeof(char) * (length+4)); 175 real_query = (char *) malloc(sizeof(char) * (length + 4));
161 length = htonl(length); 176 length = htonl(length);
162 memcpy(real_query, &length, sizeof(length)); 177 memcpy(real_query, &length, sizeof(length));
163 memcpy(real_query+4, raw_data, ntohl(length)); 178 memcpy(real_query + 4, raw_data, ntohl(length));
164 if (debug) { 179 if (debug) {
165 printf("lockdownd_send(): made the query, sending it along\n"); 180 printf("lockdownd_send(): made the query, sending it along\n");
166 FILE *packet = fopen("grpkt", "w"); 181 FILE *packet = fopen("grpkt", "w");
167 fwrite(real_query, 1, ntohl(length)+4, packet); 182 fwrite(real_query, 1, ntohl(length) + 4, packet);
168 fclose(packet); 183 fclose(packet);
169 packet = NULL; 184 packet = NULL;
170 } 185 }
171 186
172 if (!client->in_SSL) ret = iphone_mux_send(client->connection, real_query, ntohl(length)+sizeof(length), &bytes); 187 if (!client->in_SSL)
188 ret = iphone_mux_send(client->connection, real_query, ntohl(length) + sizeof(length), &bytes);
173 else { 189 else {
174 gnutls_record_send(*client->ssl_session, real_query, ntohl(length)+sizeof(length)); 190 gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length));
175 ret = IPHONE_E_SUCCESS; 191 ret = IPHONE_E_SUCCESS;
176 } 192 }
177 if (debug) printf("lockdownd_send(): sent it!\n"); 193 if (debug)
194 printf("lockdownd_send(): sent it!\n");
178 free(real_query); 195 free(real_query);
179 *sent_bytes = bytes; 196 *sent_bytes = bytes;
180 return ret; 197 return ret;
@@ -188,46 +205,54 @@ iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, u
188 * 205 *
189 * @return 1 on success and 0 on failure. 206 * @return 1 on success and 0 on failure.
190 */ 207 */
191iphone_error_t lockdownd_hello(iphone_lckd_client_t control) { 208iphone_error_t lockdownd_hello(iphone_lckd_client_t control)
192 if (!control) return IPHONE_E_INVALID_ARG; 209{
210 if (!control)
211 return IPHONE_E_INVALID_ARG;
193 xmlDocPtr plist = new_plist(); 212 xmlDocPtr plist = new_plist();
194 xmlNode *dict, *key; 213 xmlNode *dict, *key;
195 char **dictionary; 214 char **dictionary;
196 int bytes = 0, i = 0; 215 int bytes = 0, i = 0;
197 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 216 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
198 217
199 if (debug) printf("lockdownd_hello() called\n"); 218 if (debug)
219 printf("lockdownd_hello() called\n");
200 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 220 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0);
201 key = add_key_str_dict_element(plist, dict, "Request", "QueryType", 1); 221 key = add_key_str_dict_element(plist, dict, "Request", "QueryType", 1);
202 char *XML_content; 222 char *XML_content;
203 uint32 length; 223 uint32 length;
204 224
205 xmlDocDumpMemory(plist, (xmlChar **)&XML_content, &length); 225 xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length);
206 ret = iphone_lckd_send(control, XML_content, length, &bytes); 226 ret = iphone_lckd_send(control, XML_content, length, &bytes);
207 227
208 xmlFree(XML_content); 228 xmlFree(XML_content);
209 xmlFreeDoc(plist); plist = NULL; 229 xmlFreeDoc(plist);
230 plist = NULL;
210 ret = iphone_lckd_recv(control, &XML_content, &bytes); 231 ret = iphone_lckd_recv(control, &XML_content, &bytes);
211 232
212 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); 233 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0);
213 if (!plist) return IPHONE_E_PLIST_ERROR; 234 if (!plist)
235 return IPHONE_E_PLIST_ERROR;
214 dict = xmlDocGetRootElement(plist); 236 dict = xmlDocGetRootElement(plist);
215 for (dict = dict->children; dict; dict = dict->next) { 237 for (dict = dict->children; dict; dict = dict->next) {
216 if (!xmlStrcmp(dict->name, "dict")) break; 238 if (!xmlStrcmp(dict->name, "dict"))
239 break;
217 } 240 }
218 if (!dict) return IPHONE_E_DICT_ERROR; 241 if (!dict)
242 return IPHONE_E_DICT_ERROR;
219 dictionary = read_dict_element_strings(dict); 243 dictionary = read_dict_element_strings(dict);
220 xmlFreeDoc(plist); 244 xmlFreeDoc(plist);
221 free(XML_content); 245 free(XML_content);
222 246
223 for (i = 0; dictionary[i]; i+=2) { 247 for (i = 0; dictionary[i]; i += 2) {
224 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i+1], "Success")) { 248 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) {
225 if (debug) printf("lockdownd_hello(): success\n"); 249 if (debug)
250 printf("lockdownd_hello(): success\n");
226 ret = IPHONE_E_SUCCESS; 251 ret = IPHONE_E_SUCCESS;
227 break; 252 break;
228 } 253 }
229 } 254 }
230 255
231 free_dictionary(dictionary); 256 free_dictionary(dictionary);
232 return ret; 257 return ret;
233} 258}
@@ -242,7 +267,8 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control) {
242 */ 267 */
243iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, char **value) 268iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, char **value)
244{ 269{
245 if (!control || !req_key || !value || (value && *value)) return IPHONE_E_INVALID_ARG; 270 if (!control || !req_key || !value || (value && *value))
271 return IPHONE_E_INVALID_ARG;
246 xmlDocPtr plist = new_plist(); 272 xmlDocPtr plist = new_plist();
247 xmlNode *dict = NULL; 273 xmlNode *dict = NULL;
248 xmlNode *key = NULL;; 274 xmlNode *key = NULL;;
@@ -251,54 +277,61 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *r
251 char *XML_content = NULL; 277 char *XML_content = NULL;
252 uint32 length = 0; 278 uint32 length = 0;
253 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 279 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
254 280
255 /* Setup DevicePublicKey request plist */ 281 /* Setup DevicePublicKey request plist */
256 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 282 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0);
257 key = add_key_str_dict_element(plist, dict, "Key", req_key, 1); 283 key = add_key_str_dict_element(plist, dict, "Key", req_key, 1);
258 key = add_key_str_dict_element(plist, dict, "Request", "GetValue", 1); 284 key = add_key_str_dict_element(plist, dict, "Request", "GetValue", 1);
259 xmlDocDumpMemory(plist, (xmlChar**)&XML_content, &length); 285 xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length);
260 286
261 /* send to iPhone */ 287 /* send to iPhone */
262 ret = iphone_lckd_send(control, XML_content, length, &bytes); 288 ret = iphone_lckd_send(control, XML_content, length, &bytes);
263 289
264 xmlFree(XML_content); 290 xmlFree(XML_content);
265 xmlFreeDoc(plist); plist = NULL; 291 xmlFreeDoc(plist);
292 plist = NULL;
266 293
267 if (ret != IPHONE_E_SUCCESS) return ret; 294 if (ret != IPHONE_E_SUCCESS)
295 return ret;
268 296
269 /* Now get iPhone's answer */ 297 /* Now get iPhone's answer */
270 ret = iphone_lckd_recv(control, &XML_content, &bytes); 298 ret = iphone_lckd_recv(control, &XML_content, &bytes);
271 299
272 if (ret != IPHONE_E_SUCCESS) return ret; 300 if (ret != IPHONE_E_SUCCESS)
301 return ret;
273 302
274 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); 303 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0);
275 if (!plist) return IPHONE_E_PLIST_ERROR; 304 if (!plist)
305 return IPHONE_E_PLIST_ERROR;
276 dict = xmlDocGetRootElement(plist); 306 dict = xmlDocGetRootElement(plist);
277 for (dict = dict->children; dict; dict = dict->next) { 307 for (dict = dict->children; dict; dict = dict->next) {
278 if (!xmlStrcmp(dict->name, "dict")) break; 308 if (!xmlStrcmp(dict->name, "dict"))
309 break;
279 } 310 }
280 if (!dict) return IPHONE_E_DICT_ERROR; 311 if (!dict)
281 312 return IPHONE_E_DICT_ERROR;
313
282 /* Parse xml to check success and to find public key */ 314 /* Parse xml to check success and to find public key */
283 dictionary = read_dict_element_strings(dict); 315 dictionary = read_dict_element_strings(dict);
284 xmlFreeDoc(plist); 316 xmlFreeDoc(plist);
285 free(XML_content); 317 free(XML_content);
286 318
287 int success = 0; 319 int success = 0;
288 for (i = 0; dictionary[i]; i+=2) { 320 for (i = 0; dictionary[i]; i += 2) {
289 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i+1], "Success")) { 321 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) {
290 success = 1; 322 success = 1;
291 } 323 }
292 if (!strcmp(dictionary[i], "Value")) { 324 if (!strcmp(dictionary[i], "Value")) {
293 *value = strdup(dictionary[i+1]); 325 *value = strdup(dictionary[i + 1]);
294 } 326 }
295 } 327 }
296 328
297 if (dictionary) { 329 if (dictionary) {
298 free_dictionary(dictionary); 330 free_dictionary(dictionary);
299 dictionary = NULL; 331 dictionary = NULL;
300 } 332 }
301 if (success) ret = IPHONE_E_SUCCESS; 333 if (success)
334 ret = IPHONE_E_SUCCESS;
302 return ret; 335 return ret;
303} 336}
304 337
@@ -331,15 +364,15 @@ iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, cha
331 * 364 *
332 * @return 1 on success and 0 on failure 365 * @return 1 on success and 0 on failure
333 */ 366 */
334iphone_error_t iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_client_t *client ) 367iphone_error_t iphone_lckd_new_client(iphone_device_t device, iphone_lckd_client_t * client)
335{ 368{
336 if (!device || !client || (client && *client) ) 369 if (!device || !client || (client && *client))
337 return IPHONE_E_INVALID_ARG; 370 return IPHONE_E_INVALID_ARG;
338 iphone_error_t ret = IPHONE_E_SUCCESS; 371 iphone_error_t ret = IPHONE_E_SUCCESS;
339 char *host_id = NULL; 372 char *host_id = NULL;
340 373
341 iphone_lckd_client_t client_loc = new_lockdownd_client( device ); 374 iphone_lckd_client_t client_loc = new_lockdownd_client(device);
342 if (IPHONE_E_SUCCESS != lockdownd_hello(client_loc)){ 375 if (IPHONE_E_SUCCESS != lockdownd_hello(client_loc)) {
343 fprintf(stderr, "Hello failed in the lockdownd client.\n"); 376 fprintf(stderr, "Hello failed in the lockdownd client.\n");
344 ret = IPHONE_E_NOT_ENOUGH_DATA; 377 ret = IPHONE_E_NOT_ENOUGH_DATA;
345 } 378 }
@@ -347,12 +380,12 @@ iphone_error_t iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_clie
347 380
348 char *uid = NULL; 381 char *uid = NULL;
349 ret = lockdownd_get_device_uid(client_loc, &uid); 382 ret = lockdownd_get_device_uid(client_loc, &uid);
350 if(IPHONE_E_SUCCESS != ret){ 383 if (IPHONE_E_SUCCESS != ret) {
351 fprintf(stderr, "Device refused to send uid.\n"); 384 fprintf(stderr, "Device refused to send uid.\n");
352 } 385 }
353 386
354 host_id = get_host_id(); 387 host_id = get_host_id();
355 if (IPHONE_E_SUCCESS == ret && !host_id){ 388 if (IPHONE_E_SUCCESS == ret && !host_id) {
356 fprintf(stderr, "No HostID found, run libiphone-initconf.\n"); 389 fprintf(stderr, "No HostID found, run libiphone-initconf.\n");
357 ret = IPHONE_E_INVALID_CONF; 390 ret = IPHONE_E_INVALID_CONF;
358 } 391 }
@@ -366,7 +399,7 @@ iphone_error_t iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_clie
366 } 399 }
367 400
368 ret = lockdownd_start_SSL_session(client_loc, host_id); 401 ret = lockdownd_start_SSL_session(client_loc, host_id);
369 if (IPHONE_E_SUCCESS != ret ) { 402 if (IPHONE_E_SUCCESS != ret) {
370 ret = IPHONE_E_SSL_ERROR; 403 ret = IPHONE_E_SSL_ERROR;
371 fprintf(stderr, "SSL Session opening failed.\n"); 404 fprintf(stderr, "SSL Session opening failed.\n");
372 } 405 }
@@ -399,19 +432,19 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
399 char *XML_content = NULL; 432 char *XML_content = NULL;
400 uint32 length = 0; 433 uint32 length = 0;
401 434
402 char* device_cert_b64 = NULL; 435 char *device_cert_b64 = NULL;
403 char* host_cert_b64 = NULL; 436 char *host_cert_b64 = NULL;
404 char* root_cert_b64 = NULL; 437 char *root_cert_b64 = NULL;
405 char *public_key_b64 = NULL; 438 char *public_key_b64 = NULL;
406 439
407 ret = lockdownd_get_device_public_key(control, &public_key_b64); 440 ret = lockdownd_get_device_public_key(control, &public_key_b64);
408 if(ret != IPHONE_E_SUCCESS){ 441 if (ret != IPHONE_E_SUCCESS) {
409 fprintf(stderr, "Device refused to send public key.\n"); 442 fprintf(stderr, "Device refused to send public key.\n");
410 return ret; 443 return ret;
411 } 444 }
412 445
413 ret = lockdownd_gen_pair_cert(public_key_b64, &device_cert_b64, &host_cert_b64, &root_cert_b64); 446 ret = lockdownd_gen_pair_cert(public_key_b64, &device_cert_b64, &host_cert_b64, &root_cert_b64);
414 if(ret != IPHONE_E_SUCCESS){ 447 if (ret != IPHONE_E_SUCCESS) {
415 free(public_key_b64); 448 free(public_key_b64);
416 return ret; 449 return ret;
417 } 450 }
@@ -426,51 +459,55 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
426 add_key_data_dict_element(plist, dictRecord, "RootCertificate", root_cert_b64, 2); 459 add_key_data_dict_element(plist, dictRecord, "RootCertificate", root_cert_b64, 2);
427 add_key_str_dict_element(plist, dict, "Request", "Pair", 1); 460 add_key_str_dict_element(plist, dict, "Request", "Pair", 1);
428 461
429 xmlDocDumpMemory(plist, (xmlChar**)&XML_content, &length); 462 xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length);
430 463
431 printf("XML Pairing request : %s\n",XML_content); 464 printf("XML Pairing request : %s\n", XML_content);
432 465
433 /* send to iPhone */ 466 /* send to iPhone */
434 ret = iphone_lckd_send(control, XML_content, length, &bytes); 467 ret = iphone_lckd_send(control, XML_content, length, &bytes);
435 468
436 xmlFree(XML_content); 469 xmlFree(XML_content);
437 xmlFreeDoc(plist); plist = NULL; 470 xmlFreeDoc(plist);
471 plist = NULL;
438 472
439 if (ret != IPHONE_E_SUCCESS) return ret; 473 if (ret != IPHONE_E_SUCCESS)
474 return ret;
440 475
441 /* Now get iPhone's answer */ 476 /* Now get iPhone's answer */
442 ret = iphone_lckd_recv(control, &XML_content, &bytes); 477 ret = iphone_lckd_recv(control, &XML_content, &bytes);
443 478
444 if (ret != IPHONE_E_SUCCESS) return ret; 479 if (ret != IPHONE_E_SUCCESS)
480 return ret;
445 481
446 if (debug) { 482 if (debug) {
447 printf("lockdown_pair_device: iPhone's response to our pair request:\n"); 483 printf("lockdown_pair_device: iPhone's response to our pair request:\n");
448 fwrite(XML_content, 1, bytes, stdout); 484 fwrite(XML_content, 1, bytes, stdout);
449 printf("\n\n"); 485 printf("\n\n");
450 } 486 }
451 487
452 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); 488 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0);
453 if (!plist) { 489 if (!plist) {
454 free(public_key_b64); 490 free(public_key_b64);
455 return IPHONE_E_PLIST_ERROR; 491 return IPHONE_E_PLIST_ERROR;
456 } 492 }
457 dict = xmlDocGetRootElement(plist); 493 dict = xmlDocGetRootElement(plist);
458 for (dict = dict->children; dict; dict = dict->next) { 494 for (dict = dict->children; dict; dict = dict->next) {
459 if (!xmlStrcmp(dict->name, "dict")) break; 495 if (!xmlStrcmp(dict->name, "dict"))
496 break;
460 } 497 }
461 if (!dict) { 498 if (!dict) {
462 free(public_key_b64); 499 free(public_key_b64);
463 return IPHONE_E_DICT_ERROR; 500 return IPHONE_E_DICT_ERROR;
464 } 501 }
465 502
466 /* Parse xml to check success and to find public key */ 503 /* Parse xml to check success and to find public key */
467 dictionary = read_dict_element_strings(dict); 504 dictionary = read_dict_element_strings(dict);
468 xmlFreeDoc(plist); 505 xmlFreeDoc(plist);
469 free(XML_content); 506 free(XML_content);
470 507
471 int success = 0; 508 int success = 0;
472 for (i = 0; dictionary[i]; i+=2) { 509 for (i = 0; dictionary[i]; i += 2) {
473 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i+1], "Success")) { 510 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) {
474 success = 1; 511 success = 1;
475 } 512 }
476 } 513 }
@@ -482,11 +519,13 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
482 519
483 /* store public key in config if pairing succeeded */ 520 /* store public key in config if pairing succeeded */
484 if (success) { 521 if (success) {
485 if (debug) printf("lockdownd_pair_device: pair success\n"); 522 if (debug)
523 printf("lockdownd_pair_device: pair success\n");
486 store_device_public_key(uid, public_key_b64); 524 store_device_public_key(uid, public_key_b64);
487 ret = IPHONE_E_SUCCESS; 525 ret = IPHONE_E_SUCCESS;
488 } else { 526 } else {
489 if (debug) printf("lockdownd_pair_device: pair failure\n"); 527 if (debug)
528 printf("lockdownd_pair_device: pair failure\n");
490 ret = IPHONE_E_PAIRING_FAILED; 529 ret = IPHONE_E_PAIRING_FAILED;
491 } 530 }
492 free(public_key_b64); 531 free(public_key_b64);
@@ -498,24 +537,26 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
498 * 537 *
499 * @return IPHONE_E_SUCCESS on success. 538 * @return IPHONE_E_SUCCESS on success.
500 */ 539 */
501iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char **host_cert_b64, char **root_cert_b64) 540iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char **host_cert_b64,
541 char **root_cert_b64)
502{ 542{
503 if (!public_key_b64 || !device_cert_b64 || !host_cert_b64 || !root_cert_b64) return IPHONE_E_INVALID_ARG; 543 if (!public_key_b64 || !device_cert_b64 || !host_cert_b64 || !root_cert_b64)
544 return IPHONE_E_INVALID_ARG;
504 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 545 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
505 546
506 gnutls_datum_t modulus = {NULL, 0}; 547 gnutls_datum_t modulus = { NULL, 0 };
507 gnutls_datum_t exponent = {NULL, 0}; 548 gnutls_datum_t exponent = { NULL, 0 };
508 549
509 /* first decode base64 public_key */ 550 /* first decode base64 public_key */
510 gnutls_datum_t pem_pub_key; 551 gnutls_datum_t pem_pub_key;
511 gsize decoded_size; 552 gsize decoded_size;
512 pem_pub_key.data = g_base64_decode (public_key_b64, &decoded_size); 553 pem_pub_key.data = g_base64_decode(public_key_b64, &decoded_size);
513 pem_pub_key.size = decoded_size; 554 pem_pub_key.size = decoded_size;
514 555
515 /* now decode the PEM encoded key */ 556 /* now decode the PEM encoded key */
516 gnutls_datum_t der_pub_key; 557 gnutls_datum_t der_pub_key;
517 if( GNUTLS_E_SUCCESS == gnutls_pem_base64_decode_alloc ("RSA PUBLIC KEY", &pem_pub_key, &der_pub_key) ){ 558 if (GNUTLS_E_SUCCESS == gnutls_pem_base64_decode_alloc("RSA PUBLIC KEY", &pem_pub_key, &der_pub_key)) {
518 559
519 /* initalize asn.1 parser */ 560 /* initalize asn.1 parser */
520 ASN1_TYPE pkcs1 = ASN1_TYPE_EMPTY; 561 ASN1_TYPE pkcs1 = ASN1_TYPE_EMPTY;
521 if (ASN1_SUCCESS == asn1_array2tree(pkcs1_asn1_tab, &pkcs1, NULL)) { 562 if (ASN1_SUCCESS == asn1_array2tree(pkcs1_asn1_tab, &pkcs1, NULL)) {
@@ -526,14 +567,14 @@ iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_
526 if (ASN1_SUCCESS == asn1_der_decoding(&asn1_pub_key, der_pub_key.data, der_pub_key.size, NULL)) { 567 if (ASN1_SUCCESS == asn1_der_decoding(&asn1_pub_key, der_pub_key.data, der_pub_key.size, NULL)) {
527 568
528 /* get size to read */ 569 /* get size to read */
529 int ret1 = asn1_read_value (asn1_pub_key, "modulus", NULL, &modulus.size); 570 int ret1 = asn1_read_value(asn1_pub_key, "modulus", NULL, &modulus.size);
530 int ret2 = asn1_read_value (asn1_pub_key, "publicExponent", NULL, &exponent.size); 571 int ret2 = asn1_read_value(asn1_pub_key, "publicExponent", NULL, &exponent.size);
531 572
532 modulus.data = gnutls_malloc(modulus.size); 573 modulus.data = gnutls_malloc(modulus.size);
533 exponent.data = gnutls_malloc(exponent.size); 574 exponent.data = gnutls_malloc(exponent.size);
534 575
535 ret1 = asn1_read_value (asn1_pub_key, "modulus", modulus.data, &modulus.size); 576 ret1 = asn1_read_value(asn1_pub_key, "modulus", modulus.data, &modulus.size);
536 ret2 = asn1_read_value (asn1_pub_key, "publicExponent", exponent.data, &exponent.size); 577 ret2 = asn1_read_value(asn1_pub_key, "publicExponent", exponent.data, &exponent.size);
537 if (ASN1_SUCCESS == ret1 && ASN1_SUCCESS == ret2) 578 if (ASN1_SUCCESS == ret1 && ASN1_SUCCESS == ret2)
538 ret = IPHONE_E_SUCCESS; 579 ret = IPHONE_E_SUCCESS;
539 } 580 }
@@ -548,34 +589,36 @@ iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_
548 if (IPHONE_E_SUCCESS == ret && 0 != modulus.size && 0 != exponent.size) { 589 if (IPHONE_E_SUCCESS == ret && 0 != modulus.size && 0 != exponent.size) {
549 590
550 gnutls_global_init(); 591 gnutls_global_init();
551 gnutls_datum_t essentially_null = {strdup("abababababababab"), strlen("abababababababab")}; 592 gnutls_datum_t essentially_null = { strdup("abababababababab"), strlen("abababababababab") };
552 593
553 gnutls_x509_privkey_t fake_privkey, root_privkey; 594 gnutls_x509_privkey_t fake_privkey, root_privkey;
554 gnutls_x509_crt_t dev_cert, root_cert, host_cert; 595 gnutls_x509_crt_t dev_cert, root_cert, host_cert;
555 596
556 gnutls_x509_privkey_init(&fake_privkey); 597 gnutls_x509_privkey_init(&fake_privkey);
557 gnutls_x509_crt_init(&dev_cert); 598 gnutls_x509_crt_init(&dev_cert);
558 gnutls_x509_crt_init(&root_cert); 599 gnutls_x509_crt_init(&root_cert);
559 gnutls_x509_crt_init(&host_cert); 600 gnutls_x509_crt_init(&host_cert);
560 601
561 if ( GNUTLS_E_SUCCESS == gnutls_x509_privkey_import_rsa_raw(fake_privkey, &modulus, &exponent, &essentially_null, &essentially_null, &essentially_null, &essentially_null) ) { 602 if (GNUTLS_E_SUCCESS ==
562 603 gnutls_x509_privkey_import_rsa_raw(fake_privkey, &modulus, &exponent, &essentially_null, &essentially_null,
604 &essentially_null, &essentially_null)) {
605
563 gnutls_x509_privkey_init(&root_privkey); 606 gnutls_x509_privkey_init(&root_privkey);
564 607
565 /* get root cert */ 608 /* get root cert */
566 gnutls_datum_t pem_root_cert = {NULL, 0}; 609 gnutls_datum_t pem_root_cert = { NULL, 0 };
567 get_root_certificate(&pem_root_cert); 610 get_root_certificate(&pem_root_cert);
568 if (GNUTLS_E_SUCCESS != gnutls_x509_crt_import(root_cert, &pem_root_cert, GNUTLS_X509_FMT_PEM)) 611 if (GNUTLS_E_SUCCESS != gnutls_x509_crt_import(root_cert, &pem_root_cert, GNUTLS_X509_FMT_PEM))
569 ret = IPHONE_E_SSL_ERROR; 612 ret = IPHONE_E_SSL_ERROR;
570 613
571 /* get host cert */ 614 /* get host cert */
572 gnutls_datum_t pem_host_cert = {NULL, 0}; 615 gnutls_datum_t pem_host_cert = { NULL, 0 };
573 get_host_certificate(&pem_host_cert); 616 get_host_certificate(&pem_host_cert);
574 if (GNUTLS_E_SUCCESS != gnutls_x509_crt_import(host_cert, &pem_host_cert, GNUTLS_X509_FMT_PEM)) 617 if (GNUTLS_E_SUCCESS != gnutls_x509_crt_import(host_cert, &pem_host_cert, GNUTLS_X509_FMT_PEM))
575 ret = IPHONE_E_SSL_ERROR; 618 ret = IPHONE_E_SSL_ERROR;
576 619
577 /* get root private key */ 620 /* get root private key */
578 gnutls_datum_t pem_root_priv = {NULL, 0}; 621 gnutls_datum_t pem_root_priv = { NULL, 0 };
579 get_root_private_key(&pem_root_priv); 622 get_root_private_key(&pem_root_priv);
580 if (GNUTLS_E_SUCCESS != gnutls_x509_privkey_import(root_privkey, &pem_root_priv, GNUTLS_X509_FMT_PEM)) 623 if (GNUTLS_E_SUCCESS != gnutls_x509_privkey_import(root_privkey, &pem_root_priv, GNUTLS_X509_FMT_PEM))
581 ret = IPHONE_E_SSL_ERROR; 624 ret = IPHONE_E_SSL_ERROR;
@@ -591,7 +634,7 @@ iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_
591 634
592 if (IPHONE_E_SUCCESS == ret) { 635 if (IPHONE_E_SUCCESS == ret) {
593 /* if everything went well, export in PEM format */ 636 /* if everything went well, export in PEM format */
594 gnutls_datum_t dev_pem = {NULL, 0}; 637 gnutls_datum_t dev_pem = { NULL, 0 };
595 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &dev_pem.size); 638 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &dev_pem.size);
596 dev_pem.data = gnutls_malloc(dev_pem.size); 639 dev_pem.data = gnutls_malloc(dev_pem.size);
597 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_pem.data, &dev_pem.size); 640 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, dev_pem.data, &dev_pem.size);
@@ -623,7 +666,8 @@ iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_
623 * 666 *
624 * @return 1 on success and 0 on failure 667 * @return 1 on success and 0 on failure
625 */ 668 */
626iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const char *HostID) { 669iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const char *HostID)
670{
627 xmlDocPtr plist = new_plist(); 671 xmlDocPtr plist = new_plist();
628 xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 672 xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0);
629 xmlNode *key; 673 xmlNode *key;
@@ -631,46 +675,52 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c
631 uint32 len = 0, bytes = 0, return_me = 0, i = 0; 675 uint32 len = 0, bytes = 0, return_me = 0, i = 0;
632 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 676 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
633 // end variables 677 // end variables
634 678
635 key = add_key_str_dict_element(plist, dict, "HostID", HostID, 1); 679 key = add_key_str_dict_element(plist, dict, "HostID", HostID, 1);
636 if (!key) { 680 if (!key) {
637 if (debug) printf("Couldn't add a key.\n"); 681 if (debug)
682 printf("Couldn't add a key.\n");
638 xmlFreeDoc(plist); 683 xmlFreeDoc(plist);
639 return IPHONE_E_DICT_ERROR; 684 return IPHONE_E_DICT_ERROR;
640 } 685 }
641 key = add_key_str_dict_element(plist, dict, "Request", "StartSession", 1); 686 key = add_key_str_dict_element(plist, dict, "Request", "StartSession", 1);
642 if (!key) { 687 if (!key) {
643 if (debug) printf("Couldn't add a key.\n"); 688 if (debug)
689 printf("Couldn't add a key.\n");
644 xmlFreeDoc(plist); 690 xmlFreeDoc(plist);
645 return IPHONE_E_DICT_ERROR; 691 return IPHONE_E_DICT_ERROR;
646 } 692 }
647 693
648 xmlDocDumpMemory(plist, (xmlChar **)&what2send, &len); 694 xmlDocDumpMemory(plist, (xmlChar **) & what2send, &len);
649 ret = iphone_lckd_send(control, what2send, len, &bytes); 695 ret = iphone_lckd_send(control, what2send, len, &bytes);
650 696
651 xmlFree(what2send); 697 xmlFree(what2send);
652 xmlFreeDoc(plist); 698 xmlFreeDoc(plist);
653 699
654 if (ret != IPHONE_E_SUCCESS) return ret; 700 if (ret != IPHONE_E_SUCCESS)
655 701 return ret;
702
656 if (bytes > 0) { 703 if (bytes > 0) {
657 ret = iphone_lckd_recv(control, &what2send, &len); 704 ret = iphone_lckd_recv(control, &what2send, &len);
658 plist = xmlReadMemory(what2send, len, NULL, NULL, 0); 705 plist = xmlReadMemory(what2send, len, NULL, NULL, 0);
659 dict = xmlDocGetRootElement(plist); 706 dict = xmlDocGetRootElement(plist);
660 if (!dict) return IPHONE_E_DICT_ERROR; 707 if (!dict)
708 return IPHONE_E_DICT_ERROR;
661 for (dict = dict->children; dict; dict = dict->next) { 709 for (dict = dict->children; dict; dict = dict->next) {
662 if (!xmlStrcmp(dict->name, "dict")) break; 710 if (!xmlStrcmp(dict->name, "dict"))
711 break;
663 } 712 }
664 dictionary = read_dict_element_strings(dict); 713 dictionary = read_dict_element_strings(dict);
665 xmlFreeDoc(plist); 714 xmlFreeDoc(plist);
666 free(what2send); 715 free(what2send);
667 for (i = 0; dictionary[i]; i+=2) { 716 for (i = 0; dictionary[i]; i += 2) {
668 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i+1], "Success")) { 717 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) {
669 // Set up GnuTLS... 718 // Set up GnuTLS...
670 //gnutls_anon_client_credentials_t anoncred; 719 //gnutls_anon_client_credentials_t anoncred;
671 gnutls_certificate_credentials_t xcred; 720 gnutls_certificate_credentials_t xcred;
672 721
673 if (debug) printf("We started the session OK, now trying GnuTLS\n"); 722 if (debug)
723 printf("We started the session OK, now trying GnuTLS\n");
674 errno = 0; 724 errno = 0;
675 gnutls_global_init(); 725 gnutls_global_init();
676 //gnutls_anon_allocate_client_credentials(&anoncred); 726 //gnutls_anon_allocate_client_credentials(&anoncred);
@@ -678,7 +728,7 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c
678 gnutls_certificate_set_x509_trust_file(xcred, "hostcert.pem", GNUTLS_X509_FMT_PEM); 728 gnutls_certificate_set_x509_trust_file(xcred, "hostcert.pem", GNUTLS_X509_FMT_PEM);
679 gnutls_init(control->ssl_session, GNUTLS_CLIENT); 729 gnutls_init(control->ssl_session, GNUTLS_CLIENT);
680 { 730 {
681 int protocol_priority[16] = {GNUTLS_SSL3, 0 }; 731 int protocol_priority[16] = { GNUTLS_SSL3, 0 };
682 int kx_priority[16] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, 0 }; 732 int kx_priority[16] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, 0 };
683 int cipher_priority[16] = { GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_AES_256_CBC, 0 }; 733 int cipher_priority[16] = { GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_AES_256_CBC, 0 };
684 int mac_priority[16] = { GNUTLS_MAC_SHA1, GNUTLS_MAC_MD5, 0 }; 734 int mac_priority[16] = { GNUTLS_MAC_SHA1, GNUTLS_MAC_MD5, 0 };
@@ -687,30 +737,38 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c
687 gnutls_cipher_set_priority(*control->ssl_session, cipher_priority); 737 gnutls_cipher_set_priority(*control->ssl_session, cipher_priority);
688 gnutls_compression_set_priority(*control->ssl_session, comp_priority); 738 gnutls_compression_set_priority(*control->ssl_session, comp_priority);
689 gnutls_kx_set_priority(*control->ssl_session, kx_priority); 739 gnutls_kx_set_priority(*control->ssl_session, kx_priority);
690 gnutls_protocol_set_priority( *control->ssl_session, protocol_priority); 740 gnutls_protocol_set_priority(*control->ssl_session, protocol_priority);
691 gnutls_mac_set_priority(*control->ssl_session, mac_priority); 741 gnutls_mac_set_priority(*control->ssl_session, mac_priority);
692 742
693 } 743 }
694 gnutls_credentials_set(*control->ssl_session, GNUTLS_CRD_CERTIFICATE, xcred); // this part is killing me. 744 gnutls_credentials_set(*control->ssl_session, GNUTLS_CRD_CERTIFICATE, xcred); // this part is killing me.
695 745
696 if (debug) printf("GnuTLS step 1...\n"); 746 if (debug)
747 printf("GnuTLS step 1...\n");
697 gnutls_transport_set_ptr(*control->ssl_session, (gnutls_transport_ptr_t) control); 748 gnutls_transport_set_ptr(*control->ssl_session, (gnutls_transport_ptr_t) control);
698 if (debug) printf("GnuTLS step 2...\n"); 749 if (debug)
699 gnutls_transport_set_push_function(*control->ssl_session, (gnutls_push_func)&lockdownd_secuwrite); 750 printf("GnuTLS step 2...\n");
700 if (debug) printf("GnuTLS step 3...\n"); 751 gnutls_transport_set_push_function(*control->ssl_session, (gnutls_push_func) & lockdownd_secuwrite);
701 gnutls_transport_set_pull_function(*control->ssl_session, (gnutls_pull_func)&lockdownd_securead); 752 if (debug)
702 if (debug) printf("GnuTLS step 4 -- now handshaking...\n"); 753 printf("GnuTLS step 3...\n");
703 754 gnutls_transport_set_pull_function(*control->ssl_session, (gnutls_pull_func) & lockdownd_securead);
704 if (errno && debug) printf("WARN: errno says %s before handshake!\n", strerror(errno)); 755 if (debug)
756 printf("GnuTLS step 4 -- now handshaking...\n");
757
758 if (errno && debug)
759 printf("WARN: errno says %s before handshake!\n", strerror(errno));
705 return_me = gnutls_handshake(*control->ssl_session); 760 return_me = gnutls_handshake(*control->ssl_session);
706 if (debug) printf("GnuTLS handshake done...\n"); 761 if (debug)
707 762 printf("GnuTLS handshake done...\n");
763
708 free_dictionary(dictionary); 764 free_dictionary(dictionary);
709 765
710 if (return_me != GNUTLS_E_SUCCESS) { 766 if (return_me != GNUTLS_E_SUCCESS) {
711 if (debug) printf("GnuTLS reported something wrong.\n"); 767 if (debug)
768 printf("GnuTLS reported something wrong.\n");
712 gnutls_perror(return_me); 769 gnutls_perror(return_me);
713 if (debug) printf("oh.. errno says %s\n", strerror(errno)); 770 if (debug)
771 printf("oh.. errno says %s\n", strerror(errno));
714 return IPHONE_E_SSL_ERROR; 772 return IPHONE_E_SSL_ERROR;
715 } else { 773 } else {
716 control->in_SSL = 1; 774 control->in_SSL = 1;
@@ -718,19 +776,20 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c
718 } 776 }
719 } 777 }
720 } 778 }
721 779
722 if (debug) { 780 if (debug) {
723 printf("Apparently failed negotiating with lockdownd.\n"); 781 printf("Apparently failed negotiating with lockdownd.\n");
724 printf("Responding dictionary: \n"); 782 printf("Responding dictionary: \n");
725 for (i = 0; dictionary[i]; i+=2) { 783 for (i = 0; dictionary[i]; i += 2) {
726 printf("\t%s: %s\n", dictionary[i], dictionary[i+1]); 784 printf("\t%s: %s\n", dictionary[i], dictionary[i + 1]);
727 } 785 }
728 } 786 }
729 787
730 free_dictionary(dictionary); 788 free_dictionary(dictionary);
731 return IPHONE_E_SSL_ERROR; 789 return IPHONE_E_SSL_ERROR;
732 } else { 790 } else {
733 if (debug) printf("Didn't get enough bytes.\n"); 791 if (debug)
792 printf("Didn't get enough bytes.\n");
734 return IPHONE_E_NOT_ENOUGH_DATA; 793 return IPHONE_E_NOT_ENOUGH_DATA;
735 } 794 }
736} 795}
@@ -743,14 +802,18 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c
743 * 802 *
744 * @return The number of bytes sent 803 * @return The number of bytes sent
745 */ 804 */
746ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length) { 805ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length)
806{
747 int bytes = 0; 807 int bytes = 0;
748 iphone_lckd_client_t control; 808 iphone_lckd_client_t control;
749 control = (iphone_lckd_client_t)transport; 809 control = (iphone_lckd_client_t) transport;
750 if (debug) printf("lockdownd_secuwrite() called\n"); 810 if (debug)
751 if (debug) printf("pre-send\nlength = %zi\n", length); 811 printf("lockdownd_secuwrite() called\n");
812 if (debug)
813 printf("pre-send\nlength = %zi\n", length);
752 iphone_mux_send(control->connection, buffer, length, &bytes); 814 iphone_mux_send(control->connection, buffer, length, &bytes);
753 if (debug) printf("post-send\nsent %i bytes\n", bytes); 815 if (debug)
816 printf("post-send\nsent %i bytes\n", bytes);
754 if (debug) { 817 if (debug) {
755 FILE *my_ssl_packet = fopen("sslpacketwrite.out", "w+"); 818 FILE *my_ssl_packet = fopen("sslpacketwrite.out", "w+");
756 fwrite(buffer, 1, length, my_ssl_packet); 819 fwrite(buffer, 1, length, my_ssl_packet);
@@ -758,7 +821,7 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size
758 printf("Wrote SSL packet to drive, too.\n"); 821 printf("Wrote SSL packet to drive, too.\n");
759 fclose(my_ssl_packet); 822 fclose(my_ssl_packet);
760 } 823 }
761 824
762 return bytes; 825 return bytes;
763} 826}
764 827
@@ -770,68 +833,86 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size
770 * 833 *
771 * @return The number of bytes read 834 * @return The number of bytes read
772 */ 835 */
773ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length) { 836ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length)
837{
774 int bytes = 0, pos_start_fill = 0; 838 int bytes = 0, pos_start_fill = 0;
775 char *hackhackhack = NULL; 839 char *hackhackhack = NULL;
776 iphone_lckd_client_t control; 840 iphone_lckd_client_t control;
777 control = (iphone_lckd_client_t)transport; 841 control = (iphone_lckd_client_t) transport;
778 if (debug) printf("lockdownd_securead() called\nlength = %zi\n", length); 842 if (debug)
843 printf("lockdownd_securead() called\nlength = %zi\n", length);
779 // Buffering hack! Throw what we've got in our "buffer" into the stream first, then get more. 844 // Buffering hack! Throw what we've got in our "buffer" into the stream first, then get more.
780 if (control->gtls_buffer_hack_len > 0) { 845 if (control->gtls_buffer_hack_len > 0) {
781 if (length > control->gtls_buffer_hack_len) { // If it's asking for more than we got 846 if (length > control->gtls_buffer_hack_len) { // If it's asking for more than we got
782 length -= control->gtls_buffer_hack_len; // Subtract what we have from their requested length 847 length -= control->gtls_buffer_hack_len; // Subtract what we have from their requested length
783 pos_start_fill = control->gtls_buffer_hack_len; // set the pos to start filling at 848 pos_start_fill = control->gtls_buffer_hack_len; // set the pos to start filling at
784 memcpy(buffer, control->gtls_buffer_hack, control->gtls_buffer_hack_len); // Fill their buffer partially 849 memcpy(buffer, control->gtls_buffer_hack, control->gtls_buffer_hack_len); // Fill their buffer partially
785 free(control->gtls_buffer_hack); // free our memory, it's not chained anymore 850 free(control->gtls_buffer_hack); // free our memory, it's not chained anymore
786 control->gtls_buffer_hack_len = 0; // we don't have a hack buffer anymore 851 control->gtls_buffer_hack_len = 0; // we don't have a hack buffer anymore
787 if (debug) printf("Did a partial fill to help quench thirst for data\n"); 852 if (debug)
788 } else if (length < control->gtls_buffer_hack_len) { // If it's asking for less... 853 printf("Did a partial fill to help quench thirst for data\n");
789 control->gtls_buffer_hack_len -= length; // subtract what they're asking for 854 } else if (length < control->gtls_buffer_hack_len) { // If it's asking for less...
790 memcpy(buffer, control->gtls_buffer_hack, length); // fill their buffer 855 control->gtls_buffer_hack_len -= length; // subtract what they're asking for
791 hackhackhack = (char*)malloc(sizeof(char) * control->gtls_buffer_hack_len); // strndup is NOT a good solution -- concatenates \0!!!! Anyway, make a new "hack" buffer. 856 memcpy(buffer, control->gtls_buffer_hack, length); // fill their buffer
792 memcpy(hackhackhack, control->gtls_buffer_hack+length, control->gtls_buffer_hack_len); // Move what's left into the new one 857 hackhackhack = (char *) malloc(sizeof(char) * control->gtls_buffer_hack_len); // strndup is NOT a good solution -- concatenates \0!!!! Anyway, make a new "hack" buffer.
793 free(control->gtls_buffer_hack); // Free the old one 858 memcpy(hackhackhack, control->gtls_buffer_hack + length, control->gtls_buffer_hack_len); // Move what's left into the new one
794 control->gtls_buffer_hack = hackhackhack; // And make it the new one. 859 free(control->gtls_buffer_hack); // Free the old one
795 hackhackhack = NULL; 860 control->gtls_buffer_hack = hackhackhack; // And make it the new one.
796 if (debug) printf("Quenched the thirst for data; new hack length is %i\n", control->gtls_buffer_hack_len); 861 hackhackhack = NULL;
797 return length; // hand it over. 862 if (debug)
798 } else { // length == hack length 863 printf("Quenched the thirst for data; new hack length is %i\n", control->gtls_buffer_hack_len);
799 memcpy(buffer, control->gtls_buffer_hack, length); // copy our buffer into theirs 864 return length; // hand it over.
800 free(control->gtls_buffer_hack); // free our "obligation" 865 } else { // length == hack length
801 control->gtls_buffer_hack_len = 0; // free our "obligation" 866 memcpy(buffer, control->gtls_buffer_hack, length); // copy our buffer into theirs
802 if (debug) printf("Satiated the thirst for data; now we have to eventually receive again.\n"); 867 free(control->gtls_buffer_hack); // free our "obligation"
803 return length; // hand it over 868 control->gtls_buffer_hack_len = 0; // free our "obligation"
869 if (debug)
870 printf("Satiated the thirst for data; now we have to eventually receive again.\n");
871 return length; // hand it over
804 } 872 }
805 } 873 }
806 // End buffering hack! 874 // End buffering hack!
807 char *recv_buffer = (char*)malloc(sizeof(char) * (length * 1000)); // ensuring nothing stupid happens 875 char *recv_buffer = (char *) malloc(sizeof(char) * (length * 1000)); // ensuring nothing stupid happens
808 876
809 if (debug) printf("pre-read\nclient wants %zi bytes\n", length); 877 if (debug)
878 printf("pre-read\nclient wants %zi bytes\n", length);
810 iphone_mux_recv(control->connection, recv_buffer, (length * 1000), &bytes); 879 iphone_mux_recv(control->connection, recv_buffer, (length * 1000), &bytes);
811 if (debug) printf("post-read\nwe got %i bytes\n", bytes); 880 if (debug)
881 printf("post-read\nwe got %i bytes\n", bytes);
812 if (debug && bytes < 0) { 882 if (debug && bytes < 0) {
813 printf("lockdownd_securead(): uh oh\n"); 883 printf("lockdownd_securead(): uh oh\n");
814 printf("I believe what we have here is a failure to communicate... libusb says %s but strerror says %s\n", usb_strerror(), strerror(errno)); 884 printf("I believe what we have here is a failure to communicate... libusb says %s but strerror says %s\n",
815 return bytes + 28; // an errno 885 usb_strerror(), strerror(errno));
886 return bytes + 28; // an errno
816 } 887 }
817 if (bytes >= length) { 888 if (bytes >= length) {
818 if (bytes > length) { 889 if (bytes > length) {
819 if (debug) printf("lockdownd_securead: Client deliberately read less data than was there; resorting to GnuTLS buffering hack.\n"); 890 if (debug)
820 if (!control->gtls_buffer_hack_len) { // if there's no hack buffer yet 891 printf
892 ("lockdownd_securead: Client deliberately read less data than was there; resorting to GnuTLS buffering hack.\n");
893 if (!control->gtls_buffer_hack_len) { // if there's no hack buffer yet
821 //control->gtls_buffer_hack = strndup(recv_buffer+length, bytes-length); // strndup is NOT a good solution! 894 //control->gtls_buffer_hack = strndup(recv_buffer+length, bytes-length); // strndup is NOT a good solution!
822 control->gtls_buffer_hack_len += bytes-length; 895 control->gtls_buffer_hack_len += bytes - length;
823 control->gtls_buffer_hack = (char*)malloc(sizeof(char) * control->gtls_buffer_hack_len); 896 control->gtls_buffer_hack = (char *) malloc(sizeof(char) * control->gtls_buffer_hack_len);
824 memcpy(control->gtls_buffer_hack, recv_buffer+length, control->gtls_buffer_hack_len); 897 memcpy(control->gtls_buffer_hack, recv_buffer + length, control->gtls_buffer_hack_len);
825 } else { // if there is. 898 } else { // if there is.
826 control->gtls_buffer_hack = realloc(control->gtls_buffer_hack, control->gtls_buffer_hack_len + (bytes - length)); 899 control->gtls_buffer_hack =
827 memcpy(control->gtls_buffer_hack+control->gtls_buffer_hack_len, recv_buffer+length, bytes-length); 900 realloc(control->gtls_buffer_hack, control->gtls_buffer_hack_len + (bytes - length));
901 memcpy(control->gtls_buffer_hack + control->gtls_buffer_hack_len, recv_buffer + length, bytes - length);
828 control->gtls_buffer_hack_len += bytes - length; 902 control->gtls_buffer_hack_len += bytes - length;
829 } 903 }
830 } 904 }
831 memcpy(buffer+pos_start_fill, recv_buffer, length); 905 memcpy(buffer + pos_start_fill, recv_buffer, length);
832 free(recv_buffer); 906 free(recv_buffer);
833 if (bytes == length) { if (debug) printf("Returning how much we received.\n"); return bytes; } 907 if (bytes == length) {
834 else { if (debug) printf("Returning what they want to hear.\nHack length: %i\n", control->gtls_buffer_hack_len); return length; } 908 if (debug)
909 printf("Returning how much we received.\n");
910 return bytes;
911 } else {
912 if (debug)
913 printf("Returning what they want to hear.\nHack length: %i\n", control->gtls_buffer_hack_len);
914 return length;
915 }
835 } 916 }
836 return bytes; 917 return bytes;
837} 918}
@@ -843,12 +924,16 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
843 * 924 *
844 * @return The port number the service was started on or 0 on failure. 925 * @return The port number the service was started on or 0 on failure.
845 */ 926 */
846iphone_error_t iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service, int *port ) { 927iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char *service, int *port)
847 if (!client || !service || !port) return IPHONE_E_INVALID_ARG; 928{
929 if (!client || !service || !port)
930 return IPHONE_E_INVALID_ARG;
848 931
849 char* host_id = get_host_id(); 932 char *host_id = get_host_id();
850 if (!host_id) return IPHONE_E_INVALID_CONF; 933 if (!host_id)
851 if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id)) return IPHONE_E_SSL_ERROR; 934 return IPHONE_E_INVALID_CONF;
935 if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id))
936 return IPHONE_E_SSL_ERROR;
852 937
853 char *XML_query, **dictionary; 938 char *XML_query, **dictionary;
854 uint32 length, i = 0, port_loc = 0, bytes = 0; 939 uint32 length, i = 0, port_loc = 0, bytes = 0;
@@ -862,63 +947,78 @@ iphone_error_t iphone_lckd_start_service ( iphone_lckd_client_t client, const ch
862 xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 947 xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0);
863 xmlNode *key; 948 xmlNode *key;
864 key = add_key_str_dict_element(plist, dict, "Request", "StartService", 1); 949 key = add_key_str_dict_element(plist, dict, "Request", "StartService", 1);
865 if (!key) { xmlFreeDoc(plist); return IPHONE_E_UNKNOWN_ERROR; } 950 if (!key) {
951 xmlFreeDoc(plist);
952 return IPHONE_E_UNKNOWN_ERROR;
953 }
866 key = add_key_str_dict_element(plist, dict, "Service", service, 1); 954 key = add_key_str_dict_element(plist, dict, "Service", service, 1);
867 if (!key) { xmlFreeDoc(plist); return IPHONE_E_UNKNOWN_ERROR; } 955 if (!key) {
868 956 xmlFreeDoc(plist);
869 xmlDocDumpMemory(plist, (xmlChar **)&XML_query, &length); 957 return IPHONE_E_UNKNOWN_ERROR;
870 958 }
959
960 xmlDocDumpMemory(plist, (xmlChar **) & XML_query, &length);
961
871 ret = iphone_lckd_send(client, XML_query, length, &bytes); 962 ret = iphone_lckd_send(client, XML_query, length, &bytes);
872 free(XML_query); 963 free(XML_query);
873 if (IPHONE_E_SUCCESS != ret) return ret; 964 if (IPHONE_E_SUCCESS != ret)
874 965 return ret;
966
875 ret = iphone_lckd_recv(client, &XML_query, &bytes); 967 ret = iphone_lckd_recv(client, &XML_query, &bytes);
876 xmlFreeDoc(plist); 968 xmlFreeDoc(plist);
877 if (IPHONE_E_SUCCESS != ret) return ret; 969 if (IPHONE_E_SUCCESS != ret)
878 970 return ret;
879 if (bytes <= 0) return IPHONE_E_NOT_ENOUGH_DATA; 971
972 if (bytes <= 0)
973 return IPHONE_E_NOT_ENOUGH_DATA;
880 else { 974 else {
881 plist = xmlReadMemory(XML_query, bytes, NULL, NULL, 0); 975 plist = xmlReadMemory(XML_query, bytes, NULL, NULL, 0);
882 if (!plist) return IPHONE_E_UNKNOWN_ERROR; 976 if (!plist)
977 return IPHONE_E_UNKNOWN_ERROR;
883 dict = xmlDocGetRootElement(plist); 978 dict = xmlDocGetRootElement(plist);
884 if (!dict) return IPHONE_E_UNKNOWN_ERROR; 979 if (!dict)
980 return IPHONE_E_UNKNOWN_ERROR;
885 for (dict = dict->children; dict; dict = dict->next) { 981 for (dict = dict->children; dict; dict = dict->next) {
886 if (!xmlStrcmp(dict->name, "dict")) break; 982 if (!xmlStrcmp(dict->name, "dict"))
983 break;
887 } 984 }
888 985
889 if (!dict) return IPHONE_E_UNKNOWN_ERROR; 986 if (!dict)
987 return IPHONE_E_UNKNOWN_ERROR;
890 dictionary = read_dict_element_strings(dict); 988 dictionary = read_dict_element_strings(dict);
891 989
892 for (i = 0; dictionary[i]; i+=2) { 990 for (i = 0; dictionary[i]; i += 2) {
893 if (debug) printf("lockdownd_start_service() dictionary %s: %s\n", dictionary[i], dictionary[i+1]); 991 if (debug)
894 992 printf("lockdownd_start_service() dictionary %s: %s\n", dictionary[i], dictionary[i + 1]);
993
895 if (!xmlStrcmp(dictionary[i], "Port")) { 994 if (!xmlStrcmp(dictionary[i], "Port")) {
896 port_loc = atoi(dictionary[i+1]); 995 port_loc = atoi(dictionary[i + 1]);
897 if (debug) printf("lockdownd_start_service() atoi'd port: %i\n", port); 996 if (debug)
997 printf("lockdownd_start_service() atoi'd port: %i\n", port);
898 } 998 }
899 999
900 if (!xmlStrcmp(dictionary[i], "Result")) { 1000 if (!xmlStrcmp(dictionary[i], "Result")) {
901 if (!xmlStrcmp(dictionary[i+1], "Success")) { 1001 if (!xmlStrcmp(dictionary[i + 1], "Success")) {
902 result = 1; 1002 result = 1;
903 } 1003 }
904 } 1004 }
905 } 1005 }
906 1006
907 if (debug) { 1007 if (debug) {
908 printf("lockdownd_start_service(): DATA RECEIVED:\n\n"); 1008 printf("lockdownd_start_service(): DATA RECEIVED:\n\n");
909 fwrite(XML_query, 1, bytes, stdout); 1009 fwrite(XML_query, 1, bytes, stdout);
910 printf("end data received by lockdownd_start_service()\n"); 1010 printf("end data received by lockdownd_start_service()\n");
911 } 1011 }
912 1012
913 free(XML_query); 1013 free(XML_query);
914 xmlFreeDoc(plist); 1014 xmlFreeDoc(plist);
915 free_dictionary(dictionary); 1015 free_dictionary(dictionary);
916 if (port && result) { 1016 if (port && result) {
917 *port = port_loc; 1017 *port = port_loc;
918 return IPHONE_E_SUCCESS; 1018 return IPHONE_E_SUCCESS;
919 } 1019 } else
920 else return IPHONE_E_UNKNOWN_ERROR; 1020 return IPHONE_E_UNKNOWN_ERROR;
921 } 1021 }
922 1022
923 return IPHONE_E_UNKNOWN_ERROR; 1023 return IPHONE_E_UNKNOWN_ERROR;
924} 1024}