summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--dev/main.c3
-rw-r--r--include/libiphone/libiphone.h5
-rw-r--r--src/lockdown.c617
-rw-r--r--src/utils.h2
4 files changed, 295 insertions, 332 deletions
diff --git a/dev/main.c b/dev/main.c
index 4974eef..f865e52 100644
--- a/dev/main.c
+++ b/dev/main.c
@@ -28,6 +28,7 @@
28#include <libxml/tree.h> 28#include <libxml/tree.h>
29 29
30#include <libiphone/libiphone.h> 30#include <libiphone/libiphone.h>
31#include "../src/utils.h"
31 32
32 33
33int main(int argc, char *argv[]) 34int main(int argc, char *argv[])
@@ -38,8 +39,10 @@ int main(int argc, char *argv[])
38 39
39 if (argc > 1 && !strcasecmp(argv[1], "--debug")) { 40 if (argc > 1 && !strcasecmp(argv[1], "--debug")) {
40 iphone_set_debug(1); 41 iphone_set_debug(1);
42 iphone_set_debug_mask(DBGMASK_ALL);
41 } else { 43 } else {
42 iphone_set_debug(0); 44 iphone_set_debug(0);
45 iphone_set_debug_mask(DBGMASK_NONE);
43 } 46 }
44 47
45 if (IPHONE_E_SUCCESS != iphone_get_device(&phone)) { 48 if (IPHONE_E_SUCCESS != iphone_get_device(&phone)) {
diff --git a/include/libiphone/libiphone.h b/include/libiphone/libiphone.h
index b3e3f95..aab7fdb 100644
--- a/include/libiphone/libiphone.h
+++ b/include/libiphone/libiphone.h
@@ -29,6 +29,7 @@ extern "C" {
29#include <stdint.h> 29#include <stdint.h>
30#include <sys/types.h> 30#include <sys/types.h>
31#include <sys/stat.h> 31#include <sys/stat.h>
32#include <plist/plist.h>
32 33
33//general errors 34//general errors
34#define IPHONE_E_SUCCESS 0 35#define IPHONE_E_SUCCESS 0
@@ -88,8 +89,8 @@ iphone_error_t iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_clie
88iphone_error_t iphone_lckd_free_client( iphone_lckd_client_t client ); 89iphone_error_t iphone_lckd_free_client( iphone_lckd_client_t client );
89 90
90iphone_error_t iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service, int *port ); 91iphone_error_t iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service, int *port );
91iphone_error_t iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data, uint32_t *recv_bytes ); 92iphone_error_t iphone_lckd_recv ( iphone_lckd_client_t client, plist_t* plist);
92iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t length, uint32_t *recv_bytes ); 93iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, plist_t plist);
93 94
94 95
95//usbmux related functions 96//usbmux related functions
diff --git a/src/lockdown.c b/src/lockdown.c
index 56a6f4e..b83b8cf 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -33,6 +33,7 @@
33 33
34#include <plist/plist.h> 34#include <plist/plist.h>
35 35
36
36const ASN1_ARRAY_TYPE pkcs1_asn1_tab[] = { 37const ASN1_ARRAY_TYPE pkcs1_asn1_tab[] = {
37 {"PKCS1", 536872976, 0}, 38 {"PKCS1", 536872976, 0},
38 {0, 1073741836, 0}, 39 {0, 1073741836, 0},
@@ -80,53 +81,49 @@ static void iphone_lckd_stop_session(iphone_lckd_client_t control)
80 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 81 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
81 82
82 plist_t dict = plist_new_dict(); 83 plist_t dict = plist_new_dict();
83 plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); 84 plist_add_sub_key_el(dict, "Request");
84 plist_add_sub_element(dict, PLIST_STRING, (void *) "StopSession", strlen("StopSession")); 85 plist_add_sub_string_el(dict, "StopSession");
85 plist_add_sub_element(dict, PLIST_KEY, (void *) "SessionID", strlen("SessionID")); 86 plist_add_sub_key_el(dict, "SessionID");
86 plist_add_sub_element(dict, PLIST_STRING, (void *) control->session_id, strlen(control->session_id)); 87 plist_add_sub_string_el(dict, control->session_id);
87 88
88 log_debug_msg("iphone_lckd_stop_session() called\n"); 89 log_dbg_msg(DBGMASK_LOCKDOWND, "iphone_lckd_stop_session() called\n");
89 char *XML_content = NULL;
90 uint32_t length = 0;
91 90
92 plist_to_xml(dict, &XML_content, &length); 91 ret = iphone_lckd_send(control, dict);
93 log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content);
94 ret = iphone_lckd_send(control, XML_content, length, &bytes);
95 92
96 free(XML_content);
97 XML_content = NULL;
98 plist_free(dict); 93 plist_free(dict);
99 dict = NULL; 94 dict = NULL;
100 95
101 ret = iphone_lckd_recv(control, &XML_content, &bytes); 96 ret = iphone_lckd_recv(control, &dict);
102 log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content);
103 plist_from_xml(XML_content, bytes, &dict);
104 97
105 if (!dict) { 98 if (!dict) {
106 log_debug_msg("lockdownd_stop_session(): IPHONE_E_PLIST_ERROR\n"); 99 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_stop_session(): IPHONE_E_PLIST_ERROR\n");
107 return; // IPHONE_E_PLIST_ERROR; 100 return; // IPHONE_E_PLIST_ERROR;
108 } 101 }
109 102
110 plist_t query_node = plist_find_node(dict, PLIST_STRING, "StopSession", strlen("StopSession")); 103 plist_t query_node = plist_find_node_by_string(dict, "StopSession");
111 plist_t result_node = plist_get_next_sibling(query_node); 104 plist_t result_node = plist_get_next_sibling(query_node);
112 plist_t value_node = plist_get_next_sibling(result_node); 105 plist_t value_node = plist_get_next_sibling(result_node);
113 106
114 plist_type result_type; 107 plist_type result_type = plist_get_node_type(result_node);
115 plist_type value_type; 108 plist_type value_type = plist_get_node_type(value_node);
109
110 if (result_type == PLIST_KEY && value_type == PLIST_STRING) {
116 111
117 char *result_value = NULL; 112 char *result_value = NULL;
118 char *value_value = NULL; 113 char *value_value = NULL;
119 uint64_t result_length = 0;
120 uint64_t value_length = 0;
121 114
122 plist_get_type_and_value(result_node, &result_type, (void *) (&result_value), &result_length); 115 plist_get_key_val(result_node, &result_value);
123 plist_get_type_and_value(value_node, &value_type, (void *) (&value_value), &value_length); 116 plist_get_string_val(value_node, &value_value);
124 117
125 if (result_type == PLIST_KEY && 118 if (!strcmp(result_value, "Result") && !strcmp(value_value, "Success")) {
126 value_type == PLIST_STRING && !strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { 119 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_stop_session(): success\n");
127 log_debug_msg("lockdownd_stop_session(): success\n"); 120 ret = IPHONE_E_SUCCESS;
128 ret = IPHONE_E_SUCCESS; 121 }
122 free(result_value);
123 free(value_value);
129 } 124 }
125 plist_free(dict);
126 dict = NULL;
130 127
131 return; // ret; 128 return; // ret;
132} 129}
@@ -142,14 +139,14 @@ static void iphone_lckd_stop_session(iphone_lckd_client_t control)
142static void iphone_lckd_stop_SSL_session(iphone_lckd_client_t client) 139static void iphone_lckd_stop_SSL_session(iphone_lckd_client_t client)
143{ 140{
144 if (!client) { 141 if (!client) {
145 log_debug_msg("lockdownd_stop_SSL_session(): invalid argument!\n"); 142 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_stop_SSL_session(): invalid argument!\n");
146 return; 143 return;
147 } 144 }
148 145
149 if (client->in_SSL) { 146 if (client->in_SSL) {
150 log_debug_msg("Stopping SSL Session\n"); 147 log_dbg_msg(DBGMASK_LOCKDOWND, "Stopping SSL Session\n");
151 iphone_lckd_stop_session(client); 148 iphone_lckd_stop_session(client);
152 log_debug_msg("Sending SSL close notify\n"); 149 log_dbg_msg(DBGMASK_LOCKDOWND, "Sending SSL close notify\n");
153 gnutls_bye(*client->ssl_session, GNUTLS_SHUT_RDWR); 150 gnutls_bye(*client->ssl_session, GNUTLS_SHUT_RDWR);
154 } 151 }
155 if (client->ssl_session) { 152 if (client->ssl_session) {
@@ -196,9 +193,9 @@ iphone_error_t iphone_lckd_free_client(iphone_lckd_client_t client)
196 * 193 *
197 * @return The number of bytes received 194 * @return The number of bytes received
198 */ 195 */
199iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, char **dump_data, uint32_t * recv_bytes) 196iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, plist_t * plist)
200{ 197{
201 if (!client || !dump_data || !recv_bytes) 198 if (!client || !plist || (plist && *plist))
202 return IPHONE_E_INVALID_ARG; 199 return IPHONE_E_INVALID_ARG;
203 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 200 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
204 char *receive; 201 char *receive;
@@ -221,8 +218,18 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, char **dump_data, u
221 if (bytes > 0) 218 if (bytes > 0)
222 ret = IPHONE_E_SUCCESS; 219 ret = IPHONE_E_SUCCESS;
223 } 220 }
224 *dump_data = receive; 221
225 *recv_bytes = bytes; 222 if (bytes <= 0) {
223 free(receive);
224 return IPHONE_E_NOT_ENOUGH_DATA;
225 }
226
227 plist_from_xml(receive, bytes, plist);
228 free(receive);
229
230 if (!*plist)
231 ret = IPHONE_E_PLIST_ERROR;
232
226 return ret; 233 return ret;
227} 234}
228 235
@@ -231,26 +238,31 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, char **dump_data, u
231 * @note This function is low-level and should only be used if you need to send 238 * @note This function is low-level and should only be used if you need to send
232 * a new type of message. 239 * a new type of message.
233 * 240 *
234 * @param control The lockdownd client 241 * @param client The lockdownd client
235 * @param raw_data The null terminated string buffer to send 242 * @param plist The plist to send
236 * @param length The length of data to send
237 * 243 *
238 * @return The number of bytes sent 244 * @return an error code (IPHONE_E_SUCCESS on success)
239 */ 245 */
240iphone_error_t iphone_lckd_send(iphone_lckd_client_t client, char *raw_data, uint32_t length, uint32_t * sent_bytes) 246iphone_error_t iphone_lckd_send(iphone_lckd_client_t client, plist_t plist)
241{ 247{
242 if (!client || !raw_data || length == 0 || !sent_bytes) 248 if (!client || !plist)
243 return IPHONE_E_INVALID_ARG; 249 return IPHONE_E_INVALID_ARG;
244 char *real_query; 250 char *real_query;
245 int bytes; 251 int bytes;
252 char *XMLContent = NULL;
253 uint32_t length = 0;
246 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 254 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
247 255
256 plist_to_xml(plist, &XMLContent, &length);
257 log_dbg_msg(DBGMASK_LOCKDOWND, "Send msg :\nsize : %i\nbuffer :\n%s\n", length, XMLContent);
258
259
248 real_query = (char *) malloc(sizeof(char) * (length + 4)); 260 real_query = (char *) malloc(sizeof(char) * (length + 4));
249 length = htonl(length); 261 length = htonl(length);
250 memcpy(real_query, &length, sizeof(length)); 262 memcpy(real_query, &length, sizeof(length));
251 memcpy(real_query + 4, raw_data, ntohl(length)); 263 memcpy(real_query + 4, XMLContent, ntohl(length));
252 log_debug_msg("lockdownd_send(): made the query, sending it along\n"); 264 free(XMLContent);
253 dump_debug_buffer("grpkt", real_query, ntohl(length) + 4); 265 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): made the query, sending it along\n");
254 266
255 if (!client->in_SSL) 267 if (!client->in_SSL)
256 ret = iphone_mux_send(client->connection, real_query, ntohl(length) + sizeof(length), &bytes); 268 ret = iphone_mux_send(client->connection, real_query, ntohl(length) + sizeof(length), &bytes);
@@ -258,9 +270,9 @@ iphone_error_t iphone_lckd_send(iphone_lckd_client_t client, char *raw_data, uin
258 gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length)); 270 gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length));
259 ret = IPHONE_E_SUCCESS; 271 ret = IPHONE_E_SUCCESS;
260 } 272 }
261 log_debug_msg("lockdownd_send(): sent it!\n"); 273 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): sent it!\n");
262 free(real_query); 274 free(real_query);
263 *sent_bytes = bytes; 275
264 return ret; 276 return ret;
265} 277}
266 278
@@ -277,54 +289,49 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control)
277 if (!control) 289 if (!control)
278 return IPHONE_E_INVALID_ARG; 290 return IPHONE_E_INVALID_ARG;
279 291
280 int bytes = 0, i = 0;
281 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 292 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
282 293
283 plist_t dict = plist_new_dict(); 294 plist_t dict = plist_new_dict();
284 plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); 295 plist_add_sub_key_el(dict, "Request");
285 plist_add_sub_element(dict, PLIST_STRING, (void *) "QueryType", strlen("QueryType")); 296 plist_add_sub_string_el(dict, "QueryType");
286 297
287 log_debug_msg("lockdownd_hello() called\n"); 298 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_hello() called\n");
288 char *XML_content = NULL; 299 ret = iphone_lckd_send(control, dict);
289 uint32_t length = 0;
290
291 plist_to_xml(dict, &XML_content, &length);
292 log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content);
293 ret = iphone_lckd_send(control, XML_content, length, &bytes);
294 300
295 free(XML_content);
296 XML_content = NULL;
297 plist_free(dict); 301 plist_free(dict);
298 dict = NULL; 302 dict = NULL;
299 303
300 ret = iphone_lckd_recv(control, &XML_content, &bytes); 304 ret = iphone_lckd_recv(control, &dict);
301 log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content);
302 plist_from_xml(XML_content, bytes, &dict);
303 305
304 if (!dict) 306 if (IPHONE_E_SUCCESS != ret)
305 return IPHONE_E_PLIST_ERROR; 307 return ret;
306 308
307 plist_t query_node = plist_find_node(dict, PLIST_STRING, "QueryType", strlen("QueryType")); 309 plist_t query_node = plist_find_node_by_string(dict, "QueryType");
308 plist_t result_node = plist_get_next_sibling(query_node); 310 plist_t result_node = plist_get_next_sibling(query_node);
309 plist_t value_node = plist_get_next_sibling(result_node); 311 plist_t value_node = plist_get_next_sibling(result_node);
310 312
311 plist_type result_type; 313 plist_type result_type = plist_get_node_type(result_node);
312 plist_type value_type; 314 plist_type value_type = plist_get_node_type(value_node);
315
316 if (result_type == PLIST_KEY && value_type == PLIST_STRING) {
313 317
314 char *result_value = NULL; 318 char *result_value = NULL;
315 char *value_value = NULL; 319 char *value_value = NULL;
316 uint64_t result_length = 0;
317 uint64_t value_length = 0;
318 320
319 plist_get_type_and_value(result_node, &result_type, (void *) (&result_value), &result_length); 321 plist_get_key_val(result_node, &result_value);
320 plist_get_type_and_value(value_node, &value_type, (void *) (&value_value), &value_length); 322 plist_get_string_val(value_node, &value_value);
321 323
322 if (result_type == PLIST_KEY && 324 if (!strcmp(result_value, "Result") && !strcmp(value_value, "Success")) {
323 value_type == PLIST_STRING && !strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { 325 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_hello(): success\n");
324 log_debug_msg("lockdownd_hello(): success\n"); 326 ret = IPHONE_E_SUCCESS;
325 ret = IPHONE_E_SUCCESS; 327 }
328 free(result_value);
329 free(value_value);
326 } 330 }
327 331
332 plist_free(dict);
333 dict = NULL;
334
328 return ret; 335 return ret;
329} 336}
330 337
@@ -343,25 +350,18 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const c
343 return IPHONE_E_INVALID_ARG; 350 return IPHONE_E_INVALID_ARG;
344 351
345 plist_t dict = NULL; 352 plist_t dict = NULL;
346 int bytes = 0, i = 0;
347 char *XML_content = NULL;
348 uint32_t length = 0;
349 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 353 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
350 354
351 /* Setup DevicePublicKey request plist */ 355 /* Setup DevicePublicKey request plist */
352 dict = plist_new_dict(); 356 dict = plist_new_dict();
353 plist_add_sub_element(dict, PLIST_KEY, (void *) req_key, strlen(req_key)); 357 plist_add_sub_key_el(dict, req_key);
354 plist_add_sub_element(dict, PLIST_STRING, (void *) req_string, strlen(req_string)); 358 plist_add_sub_string_el(dict, req_string);
355 plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); 359 plist_add_sub_key_el(dict, "Request");
356 plist_add_sub_element(dict, PLIST_STRING, (void *) "GetValue", strlen("GetValue")); 360 plist_add_sub_string_el(dict, "GetValue");
357 plist_to_xml(dict, &XML_content, &length);
358 361
359 /* send to iPhone */ 362 /* send to iPhone */
360 log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); 363 ret = iphone_lckd_send(control, dict);
361 ret = iphone_lckd_send(control, XML_content, length, &bytes);
362 364
363 free(XML_content);
364 XML_content = NULL;
365 plist_free(dict); 365 plist_free(dict);
366 dict = NULL; 366 dict = NULL;
367 367
@@ -369,61 +369,65 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const c
369 return ret; 369 return ret;
370 370
371 /* Now get iPhone's answer */ 371 /* Now get iPhone's answer */
372 ret = iphone_lckd_recv(control, &XML_content, &bytes); 372 ret = iphone_lckd_recv(control, &dict);
373 log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content);
374 373
375 if (ret != IPHONE_E_SUCCESS) 374 if (ret != IPHONE_E_SUCCESS)
376 return ret; 375 return ret;
377 376
378 plist_from_xml(XML_content, bytes, &dict); 377 plist_t query_node = plist_find_node_by_string(dict, "GetValue");
379 if (!dict)
380 return IPHONE_E_PLIST_ERROR;
381
382 plist_t query_node = plist_find_node(dict, PLIST_STRING, "GetValue", strlen("GetValue"));
383 plist_t result_key_node = plist_get_next_sibling(query_node); 378 plist_t result_key_node = plist_get_next_sibling(query_node);
384 plist_t result_value_node = plist_get_next_sibling(result_key_node); 379 plist_t result_value_node = plist_get_next_sibling(result_key_node);
385 380
386 plist_type result_key_type; 381 plist_type result_key_type = plist_get_node_type(result_key_node);
387 plist_type result_value_type; 382 plist_type result_value_type = plist_get_node_type(result_value_node);
388 char *result_key = NULL;
389 char *result_value = NULL;
390 uint64_t result_length = 0;
391 uint64_t value_length = 0;
392 383
393 plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &result_length); 384 if (result_key_type == PLIST_KEY && result_value_type == PLIST_STRING) {
394 plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &value_length);
395 385
396 if (result_key_type == PLIST_KEY && 386 char *result_key = NULL;
397 result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { 387 char *result_value = NULL;
398 log_debug_msg("lockdownd_generic_get_value(): success\n"); 388 ret = IPHONE_E_DICT_ERROR;
399 ret = IPHONE_E_SUCCESS; 389
400 } 390 plist_get_key_val(result_key_node, &result_key);
391 plist_get_string_val(result_value_node, &result_value);
401 392
393 if (!strcmp(result_key, "Result") && !strcmp(result_value, "Success")) {
394 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_generic_get_value(): success\n");
395 ret = IPHONE_E_SUCCESS;
396 }
397 free(result_key);
398 free(result_value);
399 }
402 if (ret != IPHONE_E_SUCCESS) { 400 if (ret != IPHONE_E_SUCCESS) {
403 return IPHONE_E_DICT_ERROR; 401 return ret;
404 } 402 }
405 403
406 plist_t value_key_node = plist_get_next_sibling(result_key_node); 404 plist_t value_key_node = plist_get_next_sibling(result_key_node);
407 plist_t value_value_node = plist_get_next_sibling(value_key_node); 405 plist_t value_value_node = plist_get_next_sibling(value_key_node);
408 plist_type value_key_type; 406
409 plist_type value_value_type; 407 plist_type value_key_type = plist_get_node_type(value_key_node);
410 char *value_key = NULL; 408
411 char *value_value = NULL; 409 if (value_key_type == PLIST_KEY) {
412 uint64_t key_length = 0; 410
413 uint64_t valval_length = 0; 411 char *result_key = NULL;
414 412 plist_get_key_val(value_key_node, &result_key);
415 plist_get_type_and_value(value_key_node, &value_key_type, (void *) (&value_key), &key_length); 413
416 plist_get_type_and_value(value_value_node, &value_value_type, (void *) (&value_value), &valval_length); 414 if (!strcmp(result_key, "Value")) {
417 415 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_generic_get_value(): success\n");
418 if (value_key_type == PLIST_KEY && !strcmp(result_key, "Value")) { 416
419 log_debug_msg("lockdownd_generic_get_value(): success\n"); 417 plist_type value_value_type;
420 value->data = value_value; 418 char *value_value = NULL;
421 value->size = valval_length; 419 uint64_t valval_length = 0;
422 ret = IPHONE_E_SUCCESS; 420
421 plist_get_type_and_value(value_value_node, &value_value_type, (void *) (&value_value), &valval_length);
422
423 value->data = value_value;
424 value->size = valval_length;
425 ret = IPHONE_E_SUCCESS;
426 }
427 free(result_key);
423 } 428 }
424 429
425 plist_free(dict); 430 plist_free(dict);
426 free(XML_content);
427 return ret; 431 return ret;
428} 432}
429 433
@@ -520,9 +524,6 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
520 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 524 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
521 plist_t dict = NULL; 525 plist_t dict = NULL;
522 plist_t dict_record = NULL; 526 plist_t dict_record = NULL;
523 int bytes = 0, i = 0;
524 char *XML_content = NULL;
525 uint32_t length = 0;
526 527
527 gnutls_datum_t device_cert = { NULL, 0 }; 528 gnutls_datum_t device_cert = { NULL, 0 };
528 gnutls_datum_t host_cert = { NULL, 0 }; 529 gnutls_datum_t host_cert = { NULL, 0 };
@@ -543,25 +544,22 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
543 544
544 /* Setup Pair request plist */ 545 /* Setup Pair request plist */
545 dict = plist_new_dict(); 546 dict = plist_new_dict();
546 plist_add_sub_element(dict, PLIST_KEY, (void *) "PairRecord", strlen("PairRecord")); 547 plist_add_sub_key_el(dict, "PairRecord");
547 dict_record = plist_add_sub_element(dict, PLIST_DICT, NULL, 0); 548 dict_record = plist_new_dict();
548 plist_add_sub_element(dict_record, PLIST_KEY, (void *) "DeviceCertificate", strlen("DeviceCertificate")); 549 plist_add_sub_node(dict, dict_record);
549 plist_add_sub_element(dict_record, PLIST_DATA, (void *) device_cert.data, device_cert.size); 550 plist_add_sub_key_el(dict_record, "DeviceCertificate");
550 plist_add_sub_element(dict_record, PLIST_KEY, (void *) "HostCertificate", strlen("HostCertificate")); 551 plist_add_sub_data_el(dict_record, device_cert.data, device_cert.size);
551 plist_add_sub_element(dict_record, PLIST_DATA, (void *) host_cert.data, host_cert.size); 552 plist_add_sub_key_el(dict_record, "HostCertificate");
552 plist_add_sub_element(dict_record, PLIST_KEY, (void *) "HostID", strlen("HostID")); 553 plist_add_sub_data_el(dict_record, host_cert.data, host_cert.size);
553 plist_add_sub_element(dict_record, PLIST_STRING, (void *) host_id, strlen(host_id)); 554 plist_add_sub_key_el(dict_record, "HostID");
554 plist_add_sub_element(dict_record, PLIST_KEY, (void *) "RootCertificate", strlen("RootCertificate")); 555 plist_add_sub_string_el(dict_record, host_id);
555 plist_add_sub_element(dict_record, PLIST_DATA, (void *) root_cert.data, root_cert.size); 556 plist_add_sub_key_el(dict_record, "RootCertificate");
556 plist_add_sub_element(dict_record, PLIST_KEY, (void *) "Request", strlen("Request")); 557 plist_add_sub_data_el(dict_record, root_cert.data, root_cert.size);
557 plist_add_sub_element(dict_record, PLIST_STRING, (void *) "Pair", strlen("Pair")); 558 plist_add_sub_key_el(dict_record, "Request");
558 plist_to_xml(dict, &XML_content, &length); 559 plist_add_sub_string_el(dict_record, "Pair");
559 log_debug_msg("XML Pairing request :\nsize : %i\nxml :\n %s", length, XML_content);
560 560
561 /* send to iPhone */ 561 /* send to iPhone */
562 ret = iphone_lckd_send(control, XML_content, length, &bytes); 562 ret = iphone_lckd_send(control, dict);
563
564 free(XML_content);
565 plist_free(dict); 563 plist_free(dict);
566 dict = NULL; 564 dict = NULL;
567 565
@@ -569,45 +567,43 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
569 return ret; 567 return ret;
570 568
571 /* Now get iPhone's answer */ 569 /* Now get iPhone's answer */
572 ret = iphone_lckd_recv(control, &XML_content, &bytes); 570 ret = iphone_lckd_recv(control, &dict);
573 571
574 if (ret != IPHONE_E_SUCCESS) 572 if (ret != IPHONE_E_SUCCESS)
575 return ret; 573 return ret;
576 574
577 log_debug_msg("lockdown_pair_device: iPhone's response to our pair request:\n"); 575 plist_t query_node = plist_find_node_by_string(dict, "Pair");
578 log_debug_msg(XML_content);
579 log_debug_msg("\n\n");
580
581 plist_from_xml(XML_content, bytes, &dict);
582 if (!dict)
583 return IPHONE_E_PLIST_ERROR;
584
585 plist_t query_node = plist_find_node(dict, PLIST_STRING, "Pair", strlen("Pair"));
586 plist_t result_key_node = plist_get_next_sibling(query_node); 576 plist_t result_key_node = plist_get_next_sibling(query_node);
587 plist_t result_value_node = plist_get_next_sibling(result_key_node); 577 plist_t result_value_node = plist_get_next_sibling(result_key_node);
588 578
589 plist_type result_key_type; 579 plist_type result_key_type = plist_get_node_type(result_key_node);
590 plist_type result_value_type; 580 plist_type result_value_type = plist_get_node_type(result_value_node);
591 char *result_key = NULL;
592 char *result_value = NULL;
593 uint64_t key_length = 0;
594 uint64_t val_length = 0;
595 581
596 plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &key_length); 582 if (result_key_type == PLIST_KEY && result_value_type == PLIST_STRING) {
597 plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &val_length);
598 583
599 if (result_key_type == PLIST_KEY && 584 char *result_key = NULL;
600 result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { 585 char *result_value = NULL;
601 ret = IPHONE_E_SUCCESS; 586
587 plist_get_key_val(result_key_node, &result_key);
588 plist_get_string_val(result_value_node, &result_value);
589
590 if (!strcmp(result_key, "Result") && !strcmp(result_value, "Success")) {
591 ret = IPHONE_E_SUCCESS;
592 }
593
594 free(result_key);
595 free(result_value);
602 } 596 }
597 plist_free(dict);
598 dict = NULL;
603 599
604 /* store public key in config if pairing succeeded */ 600 /* store public key in config if pairing succeeded */
605 if (ret == IPHONE_E_SUCCESS) { 601 if (ret == IPHONE_E_SUCCESS) {
606 log_debug_msg("lockdownd_pair_device: pair success\n"); 602 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_pair_device: pair success\n");
607 store_device_public_key(uid, public_key); 603 store_device_public_key(uid, public_key);
608 ret = IPHONE_E_SUCCESS; 604 ret = IPHONE_E_SUCCESS;
609 } else { 605 } else {
610 log_debug_msg("lockdownd_pair_device: pair failure\n"); 606 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_pair_device: pair failure\n");
611 ret = IPHONE_E_PAIRING_FAILED; 607 ret = IPHONE_E_PAIRING_FAILED;
612 } 608 }
613 free(public_key.data); 609 free(public_key.data);
@@ -625,56 +621,48 @@ void lockdownd_close(iphone_lckd_client_t control)
625 if (!control) 621 if (!control)
626 return; //IPHONE_E_INVALID_ARG; 622 return; //IPHONE_E_INVALID_ARG;
627 623
628 int bytes = 0, i = 0;
629 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 624 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
630 625
631 plist_t dict = plist_new_dict(); 626 plist_t dict = plist_new_dict();
632 plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); 627 plist_add_sub_key_el(dict, "Request");
633 plist_add_sub_element(dict, PLIST_STRING, (void *) "Goodbye", strlen("Goodbye")); 628 plist_add_sub_string_el(dict, "Goodbye");
634
635 log_debug_msg("lockdownd_close() called\n");
636 char *XML_content = NULL;
637 uint32_t length = 0;
638 629
639 plist_to_xml(dict, &XML_content, &length); 630 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_close() called\n");
640 log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content);
641 ret = iphone_lckd_send(control, XML_content, length, &bytes);
642 631
643 free(XML_content); 632 ret = iphone_lckd_send(control, dict);
644 XML_content = NULL;
645 plist_free(dict); 633 plist_free(dict);
646 dict = NULL; 634 dict = NULL;
647 635
648 ret = iphone_lckd_recv(control, &XML_content, &bytes); 636 ret = iphone_lckd_recv(control, &dict);
649 log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content);
650 plist_from_xml(XML_content, bytes, &dict);
651 637
652 if (!dict) { 638 if (!dict) {
653 log_debug_msg("lockdownd_close(): IPHONE_E_PLIST_ERROR\n"); 639 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_close(): IPHONE_E_PLIST_ERROR\n");
654 return; // IPHONE_E_PLIST_ERROR; 640 return; // IPHONE_E_PLIST_ERROR;
655 } 641 }
656 642
657 plist_t query_node = plist_find_node(dict, PLIST_STRING, "Goodbye", strlen("Goodbye")); 643 plist_t query_node = plist_find_node_by_string(dict, "Goodbye");
658 plist_t result_node = plist_get_next_sibling(query_node); 644 plist_t result_node = plist_get_next_sibling(query_node);
659 plist_t value_node = plist_get_next_sibling(result_node); 645 plist_t value_node = plist_get_next_sibling(result_node);
660 646
661 plist_type result_type; 647 plist_type result_type = plist_get_node_type(result_node);
662 plist_type value_type; 648 plist_type value_type = plist_get_node_type(value_node);
663 649
664 char *result_value = NULL; 650 if (result_type == PLIST_KEY && value_type == PLIST_STRING) {
665 char *value_value = NULL; 651 char *result_value = NULL;
666 uint64_t result_length = 0; 652 char *value_value = NULL;
667 uint64_t value_length = 0;
668 653
669 plist_get_type_and_value(result_node, &result_type, (void *) (&result_value), &result_length); 654 plist_get_key_val(result_node, &result_value);
670 plist_get_type_and_value(value_node, &value_type, (void *) (&value_value), &value_length); 655 plist_get_string_val(value_node, &value_value);
671 656
672 if (result_type == PLIST_KEY && 657 if (!strcmp(result_value, "Result") && !strcmp(value_value, "Success")) {
673 value_type == PLIST_STRING && !strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { 658 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_close(): success\n");
674 log_debug_msg("lockdownd_close(): success\n"); 659 ret = IPHONE_E_SUCCESS;
675 ret = IPHONE_E_SUCCESS; 660 }
661 free(result_value);
662 free(value_value);
676 } 663 }
677 664 plist_free(dict);
665 dict = NULL;
678 return; // ret; 666 return; // ret;
679} 667}
680 668
@@ -824,54 +812,44 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c
824 812
825 /* Setup DevicePublicKey request plist */ 813 /* Setup DevicePublicKey request plist */
826 dict = plist_new_dict(); 814 dict = plist_new_dict();
827 plist_add_sub_element(dict, PLIST_KEY, (void *) "HostID", strlen("HostID")); 815 plist_add_sub_key_el(dict, "HostID");
828 plist_add_sub_element(dict, PLIST_STRING, (void *) HostID, strlen(HostID)); 816 plist_add_sub_string_el(dict, HostID);
829 plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); 817 plist_add_sub_key_el(dict, "Request");
830 plist_add_sub_element(dict, PLIST_STRING, (void *) "StartSession", strlen("StartSession")); 818 plist_add_sub_string_el(dict, "StartSession");
831 plist_to_xml(dict, &XML_content, &length);
832 log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content);
833 819
834 ret = iphone_lckd_send(control, XML_content, length, &bytes); 820 ret = iphone_lckd_send(control, dict);
835
836 free(XML_content);
837 XML_content = NULL;
838 plist_free(dict); 821 plist_free(dict);
839 dict = NULL; 822 dict = NULL;
840 823
841 if (ret != IPHONE_E_SUCCESS) 824 if (ret != IPHONE_E_SUCCESS)
842 return ret; 825 return ret;
843 826
844 if (bytes > 0) { 827 ret = iphone_lckd_recv(control, &dict);
845 ret = iphone_lckd_recv(control, &XML_content, &bytes); 828
846 log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); 829 if (!dict)
847 plist_from_xml(XML_content, bytes, &dict); 830 return IPHONE_E_PLIST_ERROR;
848 free(XML_content); 831
849 XML_content = NULL; 832 plist_t query_node = plist_find_node(dict, PLIST_STRING, "StartSession", strlen("StartSession"));
850 if (!dict) 833 plist_t result_key_node = plist_get_next_sibling(query_node);
851 return IPHONE_E_PLIST_ERROR; 834 plist_t result_value_node = plist_get_next_sibling(result_key_node);
852 835
853 plist_t query_node = plist_find_node(dict, PLIST_STRING, "StartSession", strlen("StartSession")); 836 plist_type result_key_type = plist_get_node_type(result_key_node);
854 plist_t result_key_node = plist_get_next_sibling(query_node); 837 plist_type result_value_type = plist_get_node_type(result_value_node);
855 plist_t result_value_node = plist_get_next_sibling(result_key_node); 838
856 839 if (result_key_type == PLIST_KEY && result_value_type == PLIST_STRING) {
857 plist_type result_key_type;
858 plist_type result_value_type;
859 char *result_key = NULL; 840 char *result_key = NULL;
860 char *result_value = NULL; 841 char *result_value = NULL;
861 uint64_t key_length = 0;
862 uint64_t val_length = 0;
863 842
864 plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &key_length); 843 plist_get_key_val(result_key_node, &result_key);
865 plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &val_length); 844 plist_get_string_val(result_value_node, &result_value);
866 845
867 ret = IPHONE_E_SSL_ERROR; 846 ret = IPHONE_E_SSL_ERROR;
868 if (result_key_type == PLIST_KEY && 847 if (!strcmp(result_key, "Result") && !strcmp(result_value, "Success")) {
869 result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) {
870 // Set up GnuTLS... 848 // Set up GnuTLS...
871 //gnutls_anon_client_credentials_t anoncred; 849 //gnutls_anon_client_credentials_t anoncred;
872 gnutls_certificate_credentials_t xcred; 850 gnutls_certificate_credentials_t xcred;
873 851
874 log_debug_msg("We started the session OK, now trying GnuTLS\n"); 852 log_dbg_msg(DBGMASK_LOCKDOWND, "We started the session OK, now trying GnuTLS\n");
875 errno = 0; 853 errno = 0;
876 gnutls_global_init(); 854 gnutls_global_init();
877 //gnutls_anon_allocate_client_credentials(&anoncred); 855 //gnutls_anon_allocate_client_credentials(&anoncred);
@@ -894,59 +872,59 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c
894 } 872 }
895 gnutls_credentials_set(*control->ssl_session, GNUTLS_CRD_CERTIFICATE, xcred); // this part is killing me. 873 gnutls_credentials_set(*control->ssl_session, GNUTLS_CRD_CERTIFICATE, xcred); // this part is killing me.
896 874
897 log_debug_msg("GnuTLS step 1...\n"); 875 log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 1...\n");
898 gnutls_transport_set_ptr(*control->ssl_session, (gnutls_transport_ptr_t) control); 876 gnutls_transport_set_ptr(*control->ssl_session, (gnutls_transport_ptr_t) control);
899 log_debug_msg("GnuTLS step 2...\n"); 877 log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 2...\n");
900 gnutls_transport_set_push_function(*control->ssl_session, (gnutls_push_func) & lockdownd_secuwrite); 878 gnutls_transport_set_push_function(*control->ssl_session, (gnutls_push_func) & lockdownd_secuwrite);
901 log_debug_msg("GnuTLS step 3...\n"); 879 log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 3...\n");
902 gnutls_transport_set_pull_function(*control->ssl_session, (gnutls_pull_func) & lockdownd_securead); 880 gnutls_transport_set_pull_function(*control->ssl_session, (gnutls_pull_func) & lockdownd_securead);
903 log_debug_msg("GnuTLS step 4 -- now handshaking...\n"); 881 log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 4 -- now handshaking...\n");
904 882
905 if (errno) 883 if (errno)
906 log_debug_msg("WARN: errno says %s before handshake!\n", strerror(errno)); 884 log_dbg_msg(DBGMASK_LOCKDOWND, "WARN: errno says %s before handshake!\n", strerror(errno));
907 return_me = gnutls_handshake(*control->ssl_session); 885 return_me = gnutls_handshake(*control->ssl_session);
908 log_debug_msg("GnuTLS handshake done...\n"); 886 log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS handshake done...\n");
909 887
910 if (return_me != GNUTLS_E_SUCCESS) { 888 if (return_me != GNUTLS_E_SUCCESS) {
911 log_debug_msg("GnuTLS reported something wrong.\n"); 889 log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS reported something wrong.\n");
912 gnutls_perror(return_me); 890 gnutls_perror(return_me);
913 log_debug_msg("oh.. errno says %s\n", strerror(errno)); 891 log_dbg_msg(DBGMASK_LOCKDOWND, "oh.. errno says %s\n", strerror(errno));
914 return IPHONE_E_SSL_ERROR; 892 return IPHONE_E_SSL_ERROR;
915 } else { 893 } else {
916 control->in_SSL = 1; 894 control->in_SSL = 1;
917 ret = IPHONE_E_SUCCESS; 895 ret = IPHONE_E_SUCCESS;
918 } 896 }
919 } 897 }
920 //store session id 898 }
921 plist_t session_node = plist_find_node(dict, PLIST_KEY, "SessionID", strlen("SessionID")); 899 //store session id
922 if (session_node) { 900 plist_t session_node = plist_find_node_by_key(dict, "SessionID");
901 if (session_node) {
902
903 plist_t session_node_val = plist_get_next_sibling(session_node);
904 plist_type session_node_val_type = plist_get_node_type(session_node_val);
905
906 if (session_node_val_type == PLIST_STRING) {
923 907
924 plist_type session_node_val_type;
925 char *session_id = NULL; 908 char *session_id = NULL;
926 uint64_t session_id_length = 0; 909 plist_get_string_val(session_node_val, &session_id);
927 plist_t session_node_val = plist_get_next_sibling(session_node);
928 910
929 plist_get_type_and_value(session_node_val, &session_node_val_type, (void *) (&session_id), 911 if (session_node_val_type == PLIST_STRING && session_id) {
930 &session_id_length);
931 if (session_node_val_type == PLIST_STRING && session_id_length > 0) {
932 // we need to store the session ID for StopSession 912 // we need to store the session ID for StopSession
933 strcpy(control->session_id, session_id); 913 strcpy(control->session_id, session_id);
934 log_debug_msg("SessionID: %s\n", control->session_id); 914 log_dbg_msg(DBGMASK_LOCKDOWND, "SessionID: %s\n", control->session_id);
935 } 915 }
936 } else 916 free(session_id);
937 log_debug_msg("Failed to get SessionID!\n"); 917 }
938 plist_free(dict); 918 } else
939 dict = NULL; 919 log_dbg_msg(DBGMASK_LOCKDOWND, "Failed to get SessionID!\n");
920 plist_free(dict);
921 dict = NULL;
940 922
941 if (ret == IPHONE_E_SUCCESS) 923 if (ret == IPHONE_E_SUCCESS)
942 return ret; 924 return ret;
943 925
944 log_debug_msg("Apparently failed negotiating with lockdownd.\n"); 926 log_dbg_msg(DBGMASK_LOCKDOWND, "Apparently failed negotiating with lockdownd.\n");
945 return IPHONE_E_SSL_ERROR; 927 return IPHONE_E_SSL_ERROR;
946 } else {
947 log_debug_msg("Didn't get enough bytes.\n");
948 return IPHONE_E_NOT_ENOUGH_DATA;
949 }
950} 928}
951 929
952/** gnutls callback for writing data to the iPhone. 930/** gnutls callback for writing data to the iPhone.
@@ -962,10 +940,10 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size
962 int bytes = 0; 940 int bytes = 0;
963 iphone_lckd_client_t control; 941 iphone_lckd_client_t control;
964 control = (iphone_lckd_client_t) transport; 942 control = (iphone_lckd_client_t) transport;
965 log_debug_msg("lockdownd_secuwrite() called\n"); 943 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_secuwrite() called\n");
966 log_debug_msg("pre-send\nlength = %zi\n", length); 944 log_dbg_msg(DBGMASK_LOCKDOWND, "pre-send\nlength = %zi\n", length);
967 iphone_mux_send(control->connection, buffer, length, &bytes); 945 iphone_mux_send(control->connection, buffer, length, &bytes);
968 log_debug_msg("post-send\nsent %i bytes\n", bytes); 946 log_dbg_msg(DBGMASK_LOCKDOWND, "post-send\nsent %i bytes\n", bytes);
969 947
970 dump_debug_buffer("sslpacketwrite.out", buffer, length); 948 dump_debug_buffer("sslpacketwrite.out", buffer, length);
971 return bytes; 949 return bytes;
@@ -985,7 +963,7 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
985 char *hackhackhack = NULL; 963 char *hackhackhack = NULL;
986 iphone_lckd_client_t control; 964 iphone_lckd_client_t control;
987 control = (iphone_lckd_client_t) transport; 965 control = (iphone_lckd_client_t) transport;
988 log_debug_msg("lockdownd_securead() called\nlength = %zi\n", length); 966 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_securead() called\nlength = %zi\n", length);
989 // Buffering hack! Throw what we've got in our "buffer" into the stream first, then get more. 967 // Buffering hack! Throw what we've got in our "buffer" into the stream first, then get more.
990 if (control->gtls_buffer_hack_len > 0) { 968 if (control->gtls_buffer_hack_len > 0) {
991 if (length > control->gtls_buffer_hack_len) { // If it's asking for more than we got 969 if (length > control->gtls_buffer_hack_len) { // If it's asking for more than we got
@@ -994,7 +972,7 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
994 memcpy(buffer, control->gtls_buffer_hack, control->gtls_buffer_hack_len); // Fill their buffer partially 972 memcpy(buffer, control->gtls_buffer_hack, control->gtls_buffer_hack_len); // Fill their buffer partially
995 free(control->gtls_buffer_hack); // free our memory, it's not chained anymore 973 free(control->gtls_buffer_hack); // free our memory, it's not chained anymore
996 control->gtls_buffer_hack_len = 0; // we don't have a hack buffer anymore 974 control->gtls_buffer_hack_len = 0; // we don't have a hack buffer anymore
997 log_debug_msg("Did a partial fill to help quench thirst for data\n"); 975 log_dbg_msg(DBGMASK_LOCKDOWND, "Did a partial fill to help quench thirst for data\n");
998 } else if (length < control->gtls_buffer_hack_len) { // If it's asking for less... 976 } else if (length < control->gtls_buffer_hack_len) { // If it's asking for less...
999 control->gtls_buffer_hack_len -= length; // subtract what they're asking for 977 control->gtls_buffer_hack_len -= length; // subtract what they're asking for
1000 memcpy(buffer, control->gtls_buffer_hack, length); // fill their buffer 978 memcpy(buffer, control->gtls_buffer_hack, length); // fill their buffer
@@ -1003,33 +981,34 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
1003 free(control->gtls_buffer_hack); // Free the old one 981 free(control->gtls_buffer_hack); // Free the old one
1004 control->gtls_buffer_hack = hackhackhack; // And make it the new one. 982 control->gtls_buffer_hack = hackhackhack; // And make it the new one.
1005 hackhackhack = NULL; 983 hackhackhack = NULL;
1006 log_debug_msg("Quenched the thirst for data; new hack length is %i\n", control->gtls_buffer_hack_len); 984 log_dbg_msg(DBGMASK_LOCKDOWND, "Quenched the thirst for data; new hack length is %i\n",
985 control->gtls_buffer_hack_len);
1007 return length; // hand it over. 986 return length; // hand it over.
1008 } else { // length == hack length 987 } else { // length == hack length
1009 memcpy(buffer, control->gtls_buffer_hack, length); // copy our buffer into theirs 988 memcpy(buffer, control->gtls_buffer_hack, length); // copy our buffer into theirs
1010 free(control->gtls_buffer_hack); // free our "obligation" 989 free(control->gtls_buffer_hack); // free our "obligation"
1011 control->gtls_buffer_hack_len = 0; // free our "obligation" 990 control->gtls_buffer_hack_len = 0; // free our "obligation"
1012 log_debug_msg("Satiated the thirst for data; now we have to eventually receive again.\n"); 991 log_dbg_msg(DBGMASK_LOCKDOWND, "Satiated the thirst for data; now we have to eventually receive again.\n");
1013 return length; // hand it over 992 return length; // hand it over
1014 } 993 }
1015 } 994 }
1016 // End buffering hack! 995 // End buffering hack!
1017 char *recv_buffer = (char *) malloc(sizeof(char) * (length * 1000)); // ensuring nothing stupid happens 996 char *recv_buffer = (char *) malloc(sizeof(char) * (length * 1000)); // ensuring nothing stupid happens
1018 997
1019 log_debug_msg("pre-read\nclient wants %zi bytes\n", length); 998 log_dbg_msg(DBGMASK_LOCKDOWND, "pre-read\nclient wants %zi bytes\n", length);
1020 iphone_mux_recv(control->connection, recv_buffer, (length * 1000), &bytes); 999 iphone_mux_recv(control->connection, recv_buffer, (length * 1000), &bytes);
1021 log_debug_msg("post-read\nwe got %i bytes\n", bytes); 1000 log_dbg_msg(DBGMASK_LOCKDOWND, "post-read\nwe got %i bytes\n", bytes);
1022 if (bytes < 0) { 1001 if (bytes < 0) {
1023 log_debug_msg("lockdownd_securead(): uh oh\n"); 1002 log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_securead(): uh oh\n");
1024 log_debug_msg 1003 log_dbg_msg(DBGMASK_LOCKDOWND,
1025 ("I believe what we have here is a failure to communicate... libusb says %s but strerror says %s\n", 1004 "I believe what we have here is a failure to communicate... libusb says %s but strerror says %s\n",
1026 usb_strerror(), strerror(errno)); 1005 usb_strerror(), strerror(errno));
1027 return bytes + 28; // an errno 1006 return bytes + 28; // an errno
1028 } 1007 }
1029 if (bytes >= length) { 1008 if (bytes >= length) {
1030 if (bytes > length) { 1009 if (bytes > length) {
1031 log_debug_msg 1010 log_dbg_msg(DBGMASK_LOCKDOWND,
1032 ("lockdownd_securead: Client deliberately read less data than was there; resorting to GnuTLS buffering hack.\n"); 1011 "lockdownd_securead: Client deliberately read less data than was there; resorting to GnuTLS buffering hack.\n");
1033 if (!control->gtls_buffer_hack_len) { // if there's no hack buffer yet 1012 if (!control->gtls_buffer_hack_len) { // if there's no hack buffer yet
1034 //control->gtls_buffer_hack = strndup(recv_buffer+length, bytes-length); // strndup is NOT a good solution! 1013 //control->gtls_buffer_hack = strndup(recv_buffer+length, bytes-length); // strndup is NOT a good solution!
1035 control->gtls_buffer_hack_len += bytes - length; 1014 control->gtls_buffer_hack_len += bytes - length;
@@ -1045,10 +1024,11 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
1045 memcpy(buffer + pos_start_fill, recv_buffer, length); 1024 memcpy(buffer + pos_start_fill, recv_buffer, length);
1046 free(recv_buffer); 1025 free(recv_buffer);
1047 if (bytes == length) { 1026 if (bytes == length) {
1048 log_debug_msg("Returning how much we received.\n"); 1027 log_dbg_msg(DBGMASK_LOCKDOWND, "Returning how much we received.\n");
1049 return bytes; 1028 return bytes;
1050 } else { 1029 } else {
1051 log_debug_msg("Returning what they want to hear.\nHack length: %i\n", control->gtls_buffer_hack_len); 1030 log_dbg_msg(DBGMASK_LOCKDOWND, "Returning what they want to hear.\nHack length: %i\n",
1031 control->gtls_buffer_hack_len);
1052 return length; 1032 return length;
1053 } 1033 }
1054 } 1034 }
@@ -1073,95 +1053,72 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char
1073 if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id)) 1053 if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id))
1074 return IPHONE_E_SSL_ERROR; 1054 return IPHONE_E_SSL_ERROR;
1075 1055
1076
1077 plist_t dict = NULL; 1056 plist_t dict = NULL;
1078 char *XML_content = NULL; 1057 uint32_t port_loc = 0;
1079 uint32_t length, i = 0, port_loc = 0, bytes = 0;
1080 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 1058 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
1081 1059
1082 free(host_id); 1060 free(host_id);
1083 host_id = NULL; 1061 host_id = NULL;
1084 1062
1085 dict = plist_new_dict(); 1063 dict = plist_new_dict();
1086 plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); 1064 plist_add_sub_key_el(dict, "Request");
1087 plist_add_sub_element(dict, PLIST_STRING, (void *) "StartService", strlen("StartService")); 1065 plist_add_sub_string_el(dict, "StartService");
1088 plist_add_sub_element(dict, PLIST_KEY, (void *) "Service", strlen("Service")); 1066 plist_add_sub_key_el(dict, "Service");
1089 plist_add_sub_element(dict, PLIST_STRING, (void *) service, strlen(service)); 1067 plist_add_sub_string_el(dict, service);
1090 plist_to_xml(dict, &XML_content, &length);
1091 1068
1092 /* send to iPhone */ 1069 /* send to iPhone */
1093 log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); 1070 ret = iphone_lckd_send(client, dict);
1094 ret = iphone_lckd_send(client, XML_content, length, &bytes);
1095
1096 free(XML_content);
1097 XML_content = NULL;
1098 plist_free(dict); 1071 plist_free(dict);
1099 dict = NULL; 1072 dict = NULL;
1100 1073
1101 if (IPHONE_E_SUCCESS != ret) 1074 if (IPHONE_E_SUCCESS != ret)
1102 return ret; 1075 return ret;
1103 1076
1104 ret = iphone_lckd_recv(client, &XML_content, &bytes); 1077 ret = iphone_lckd_recv(client, &dict);
1105 1078
1106 if (IPHONE_E_SUCCESS != ret) 1079 if (IPHONE_E_SUCCESS != ret)
1107 return ret; 1080 return ret;
1108 1081
1109 plist_from_xml(XML_content, bytes, &dict);
1110 if (!dict) 1082 if (!dict)
1111 return IPHONE_E_PLIST_ERROR; 1083 return IPHONE_E_PLIST_ERROR;
1112 1084
1085 plist_t query_node = plist_find_node_by_string(dict, "StartService");
1086 plist_t result_key_node = plist_get_next_sibling(query_node);
1087 plist_t result_value_node = plist_get_next_sibling(result_key_node);
1113 1088
1114 if (bytes <= 0) 1089 plist_t port_key_node = plist_find_node_by_key(dict, "Port");
1115 return IPHONE_E_NOT_ENOUGH_DATA; 1090 plist_t port_value_node = plist_get_next_sibling(port_key_node);
1116 else {
1117 1091
1118 plist_t query_node = plist_find_node(dict, PLIST_STRING, "StartService", strlen("StartService")); 1092 plist_type result_key_type = plist_get_node_type(result_key_node);
1119 plist_t result_key_node = plist_get_next_sibling(query_node); 1093 plist_type result_value_type = plist_get_node_type(result_value_node);
1120 plist_t result_value_node = plist_get_next_sibling(result_key_node); 1094 plist_type port_key_type = plist_get_node_type(port_key_node);
1095 plist_type port_value_type = plist_get_node_type(port_value_node);
1121 1096
1122 plist_t port_key_node = plist_find_node(dict, PLIST_KEY, "Port", strlen("Port")); 1097 if (result_key_type == PLIST_KEY && result_value_type == PLIST_STRING && port_key_type == PLIST_KEY
1123 plist_t port_value_node = plist_get_next_sibling(port_key_node); 1098 && port_value_type == PLIST_UINT) {
1124 1099
1125 plist_type result_key_type;
1126 plist_type result_value_type;
1127 plist_type port_key_type;
1128 plist_type port_value_type;
1129 char *result_key = NULL; 1100 char *result_key = NULL;
1130 char *result_value = NULL; 1101 char *result_value = NULL;
1131 char *port_key = NULL; 1102 char *port_key = NULL;
1132 uint64_t res_key_length = 0;
1133 uint64_t res_val_length = 0;
1134 uint64_t port_key_length = 0;
1135 uint64_t port_val_length = 0;
1136 uint64_t port_value = 0; 1103 uint64_t port_value = 0;
1137 1104
1138 plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &res_key_length); 1105 plist_get_key_val(result_key_node, &result_key);
1139 plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &res_val_length); 1106 plist_get_string_val(result_value_node, &result_value);
1140 plist_get_type_and_value(port_key_node, &port_key_type, (void *) (&port_key), &port_key_length); 1107 plist_get_key_val(port_key_node, &port_key);
1141 plist_get_type_and_value(port_value_node, &port_value_type, (void *) (&port_value), &port_val_length); 1108 plist_get_uint_val(port_value_node, &port_value);
1142 1109
1143 if (result_key_type == PLIST_KEY && 1110 if (!strcmp(result_key, "Result") && !strcmp(result_value, "Success") && !strcmp(port_key, "Port")) {
1144 result_value_type == PLIST_STRING &&
1145 port_key_type == PLIST_KEY &&
1146 port_value_type == PLIST_UINT &&
1147 !strcmp(result_key, "Result") && !strcmp(result_value, "Success") && !strcmp(port_key, "Port")) {
1148 port_loc = port_value; 1111 port_loc = port_value;
1149 ret = IPHONE_E_SUCCESS; 1112 ret = IPHONE_E_SUCCESS;
1150 } 1113 }
1151 1114
1152 log_debug_msg("lockdownd_start_service(): DATA RECEIVED:\n\n"); 1115 if (port && ret == IPHONE_E_SUCCESS)
1153 log_debug_msg(XML_content);
1154 log_debug_msg("end data received by lockdownd_start_service()\n");
1155
1156 free(XML_content);
1157 plist_free(dict);
1158 dict = NULL;
1159 if (port && ret == IPHONE_E_SUCCESS) {
1160 *port = port_loc; 1116 *port = port_loc;
1161 return IPHONE_E_SUCCESS; 1117 else
1162 } else 1118 ret = IPHONE_E_UNKNOWN_ERROR;
1163 return IPHONE_E_UNKNOWN_ERROR;
1164 } 1119 }
1165 1120
1166 return IPHONE_E_UNKNOWN_ERROR; 1121 plist_free(dict);
1122 dict = NULL;
1123 return ret;
1167} 1124}
diff --git a/src/utils.h b/src/utils.h
index c1a8e54..d9a441d 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -24,6 +24,8 @@
24 24
25#include "libiphone/libiphone.h" 25#include "libiphone/libiphone.h"
26 26
27#define DBGMASK_ALL 0xFFFF
28#define DBGMASK_NONE 0x0000
27#define DBGMASK_USBMUX (1 << 1) 29#define DBGMASK_USBMUX (1 << 1)
28#define DBGMASK_LOCKDOWND (1 << 2) 30#define DBGMASK_LOCKDOWND (1 << 2)
29#define DBGMASK_MOBILESYNC (1 << 3) 31#define DBGMASK_MOBILESYNC (1 << 3)