summaryrefslogtreecommitdiffstats
path: root/src/lockdown.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/lockdown.c')
-rw-r--r--src/lockdown.c164
1 files changed, 89 insertions, 75 deletions
diff --git a/src/lockdown.c b/src/lockdown.c
index a22b896..e5420a3 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -117,7 +117,7 @@ iphone_error_t iphone_lckd_free_client( iphone_lckd_client_t client ) {
117 * @return The number of bytes received 117 * @return The number of bytes received
118 */ 118 */
119iphone_error_t iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data, uint32_t *recv_bytes ) { 119iphone_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; 120 if (!client || !dump_data || !recv_bytes) return IPHONE_E_INVALID_ARG;
121 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 121 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
122 char *receive; 122 char *receive;
123 uint32 datalen = 0, bytes = 0; 123 uint32 datalen = 0, bytes = 0;
@@ -188,12 +188,13 @@ iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, u
188 * 188 *
189 * @return 1 on success and 0 on failure. 189 * @return 1 on success and 0 on failure.
190 */ 190 */
191int lockdownd_hello(iphone_lckd_client_t control) { 191iphone_error_t lockdownd_hello(iphone_lckd_client_t control) {
192 if (!control) return 0; 192 if (!control) return IPHONE_E_INVALID_ARG;
193 xmlDocPtr plist = new_plist(); 193 xmlDocPtr plist = new_plist();
194 xmlNode *dict, *key; 194 xmlNode *dict, *key;
195 char **dictionary; 195 char **dictionary;
196 int bytes = 0, i = 0; 196 int bytes = 0, i = 0;
197 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
197 198
198 if (debug) printf("lockdownd_hello() called\n"); 199 if (debug) printf("lockdownd_hello() called\n");
199 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 200 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0);
@@ -202,33 +203,33 @@ int lockdownd_hello(iphone_lckd_client_t control) {
202 uint32 length; 203 uint32 length;
203 204
204 xmlDocDumpMemory(plist, (xmlChar **)&XML_content, &length); 205 xmlDocDumpMemory(plist, (xmlChar **)&XML_content, &length);
205 bytes = iphone_lckd_send(control, XML_content, length); 206 ret = iphone_lckd_send(control, XML_content, length, &bytes);
206 207
207 xmlFree(XML_content); 208 xmlFree(XML_content);
208 xmlFreeDoc(plist); plist = NULL; 209 xmlFreeDoc(plist); plist = NULL;
209 bytes = iphone_lckd_recv(control, &XML_content); 210 ret = iphone_lckd_recv(control, &XML_content, &bytes);
210 211
211 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); 212 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0);
212 if (!plist) return 0; 213 if (!plist) return IPHONE_E_PLIST_ERROR;
213 dict = xmlDocGetRootElement(plist); 214 dict = xmlDocGetRootElement(plist);
214 for (dict = dict->children; dict; dict = dict->next) { 215 for (dict = dict->children; dict; dict = dict->next) {
215 if (!xmlStrcmp(dict->name, "dict")) break; 216 if (!xmlStrcmp(dict->name, "dict")) break;
216 } 217 }
217 if (!dict) return 0; 218 if (!dict) return IPHONE_E_DICT_ERROR;
218 dictionary = read_dict_element_strings(dict); 219 dictionary = read_dict_element_strings(dict);
219 xmlFreeDoc(plist); 220 xmlFreeDoc(plist);
220 free(XML_content); 221 free(XML_content);
221 222
222 for (i = 0; dictionary[i]; i+=2) { 223 for (i = 0; dictionary[i]; i+=2) {
223 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i+1], "Success")) { 224 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i+1], "Success")) {
224 free_dictionary(dictionary);
225 if (debug) printf("lockdownd_hello(): success\n"); 225 if (debug) printf("lockdownd_hello(): success\n");
226 return 1; 226 ret = IPHONE_E_SUCCESS;
227 break;
227 } 228 }
228 } 229 }
229 230
230 free_dictionary(dictionary); 231 free_dictionary(dictionary);
231 return 0; 232 return ret;
232} 233}
233 234
234/** Generic function to handle simple (key, value) requests. 235/** Generic function to handle simple (key, value) requests.
@@ -237,10 +238,11 @@ int lockdownd_hello(iphone_lckd_client_t control) {
237 * @param key the key to request 238 * @param key the key to request
238 * @param value a pointer to the requested value 239 * @param value a pointer to the requested value
239 * 240 *
240 * @return 1 on success and 0 on failure. 241 * @return IPHONE_E_SUCCESS on success.
241 */ 242 */
242int lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, char **value) 243iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, char **value)
243{ 244{
245 if (!control || !req_key || !value || (value && *value)) return IPHONE_E_INVALID_ARG;
244 xmlDocPtr plist = new_plist(); 246 xmlDocPtr plist = new_plist();
245 xmlNode *dict = NULL; 247 xmlNode *dict = NULL;
246 xmlNode *key = NULL;; 248 xmlNode *key = NULL;;
@@ -248,6 +250,7 @@ int lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, cha
248 int bytes = 0, i = 0; 250 int bytes = 0, i = 0;
249 char *XML_content = NULL; 251 char *XML_content = NULL;
250 uint32 length = 0; 252 uint32 length = 0;
253 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
251 254
252 /* Setup DevicePublicKey request plist */ 255 /* Setup DevicePublicKey request plist */
253 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 256 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0);
@@ -256,21 +259,25 @@ int lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, cha
256 xmlDocDumpMemory(plist, (xmlChar**)&XML_content, &length); 259 xmlDocDumpMemory(plist, (xmlChar**)&XML_content, &length);
257 260
258 /* send to iPhone */ 261 /* send to iPhone */
259 bytes = iphone_lckd_send(control, XML_content, length); 262 ret = iphone_lckd_send(control, XML_content, length, &bytes);
260 263
261 xmlFree(XML_content); 264 xmlFree(XML_content);
262 xmlFreeDoc(plist); plist = NULL; 265 xmlFreeDoc(plist); plist = NULL;
263 266
267 if (ret != IPHONE_E_SUCCESS) return ret;
268
264 /* Now get iPhone's answer */ 269 /* Now get iPhone's answer */
265 bytes = iphone_lckd_recv(control, &XML_content); 270 ret = iphone_lckd_recv(control, &XML_content, &bytes);
271
272 if (ret != IPHONE_E_SUCCESS) return ret;
266 273
267 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); 274 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0);
268 if (!plist) return 0; 275 if (!plist) return IPHONE_E_PLIST_ERROR;
269 dict = xmlDocGetRootElement(plist); 276 dict = xmlDocGetRootElement(plist);
270 for (dict = dict->children; dict; dict = dict->next) { 277 for (dict = dict->children; dict; dict = dict->next) {
271 if (!xmlStrcmp(dict->name, "dict")) break; 278 if (!xmlStrcmp(dict->name, "dict")) break;
272 } 279 }
273 if (!dict) return 0; 280 if (!dict) return IPHONE_E_DICT_ERROR;
274 281
275 /* Parse xml to check success and to find public key */ 282 /* Parse xml to check success and to find public key */
276 dictionary = read_dict_element_strings(dict); 283 dictionary = read_dict_element_strings(dict);
@@ -291,7 +298,8 @@ int lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, cha
291 free_dictionary(dictionary); 298 free_dictionary(dictionary);
292 dictionary = NULL; 299 dictionary = NULL;
293 } 300 }
294 return success; 301 if (success) ret = IPHONE_E_SUCCESS;
302 return ret;
295} 303}
296 304
297/** Askes for the device's unique id. Part of the lockdownd handshake. 305/** Askes for the device's unique id. Part of the lockdownd handshake.
@@ -300,7 +308,7 @@ int lockdownd_generic_get_value(iphone_lckd_client_t control, char *req_key, cha
300 * 308 *
301 * @return 1 on success and 0 on failure. 309 * @return 1 on success and 0 on failure.
302 */ 310 */
303int lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid) 311iphone_error_t lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid)
304{ 312{
305 return lockdownd_generic_get_value(control, "UniqueDeviceID", uid); 313 return lockdownd_generic_get_value(control, "UniqueDeviceID", uid);
306} 314}
@@ -311,7 +319,7 @@ int lockdownd_get_device_uid(iphone_lckd_client_t control, char **uid)
311 * 319 *
312 * @return 1 on success and 0 on failure. 320 * @return 1 on success and 0 on failure.
313 */ 321 */
314int lockdownd_get_device_public_key(iphone_lckd_client_t control, char **public_key) 322iphone_error_t lockdownd_get_device_public_key(iphone_lckd_client_t control, char **public_key)
315{ 323{
316 return lockdownd_generic_get_value(control, "DevicePublicKey", public_key); 324 return lockdownd_generic_get_value(control, "DevicePublicKey", public_key);
317} 325}
@@ -331,16 +339,16 @@ iphone_error_t iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_clie
331 char *host_id = NULL; 339 char *host_id = NULL;
332 340
333 iphone_lckd_client_t client_loc = new_lockdownd_client( device ); 341 iphone_lckd_client_t client_loc = new_lockdownd_client( device );
334 if (!lockdownd_hello(client_loc)){ 342 if (IPHONE_E_SUCCESS != lockdownd_hello(client_loc)){
335 fprintf(stderr, "Hello failed in the lockdownd client.\n"); 343 fprintf(stderr, "Hello failed in the lockdownd client.\n");
336 ret = IPHONE_E_NOT_ENOUGH_DATA; 344 ret = IPHONE_E_NOT_ENOUGH_DATA;
337 } 345 }
338 346
339 347
340 char *uid = NULL; 348 char *uid = NULL;
341 if(IPHONE_E_SUCCESS == ret && !lockdownd_get_device_uid(client_loc, &uid)){ 349 ret = lockdownd_get_device_uid(client_loc, &uid);
350 if(IPHONE_E_SUCCESS != ret){
342 fprintf(stderr, "Device refused to send uid.\n"); 351 fprintf(stderr, "Device refused to send uid.\n");
343 ret = IPHONE_E_NOT_ENOUGH_DATA;
344 } 352 }
345 353
346 host_id = get_host_id(); 354 host_id = get_host_id();
@@ -357,9 +365,8 @@ iphone_error_t iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_clie
357 uid = NULL; 365 uid = NULL;
358 } 366 }
359 367
360 if (IPHONE_E_SUCCESS == ret && lockdownd_start_SSL_session(client_loc, host_id)) { 368 ret = lockdownd_start_SSL_session(client_loc, host_id);
361 ret = IPHONE_E_SUCCESS; 369 if (IPHONE_E_SUCCESS != ret ) {
362 } else {
363 ret = IPHONE_E_SSL_ERROR; 370 ret = IPHONE_E_SSL_ERROR;
364 fprintf(stderr, "SSL Session opening failed.\n"); 371 fprintf(stderr, "SSL Session opening failed.\n");
365 } 372 }
@@ -381,9 +388,9 @@ iphone_error_t iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_clie
381 * 388 *
382 * @return 1 on success and 0 on failure 389 * @return 1 on success and 0 on failure
383 */ 390 */
384int lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id) 391iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id)
385{ 392{
386 int ret = 0; 393 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
387 xmlDocPtr plist = new_plist(); 394 xmlDocPtr plist = new_plist();
388 xmlNode *dict = NULL; 395 xmlNode *dict = NULL;
389 xmlNode *dictRecord = NULL; 396 xmlNode *dictRecord = NULL;
@@ -397,15 +404,16 @@ int lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id
397 char* root_cert_b64 = NULL; 404 char* root_cert_b64 = NULL;
398 char *public_key_b64 = NULL; 405 char *public_key_b64 = NULL;
399 406
400 if(!lockdownd_get_device_public_key(control, &public_key_b64)){ 407 ret = lockdownd_get_device_public_key(control, &public_key_b64);
408 if(ret != IPHONE_E_SUCCESS){
401 fprintf(stderr, "Device refused to send public key.\n"); 409 fprintf(stderr, "Device refused to send public key.\n");
402 return 0; 410 return ret;
403 } 411 }
404 412
405 413 ret = lockdownd_gen_pair_cert(public_key_b64, &device_cert_b64, &host_cert_b64, &root_cert_b64);
406 if(!lockdownd_gen_pair_cert(public_key_b64, &device_cert_b64, &host_cert_b64, &root_cert_b64)){ 414 if(ret != IPHONE_E_SUCCESS){
407 free(public_key_b64); 415 free(public_key_b64);
408 return 0; 416 return ret;
409 } 417 }
410 418
411 /* Setup Pair request plist */ 419 /* Setup Pair request plist */
@@ -423,13 +431,17 @@ int lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id
423 printf("XML Pairing request : %s\n",XML_content); 431 printf("XML Pairing request : %s\n",XML_content);
424 432
425 /* send to iPhone */ 433 /* send to iPhone */
426 bytes = iphone_lckd_send(control, XML_content, length); 434 ret = iphone_lckd_send(control, XML_content, length, &bytes);
427 435
428 xmlFree(XML_content); 436 xmlFree(XML_content);
429 xmlFreeDoc(plist); plist = NULL; 437 xmlFreeDoc(plist); plist = NULL;
430 438
439 if (ret != IPHONE_E_SUCCESS) return ret;
440
431 /* Now get iPhone's answer */ 441 /* Now get iPhone's answer */
432 bytes = iphone_lckd_recv(control, &XML_content); 442 ret = iphone_lckd_recv(control, &XML_content, &bytes);
443
444 if (ret != IPHONE_E_SUCCESS) return ret;
433 445
434 if (debug) { 446 if (debug) {
435 printf("lockdown_pair_device: iPhone's response to our pair request:\n"); 447 printf("lockdown_pair_device: iPhone's response to our pair request:\n");
@@ -440,7 +452,7 @@ int lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id
440 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); 452 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0);
441 if (!plist) { 453 if (!plist) {
442 free(public_key_b64); 454 free(public_key_b64);
443 return 0; 455 return IPHONE_E_PLIST_ERROR;
444 } 456 }
445 dict = xmlDocGetRootElement(plist); 457 dict = xmlDocGetRootElement(plist);
446 for (dict = dict->children; dict; dict = dict->next) { 458 for (dict = dict->children; dict; dict = dict->next) {
@@ -448,7 +460,7 @@ int lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id
448 } 460 }
449 if (!dict) { 461 if (!dict) {
450 free(public_key_b64); 462 free(public_key_b64);
451 return 0; 463 return IPHONE_E_DICT_ERROR;
452 } 464 }
453 465
454 /* Parse xml to check success and to find public key */ 466 /* Parse xml to check success and to find public key */
@@ -472,9 +484,10 @@ int lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id
472 if (success) { 484 if (success) {
473 if (debug) printf("lockdownd_pair_device: pair success\n"); 485 if (debug) printf("lockdownd_pair_device: pair success\n");
474 store_device_public_key(uid, public_key_b64); 486 store_device_public_key(uid, public_key_b64);
475 ret = 1; 487 ret = IPHONE_E_SUCCESS;
476 } else { 488 } else {
477 if (debug) printf("lockdownd_pair_device: pair failure\n"); 489 if (debug) printf("lockdownd_pair_device: pair failure\n");
490 ret = IPHONE_E_PAIRING_FAILED;
478 } 491 }
479 free(public_key_b64); 492 free(public_key_b64);
480 return ret; 493 return ret;
@@ -483,11 +496,12 @@ int lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id
483/** Generates the device certificate from the public key as well as the host 496/** Generates the device certificate from the public key as well as the host
484 * and root certificates. 497 * and root certificates.
485 * 498 *
486 * @return 1 on success and 0 on failure. 499 * @return IPHONE_E_SUCCESS on success.
487 */ 500 */
488int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char **host_cert_b64, char **root_cert_b64) 501iphone_error_t lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char **host_cert_b64, char **root_cert_b64)
489{ 502{
490 int ret = 0, error = 0; 503 if (!public_key_b64 || !device_cert_b64 || !host_cert_b64 || !root_cert_b64) return IPHONE_E_INVALID_ARG;
504 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
491 505
492 gnutls_datum_t modulus = {NULL, 0}; 506 gnutls_datum_t modulus = {NULL, 0};
493 gnutls_datum_t exponent = {NULL, 0}; 507 gnutls_datum_t exponent = {NULL, 0};
@@ -501,7 +515,6 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char *
501 /* now decode the PEM encoded key */ 515 /* now decode the PEM encoded key */
502 gnutls_datum_t der_pub_key; 516 gnutls_datum_t der_pub_key;
503 if( GNUTLS_E_SUCCESS == gnutls_pem_base64_decode_alloc ("RSA PUBLIC KEY", &pem_pub_key, &der_pub_key) ){ 517 if( GNUTLS_E_SUCCESS == gnutls_pem_base64_decode_alloc ("RSA PUBLIC KEY", &pem_pub_key, &der_pub_key) ){
504 ret = 1;
505 518
506 /* initalize asn.1 parser */ 519 /* initalize asn.1 parser */
507 ASN1_TYPE pkcs1 = ASN1_TYPE_EMPTY; 520 ASN1_TYPE pkcs1 = ASN1_TYPE_EMPTY;
@@ -522,7 +535,7 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char *
522 ret1 = asn1_read_value (asn1_pub_key, "modulus", modulus.data, &modulus.size); 535 ret1 = asn1_read_value (asn1_pub_key, "modulus", modulus.data, &modulus.size);
523 ret2 = asn1_read_value (asn1_pub_key, "publicExponent", exponent.data, &exponent.size); 536 ret2 = asn1_read_value (asn1_pub_key, "publicExponent", exponent.data, &exponent.size);
524 if (ASN1_SUCCESS == ret1 && ASN1_SUCCESS == ret2) 537 if (ASN1_SUCCESS == ret1 && ASN1_SUCCESS == ret2)
525 ret = 1; 538 ret = IPHONE_E_SUCCESS;
526 } 539 }
527 if (asn1_pub_key) 540 if (asn1_pub_key)
528 asn1_delete_structure(&asn1_pub_key); 541 asn1_delete_structure(&asn1_pub_key);
@@ -532,7 +545,7 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char *
532 } 545 }
533 546
534 /* now generate certifcates */ 547 /* now generate certifcates */
535 if (1 == ret && 0 != modulus.size && 0 != exponent.size) { 548 if (IPHONE_E_SUCCESS == ret && 0 != modulus.size && 0 != exponent.size) {
536 549
537 gnutls_global_init(); 550 gnutls_global_init();
538 gnutls_datum_t essentially_null = {strdup("abababababababab"), strlen("abababababababab")}; 551 gnutls_datum_t essentially_null = {strdup("abababababababab"), strlen("abababababababab")};
@@ -552,20 +565,20 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char *
552 /* get root cert */ 565 /* get root cert */
553 gnutls_datum_t pem_root_cert = {NULL, 0}; 566 gnutls_datum_t pem_root_cert = {NULL, 0};
554 get_root_certificate(&pem_root_cert); 567 get_root_certificate(&pem_root_cert);
555 ret = gnutls_x509_crt_import(root_cert, &pem_root_cert, GNUTLS_X509_FMT_PEM); 568 if (GNUTLS_E_SUCCESS != gnutls_x509_crt_import(root_cert, &pem_root_cert, GNUTLS_X509_FMT_PEM))
556 if (ret != GNUTLS_E_SUCCESS) error = 1; 569 ret = IPHONE_E_SSL_ERROR;
557 570
558 /* get host cert */ 571 /* get host cert */
559 gnutls_datum_t pem_host_cert = {NULL, 0}; 572 gnutls_datum_t pem_host_cert = {NULL, 0};
560 get_host_certificate(&pem_host_cert); 573 get_host_certificate(&pem_host_cert);
561 ret = gnutls_x509_crt_import(host_cert, &pem_host_cert, GNUTLS_X509_FMT_PEM); 574 if (GNUTLS_E_SUCCESS != gnutls_x509_crt_import(host_cert, &pem_host_cert, GNUTLS_X509_FMT_PEM))
562 if (ret != GNUTLS_E_SUCCESS) error = 1; 575 ret = IPHONE_E_SSL_ERROR;
563 576
564 /* get root private key */ 577 /* get root private key */
565 gnutls_datum_t pem_root_priv = {NULL, 0}; 578 gnutls_datum_t pem_root_priv = {NULL, 0};
566 get_root_private_key(&pem_root_priv); 579 get_root_private_key(&pem_root_priv);
567 ret = gnutls_x509_privkey_import(root_privkey, &pem_root_priv, GNUTLS_X509_FMT_PEM); 580 if (GNUTLS_E_SUCCESS != gnutls_x509_privkey_import(root_privkey, &pem_root_priv, GNUTLS_X509_FMT_PEM))
568 if (ret != GNUTLS_E_SUCCESS) error = 1; 581 ret = IPHONE_E_SSL_ERROR;
569 582
570 /* generate device certificate */ 583 /* generate device certificate */
571 gnutls_x509_crt_set_key(dev_cert, fake_privkey); 584 gnutls_x509_crt_set_key(dev_cert, fake_privkey);
@@ -576,7 +589,7 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char *
576 gnutls_x509_crt_set_expiration_time(dev_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); 589 gnutls_x509_crt_set_expiration_time(dev_cert, time(NULL) + (60 * 60 * 24 * 365 * 10));
577 gnutls_x509_crt_sign(dev_cert, root_cert, root_privkey); 590 gnutls_x509_crt_sign(dev_cert, root_cert, root_privkey);
578 591
579 if (!error) { 592 if (IPHONE_E_SUCCESS == ret) {
580 /* if everything went well, export in PEM format */ 593 /* if everything went well, export in PEM format */
581 gnutls_datum_t dev_pem = {NULL, 0}; 594 gnutls_datum_t dev_pem = {NULL, 0};
582 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &dev_pem.size); 595 gnutls_x509_crt_export(dev_cert, GNUTLS_X509_FMT_PEM, NULL, &dev_pem.size);
@@ -587,7 +600,6 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char *
587 *device_cert_b64 = g_base64_encode(dev_pem.data, dev_pem.size); 600 *device_cert_b64 = g_base64_encode(dev_pem.data, dev_pem.size);
588 *host_cert_b64 = g_base64_encode(pem_host_cert.data, pem_host_cert.size); 601 *host_cert_b64 = g_base64_encode(pem_host_cert.data, pem_host_cert.size);
589 *root_cert_b64 = g_base64_encode(pem_root_cert.data, pem_root_cert.size); 602 *root_cert_b64 = g_base64_encode(pem_root_cert.data, pem_root_cert.size);
590 ret = 1;
591 } 603 }
592 gnutls_free(pem_root_priv.data); 604 gnutls_free(pem_root_priv.data);
593 gnutls_free(pem_root_cert.data); 605 gnutls_free(pem_root_cert.data);
@@ -600,12 +612,8 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char *
600 612
601 gnutls_free(der_pub_key.data); 613 gnutls_free(der_pub_key.data);
602 g_free(pem_pub_key.data); 614 g_free(pem_pub_key.data);
603 615
604 if (error) { 616 return ret;
605 return 0;
606 } else {
607 return ret;
608 }
609} 617}
610 618
611/** Starts SSL communication with lockdownd after the iPhone has been paired. 619/** Starts SSL communication with lockdownd after the iPhone has been paired.
@@ -615,37 +623,41 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char *
615 * 623 *
616 * @return 1 on success and 0 on failure 624 * @return 1 on success and 0 on failure
617 */ 625 */
618int lockdownd_start_SSL_session(iphone_lckd_client_t control, const char *HostID) { 626iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const char *HostID) {
619 xmlDocPtr plist = new_plist(); 627 xmlDocPtr plist = new_plist();
620 xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 628 xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0);
621 xmlNode *key; 629 xmlNode *key;
622 char *what2send = NULL, **dictionary = NULL; 630 char *what2send = NULL, **dictionary = NULL;
623 uint32 len = 0, bytes = 0, return_me = 0, i = 0; 631 uint32 len = 0, bytes = 0, return_me = 0, i = 0;
632 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
624 // end variables 633 // end variables
625 634
626 key = add_key_str_dict_element(plist, dict, "HostID", HostID, 1); 635 key = add_key_str_dict_element(plist, dict, "HostID", HostID, 1);
627 if (!key) { 636 if (!key) {
628 if (debug) printf("Couldn't add a key.\n"); 637 if (debug) printf("Couldn't add a key.\n");
629 xmlFreeDoc(plist); 638 xmlFreeDoc(plist);
630 return 0; 639 return IPHONE_E_DICT_ERROR;
631 } 640 }
632 key = add_key_str_dict_element(plist, dict, "Request", "StartSession", 1); 641 key = add_key_str_dict_element(plist, dict, "Request", "StartSession", 1);
633 if (!key) { 642 if (!key) {
634 if (debug) printf("Couldn't add a key.\n"); 643 if (debug) printf("Couldn't add a key.\n");
635 xmlFreeDoc(plist); 644 xmlFreeDoc(plist);
636 return 0; 645 return IPHONE_E_DICT_ERROR;
637 } 646 }
638 647
639 xmlDocDumpMemory(plist, (xmlChar **)&what2send, &len); 648 xmlDocDumpMemory(plist, (xmlChar **)&what2send, &len);
640 bytes = iphone_lckd_send(control, what2send, len); 649 ret = iphone_lckd_send(control, what2send, len, &bytes);
641 650
642 xmlFree(what2send); 651 xmlFree(what2send);
643 xmlFreeDoc(plist); 652 xmlFreeDoc(plist);
653
654 if (ret != IPHONE_E_SUCCESS) return ret;
644 655
645 if (bytes > 0) { 656 if (bytes > 0) {
646 len = iphone_lckd_recv(control, &what2send); 657 ret = iphone_lckd_recv(control, &what2send, &len);
647 plist = xmlReadMemory(what2send, len, NULL, NULL, 0); 658 plist = xmlReadMemory(what2send, len, NULL, NULL, 0);
648 dict = xmlDocGetRootElement(plist); 659 dict = xmlDocGetRootElement(plist);
660 if (!dict) return IPHONE_E_DICT_ERROR;
649 for (dict = dict->children; dict; dict = dict->next) { 661 for (dict = dict->children; dict; dict = dict->next) {
650 if (!xmlStrcmp(dict->name, "dict")) break; 662 if (!xmlStrcmp(dict->name, "dict")) break;
651 } 663 }
@@ -699,10 +711,10 @@ int lockdownd_start_SSL_session(iphone_lckd_client_t control, const char *HostID
699 if (debug) printf("GnuTLS reported something wrong.\n"); 711 if (debug) printf("GnuTLS reported something wrong.\n");
700 gnutls_perror(return_me); 712 gnutls_perror(return_me);
701 if (debug) printf("oh.. errno says %s\n", strerror(errno)); 713 if (debug) printf("oh.. errno says %s\n", strerror(errno));
702 return 0; 714 return IPHONE_E_SSL_ERROR;
703 } else { 715 } else {
704 control->in_SSL = 1; 716 control->in_SSL = 1;
705 return 1; 717 return IPHONE_E_SUCCESS;
706 } 718 }
707 } 719 }
708 } 720 }
@@ -716,10 +728,10 @@ int lockdownd_start_SSL_session(iphone_lckd_client_t control, const char *HostID
716 } 728 }
717 729
718 free_dictionary(dictionary); 730 free_dictionary(dictionary);
719 return 0; 731 return IPHONE_E_SSL_ERROR;
720 } else { 732 } else {
721 if (debug) printf("Didn't get enough bytes.\n"); 733 if (debug) printf("Didn't get enough bytes.\n");
722 return 0; 734 return IPHONE_E_NOT_ENOUGH_DATA;
723 } 735 }
724} 736}
725 737
@@ -737,7 +749,7 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size
737 control = (iphone_lckd_client_t)transport; 749 control = (iphone_lckd_client_t)transport;
738 if (debug) printf("lockdownd_secuwrite() called\n"); 750 if (debug) printf("lockdownd_secuwrite() called\n");
739 if (debug) printf("pre-send\nlength = %zi\n", length); 751 if (debug) printf("pre-send\nlength = %zi\n", length);
740 bytes = iphone_mux_send(control->connection, buffer, length); 752 iphone_mux_send(control->connection, buffer, length, &bytes);
741 if (debug) printf("post-send\nsent %i bytes\n", bytes); 753 if (debug) printf("post-send\nsent %i bytes\n", bytes);
742 if (debug) { 754 if (debug) {
743 FILE *my_ssl_packet = fopen("sslpacketwrite.out", "w+"); 755 FILE *my_ssl_packet = fopen("sslpacketwrite.out", "w+");
@@ -795,7 +807,7 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_
795 char *recv_buffer = (char*)malloc(sizeof(char) * (length * 1000)); // ensuring nothing stupid happens 807 char *recv_buffer = (char*)malloc(sizeof(char) * (length * 1000)); // ensuring nothing stupid happens
796 808
797 if (debug) printf("pre-read\nclient wants %zi bytes\n", length); 809 if (debug) printf("pre-read\nclient wants %zi bytes\n", length);
798 bytes = iphone_mux_recv(control->connection, recv_buffer, (length * 1000)); 810 iphone_mux_recv(control->connection, recv_buffer, (length * 1000), &bytes);
799 if (debug) printf("post-read\nwe got %i bytes\n", bytes); 811 if (debug) printf("post-read\nwe got %i bytes\n", bytes);
800 if (debug && bytes < 0) { 812 if (debug && bytes < 0) {
801 printf("lockdownd_securead(): uh oh\n"); 813 printf("lockdownd_securead(): uh oh\n");
@@ -839,8 +851,9 @@ iphone_error_t iphone_lckd_start_service ( iphone_lckd_client_t client, const ch
839 if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id)) return IPHONE_E_SSL_ERROR; 851 if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id)) return IPHONE_E_SSL_ERROR;
840 852
841 char *XML_query, **dictionary; 853 char *XML_query, **dictionary;
842 uint32 length, i = 0, port_loc = 0; 854 uint32 length, i = 0, port_loc = 0, bytes = 0;
843 uint8 result = 0; 855 uint8 result = 0;
856 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
844 857
845 free(host_id); 858 free(host_id);
846 host_id = NULL; 859 host_id = NULL;
@@ -855,16 +868,17 @@ iphone_error_t iphone_lckd_start_service ( iphone_lckd_client_t client, const ch
855 868
856 xmlDocDumpMemory(plist, (xmlChar **)&XML_query, &length); 869 xmlDocDumpMemory(plist, (xmlChar **)&XML_query, &length);
857 870
858 iphone_lckd_send(client, XML_query, length); 871 ret = iphone_lckd_send(client, XML_query, length, &bytes);
859 free(XML_query); 872 free(XML_query);
873 if (IPHONE_E_SUCCESS != ret) return ret;
860 874
861 length = iphone_lckd_recv(client, &XML_query); 875 ret = iphone_lckd_recv(client, &XML_query, &bytes);
862
863 xmlFreeDoc(plist); 876 xmlFreeDoc(plist);
877 if (IPHONE_E_SUCCESS != ret) return ret;
864 878
865 if (length <= 0) return IPHONE_E_NOT_ENOUGH_DATA; 879 if (bytes <= 0) return IPHONE_E_NOT_ENOUGH_DATA;
866 else { 880 else {
867 plist = xmlReadMemory(XML_query, length, NULL, NULL, 0); 881 plist = xmlReadMemory(XML_query, bytes, NULL, NULL, 0);
868 if (!plist) return IPHONE_E_UNKNOWN_ERROR; 882 if (!plist) return IPHONE_E_UNKNOWN_ERROR;
869 dict = xmlDocGetRootElement(plist); 883 dict = xmlDocGetRootElement(plist);
870 if (!dict) return IPHONE_E_UNKNOWN_ERROR; 884 if (!dict) return IPHONE_E_UNKNOWN_ERROR;
@@ -892,7 +906,7 @@ iphone_error_t iphone_lckd_start_service ( iphone_lckd_client_t client, const ch
892 906
893 if (debug) { 907 if (debug) {
894 printf("lockdownd_start_service(): DATA RECEIVED:\n\n"); 908 printf("lockdownd_start_service(): DATA RECEIVED:\n\n");
895 fwrite(XML_query, 1, length, stdout); 909 fwrite(XML_query, 1, bytes, stdout);
896 printf("end data received by lockdownd_start_service()\n"); 910 printf("end data received by lockdownd_start_service()\n");
897 } 911 }
898 912