summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/lockdown.c184
-rw-r--r--src/plist.c67
-rw-r--r--src/plist.h1
3 files changed, 155 insertions, 97 deletions
diff --git a/src/lockdown.c b/src/lockdown.c
index 1782d45..3d39fbd 100644
--- a/src/lockdown.c
+++ b/src/lockdown.c
@@ -91,7 +91,6 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone)
91 return control; 91 return control;
92} 92}
93 93
94
95/** Closes the lockdownd client and does the necessary housekeeping. 94/** Closes the lockdownd client and does the necessary housekeeping.
96 * 95 *
97 * @param control The lockdown client 96 * @param control The lockdown client
@@ -436,10 +435,9 @@ iphone_error_t iphone_lckd_new_client(iphone_device_t device, iphone_lckd_client
436iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id) 435iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, char *host_id)
437{ 436{
438 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 437 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
439 xmlDocPtr plist = new_plist(); 438 plist_t plist = NULL;
440 xmlNode *dict = NULL; 439 dict_t dict = NULL;
441 xmlNode *dictRecord = NULL; 440 dict_t dict_record = NULL;
442 char **dictionary = NULL;
443 int bytes = 0, i = 0; 441 int bytes = 0, i = 0;
444 char *XML_content = NULL; 442 char *XML_content = NULL;
445 uint32_t length = 0; 443 uint32_t length = 0;
@@ -462,24 +460,23 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
462 } 460 }
463 461
464 /* Setup Pair request plist */ 462 /* Setup Pair request plist */
465 dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 463 plist_new_plist(&plist);
466 dictRecord = add_key_dict_node(plist, dict, "PairRecord", "\n", 1); 464 plist_new_dict_in_plist(plist, &dict);
467 //dictRecord = add_child_to_plist(plist, "dict", "\n", NULL, 1); 465 plist_add_dict_element(dict, "PairRecord", PLIST_DICT, NULL);
468 add_key_data_dict_element(plist, dictRecord, "DeviceCertificate", device_cert_b64, 2); 466 dict_record = g_node_last_child(dict);
469 add_key_data_dict_element(plist, dictRecord, "HostCertificate", host_cert_b64, 2); 467 plist_add_dict_element(dict_record, "DeviceCertificate", PLIST_DATA, (void *) device_cert_b64);
470 add_key_str_dict_element(plist, dictRecord, "HostID", host_id, 2); 468 plist_add_dict_element(dict_record, "HostCertificate", PLIST_DATA, (void *) host_cert_b64);
471 add_key_data_dict_element(plist, dictRecord, "RootCertificate", root_cert_b64, 2); 469 plist_add_dict_element(dict_record, "HostID", PLIST_STRING, (void *) host_id);
472 add_key_str_dict_element(plist, dict, "Request", "Pair", 1); 470 plist_add_dict_element(dict_record, "RootCertificate", PLIST_DATA, (void *) root_cert_b64);
473 471 plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "Pair");
474 xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); 472 plist_to_xml(plist, &XML_content, &length);
475 473 log_debug_msg("XML Pairing request :\nsize : %i\nxml :\n %s", length, XML_content);
476 printf("XML Pairing request : %s\n", XML_content);
477 474
478 /* send to iPhone */ 475 /* send to iPhone */
479 ret = iphone_lckd_send(control, XML_content, length, &bytes); 476 ret = iphone_lckd_send(control, XML_content, length, &bytes);
480 477
481 xmlFree(XML_content); 478 xmlFree(XML_content);
482 xmlFreeDoc(plist); 479 plist_free(plist);
483 plist = NULL; 480 plist = NULL;
484 481
485 if (ret != IPHONE_E_SUCCESS) 482 if (ret != IPHONE_E_SUCCESS)
@@ -495,40 +492,29 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch
495 log_debug_msg(XML_content); 492 log_debug_msg(XML_content);
496 log_debug_msg("\n\n"); 493 log_debug_msg("\n\n");
497 494
498 plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); 495 xml_to_plist(XML_content, bytes, &plist);
499 if (!plist) { 496 if (!plist)
500 free(public_key_b64);
501 return IPHONE_E_PLIST_ERROR; 497 return IPHONE_E_PLIST_ERROR;
502 }
503 dict = xmlDocGetRootElement(plist);
504 for (dict = dict->children; dict; dict = dict->next) {
505 if (!xmlStrcmp(dict->name, "dict"))
506 break;
507 }
508 if (!dict) {
509 free(public_key_b64);
510 return IPHONE_E_DICT_ERROR;
511 }
512 498
513 /* Parse xml to check success and to find public key */ 499 plist_t query_node = find_query_node(plist, "Request", "Pair");
514 dictionary = read_dict_element_strings(dict); 500 plist_t result_key_node = g_node_next_sibling(query_node);
515 xmlFreeDoc(plist); 501 plist_t result_value_node = g_node_next_sibling(result_key_node);
516 free(XML_content);
517 502
518 int success = 0; 503 plist_type result_key_type;
519 for (i = 0; dictionary[i]; i += 2) { 504 plist_type result_value_type;
520 if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) { 505 char *result_key = NULL;
521 success = 1; 506 char *result_value = NULL;
522 }
523 }
524 507
525 if (dictionary) { 508 get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key));
526 free_dictionary(dictionary); 509 get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value));
527 dictionary = NULL; 510
511 if (result_key_type == PLIST_KEY &&
512 result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) {
513 ret = IPHONE_E_SUCCESS;
528 } 514 }
529 515
530 /* store public key in config if pairing succeeded */ 516 /* store public key in config if pairing succeeded */
531 if (success) { 517 if (ret == IPHONE_E_SUCCESS) {
532 log_debug_msg("lockdownd_pair_device: pair success\n"); 518 log_debug_msg("lockdownd_pair_device: pair success\n");
533 store_device_public_key(uid, public_key_b64); 519 store_device_public_key(uid, public_key_b64);
534 ret = IPHONE_E_SUCCESS; 520 ret = IPHONE_E_SUCCESS;
@@ -914,81 +900,85 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char
914 if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id)) 900 if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id))
915 return IPHONE_E_SSL_ERROR; 901 return IPHONE_E_SSL_ERROR;
916 902
917 char *XML_query, **dictionary; 903
904 plist_t plist = NULL;
905 dict_t dict = NULL;
906 char *XML_content = NULL;
918 uint32_t length, i = 0, port_loc = 0, bytes = 0; 907 uint32_t length, i = 0, port_loc = 0, bytes = 0;
919 uint8_t result = 0;
920 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; 908 iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR;
921 909
922 free(host_id); 910 free(host_id);
923 host_id = NULL; 911 host_id = NULL;
924 912
925 xmlDocPtr plist = new_plist(); 913 plist_new_plist(&plist);
926 xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); 914 plist_new_dict_in_plist(plist, &dict);
927 xmlNode *key; 915 plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "StartService");
928 key = add_key_str_dict_element(plist, dict, "Request", "StartService", 1); 916 plist_add_dict_element(dict, "Service", PLIST_STRING, (void *) service);
929 if (!key) { 917 plist_to_xml(plist, &XML_content, &length);
930 xmlFreeDoc(plist); 918
931 return IPHONE_E_UNKNOWN_ERROR; 919 /* send to iPhone */
932 } 920 log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content);
933 key = add_key_str_dict_element(plist, dict, "Service", service, 1); 921 ret = iphone_lckd_send(client, XML_content, length, &bytes);
934 if (!key) {
935 xmlFreeDoc(plist);
936 return IPHONE_E_UNKNOWN_ERROR;
937 }
938 922
939 xmlDocDumpMemory(plist, (xmlChar **) & XML_query, &length); 923 xmlFree(XML_content);
924 XML_content = NULL;
925 plist_free(plist);
926 plist = NULL;
940 927
941 ret = iphone_lckd_send(client, XML_query, length, &bytes);
942 free(XML_query);
943 if (IPHONE_E_SUCCESS != ret) 928 if (IPHONE_E_SUCCESS != ret)
944 return ret; 929 return ret;
945 930
946 ret = iphone_lckd_recv(client, &XML_query, &bytes); 931 ret = iphone_lckd_recv(client, &XML_content, &bytes);
947 xmlFreeDoc(plist); 932
948 if (IPHONE_E_SUCCESS != ret) 933 if (IPHONE_E_SUCCESS != ret)
949 return ret; 934 return ret;
950 935
936 xml_to_plist(XML_content, bytes, &plist);
937 if (!plist)
938 return IPHONE_E_PLIST_ERROR;
939
940
951 if (bytes <= 0) 941 if (bytes <= 0)
952 return IPHONE_E_NOT_ENOUGH_DATA; 942 return IPHONE_E_NOT_ENOUGH_DATA;
953 else { 943 else {
954 plist = xmlReadMemory(XML_query, bytes, NULL, NULL, 0);
955 if (!plist)
956 return IPHONE_E_UNKNOWN_ERROR;
957 dict = xmlDocGetRootElement(plist);
958 if (!dict)
959 return IPHONE_E_UNKNOWN_ERROR;
960 for (dict = dict->children; dict; dict = dict->next) {
961 if (!xmlStrcmp(dict->name, "dict"))
962 break;
963 }
964 944
965 if (!dict) 945 plist_t query_node = find_query_node(plist, "Request", "StartService");
966 return IPHONE_E_UNKNOWN_ERROR; 946 plist_t result_key_node = g_node_next_sibling(query_node);
967 dictionary = read_dict_element_strings(dict); 947 plist_t result_value_node = g_node_next_sibling(result_key_node);
968 948
969 for (i = 0; dictionary[i]; i += 2) { 949 plist_t port_key_node = find_node(plist, PLIST_KEY, "Port");
970 log_debug_msg("lockdownd_start_service() dictionary %s: %s\n", dictionary[i], dictionary[i + 1]); 950 plist_t port_value_node = g_node_next_sibling(port_key_node);
971 951
972 if (!xmlStrcmp(dictionary[i], "Port")) { 952 plist_type result_key_type;
973 port_loc = atoi(dictionary[i + 1]); 953 plist_type result_value_type;
974 log_debug_msg("lockdownd_start_service() atoi'd port: %i\n", port); 954 plist_type port_key_type;
975 } 955 plist_type port_value_type;
976 956 char *result_key = NULL;
977 if (!xmlStrcmp(dictionary[i], "Result")) { 957 char *result_value = NULL;
978 if (!xmlStrcmp(dictionary[i + 1], "Success")) { 958 char *port_key = NULL;
979 result = 1; 959 uint64_t port_value = 0;
980 } 960
981 } 961 get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key));
962 get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value));
963 get_type_and_value(port_key_node, &port_key_type, (void *) (&port_key));
964 get_type_and_value(port_value_node, &port_value_type, (void *) (&port_value));
965
966 if (result_key_type == PLIST_KEY &&
967 result_value_type == PLIST_STRING &&
968 port_key_type == PLIST_KEY &&
969 port_value_type == PLIST_UINT64 &&
970 !strcmp(result_key, "Result") && !strcmp(result_value, "Success") && !strcmp(port_key, "Port")) {
971 port_loc = port_value;
972 ret = IPHONE_E_SUCCESS;
982 } 973 }
983 974
984 log_debug_msg("lockdownd_start_service(): DATA RECEIVED:\n\n"); 975 log_debug_msg("lockdownd_start_service(): DATA RECEIVED:\n\n");
985 log_debug_msg(XML_query); 976 log_debug_msg(XML_content);
986 log_debug_msg("end data received by lockdownd_start_service()\n"); 977 log_debug_msg("end data received by lockdownd_start_service()\n");
987 978
988 free(XML_query); 979 free(XML_content);
989 xmlFreeDoc(plist); 980 plist_free(plist);
990 free_dictionary(dictionary); 981 if (port && ret == IPHONE_E_SUCCESS) {
991 if (port && result) {
992 *port = port_loc; 982 *port = port_loc;
993 return IPHONE_E_SUCCESS; 983 return IPHONE_E_SUCCESS;
994 } else 984 } else
diff --git a/src/plist.c b/src/plist.c
index 5b61570..1c00cc6 100644
--- a/src/plist.c
+++ b/src/plist.c
@@ -946,6 +946,73 @@ GNode *find_query_node(plist_t plist, char *key, char *request)
946 return NULL; 946 return NULL;
947} 947}
948 948
949char compare_node_value(plist_type type, struct plist_data *data, void *value)
950{
951 char res = FALSE;
952 switch (type) {
953 case PLIST_BOOLEAN:
954 res = data->boolval == *((char *) value) ? TRUE : FALSE;
955 break;
956 case PLIST_UINT8:
957 res = data->intval8 == *((uint8_t *) value) ? TRUE : FALSE;
958 break;
959 case PLIST_UINT16:
960 res = data->intval16 == *((uint16_t *) value) ? TRUE : FALSE;
961 break;
962 case PLIST_UINT32:
963 res = data->intval32 == *((uint32_t *) value) ? TRUE : FALSE;
964 break;
965 case PLIST_UINT64:
966 res = data->intval64 == *((uint64_t *) value) ? TRUE : FALSE;
967 break;
968 case PLIST_FLOAT32:
969 res = data->realval32 == *((float *) value) ? TRUE : FALSE;
970 break;
971 case PLIST_FLOAT64:
972 res = data->realval64 == *((double *) value) ? TRUE : FALSE;
973 break;
974 case PLIST_KEY:
975 case PLIST_STRING:
976 res = !strcmp(data->strval, ((char *) value));
977 break;
978 case PLIST_UNICODE:
979 res = !wcscmp(data->unicodeval, ((wchar_t *) value));
980 break;
981 case PLIST_DATA:
982 res = !strcmp(data->buff, ((char *) value));
983 break;
984 case PLIST_ARRAY:
985 case PLIST_DICT:
986 case PLIST_DATE:
987 case PLIST_PLIST:
988 default:
989 break;
990 }
991 return res;
992}
993
994GNode *find_node(plist_t plist, plist_type type, void *value)
995{
996 if (!plist)
997 return NULL;
998
999 GNode *current = NULL;
1000 for (current = plist->children; current; current = current->next) {
1001
1002 struct plist_data *data = (struct plist_data *) current->data;
1003
1004 if (data->type == type && compare_node_value(type, data, value)) {
1005 return current;
1006 }
1007 if (data->type == PLIST_DICT || data->type == PLIST_ARRAY || data->type == PLIST_PLIST) {
1008 GNode *sub = find_node(current, type, value);
1009 if (sub)
1010 return sub;
1011 }
1012 }
1013 return NULL;
1014}
1015
949void get_type_and_value(GNode * node, plist_type * type, void *value) 1016void get_type_and_value(GNode * node, plist_type * type, void *value)
950{ 1017{
951 if (!node) 1018 if (!node)
diff --git a/src/plist.h b/src/plist.h
index ffc00e4..34e3934 100644
--- a/src/plist.h
+++ b/src/plist.h
@@ -84,5 +84,6 @@ void xml_to_plist(const char *plist_xml, uint32_t length, plist_t * plist);
84void bin_to_plist(const char *plist_bin, uint32_t length, plist_t * plist); 84void bin_to_plist(const char *plist_bin, uint32_t length, plist_t * plist);
85 85
86GNode *find_query_node(plist_t plist, char *key, char *request); 86GNode *find_query_node(plist_t plist, char *key, char *request);
87GNode *find_node(plist_t plist, plist_type type, void *value);
87void get_type_and_value(GNode * node, plist_type * type, void *value); 88void get_type_and_value(GNode * node, plist_type * type, void *value);
88#endif 89#endif