diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lockdown.c | 62 | ||||
| -rw-r--r-- | src/plist.c | 141 | ||||
| -rw-r--r-- | src/plist.h | 12 |
3 files changed, 166 insertions, 49 deletions
diff --git a/src/lockdown.c b/src/lockdown.c index 6b8f298..2906fdf 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -201,49 +201,57 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control) | |||
| 201 | { | 201 | { |
| 202 | if (!control) | 202 | if (!control) |
| 203 | return IPHONE_E_INVALID_ARG; | 203 | return IPHONE_E_INVALID_ARG; |
| 204 | xmlDocPtr plist = new_plist(); | 204 | |
| 205 | xmlNode *dict, *key; | ||
| 206 | char **dictionary; | ||
| 207 | int bytes = 0, i = 0; | 205 | int bytes = 0, i = 0; |
| 208 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 206 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 209 | 207 | ||
| 208 | plist_t plist = NULL; | ||
| 209 | plist_new_plist(&plist); | ||
| 210 | |||
| 211 | dict_t dict = NULL; | ||
| 212 | plist_new_dict_in_plist(plist, &dict); | ||
| 213 | |||
| 214 | plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "QueryType"); | ||
| 215 | |||
| 210 | log_debug_msg("lockdownd_hello() called\n"); | 216 | log_debug_msg("lockdownd_hello() called\n"); |
| 211 | dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); | 217 | char *XML_content = NULL; |
| 212 | key = add_key_str_dict_element(plist, dict, "Request", "QueryType", 1); | 218 | uint32_t length = 0; |
| 213 | char *XML_content; | ||
| 214 | uint32_t length; | ||
| 215 | 219 | ||
| 216 | xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); | 220 | plist_to_xml(plist, &XML_content, &length); |
| 221 | log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); | ||
| 217 | ret = iphone_lckd_send(control, XML_content, length, &bytes); | 222 | ret = iphone_lckd_send(control, XML_content, length, &bytes); |
| 218 | 223 | ||
| 219 | xmlFree(XML_content); | 224 | xmlFree(XML_content); |
| 220 | xmlFreeDoc(plist); | 225 | XML_content = NULL; |
| 226 | plist_free(plist); | ||
| 221 | plist = NULL; | 227 | plist = NULL; |
| 228 | |||
| 222 | ret = iphone_lckd_recv(control, &XML_content, &bytes); | 229 | ret = iphone_lckd_recv(control, &XML_content, &bytes); |
| 230 | log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); | ||
| 231 | xml_to_plist(XML_content, bytes, &plist); | ||
| 223 | 232 | ||
| 224 | plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); | ||
| 225 | if (!plist) | 233 | if (!plist) |
| 226 | return IPHONE_E_PLIST_ERROR; | 234 | return IPHONE_E_PLIST_ERROR; |
| 227 | dict = xmlDocGetRootElement(plist); | ||
| 228 | for (dict = dict->children; dict; dict = dict->next) { | ||
| 229 | if (!xmlStrcmp(dict->name, "dict")) | ||
| 230 | break; | ||
| 231 | } | ||
| 232 | if (!dict) | ||
| 233 | return IPHONE_E_DICT_ERROR; | ||
| 234 | dictionary = read_dict_element_strings(dict); | ||
| 235 | xmlFreeDoc(plist); | ||
| 236 | free(XML_content); | ||
| 237 | 235 | ||
| 238 | for (i = 0; dictionary[i]; i += 2) { | 236 | plist_t query_node = find_query_node(plist, "Request", "QueryType"); |
| 239 | if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) { | 237 | plist_t result_node = g_node_next_sibling(query_node); |
| 240 | log_debug_msg("lockdownd_hello(): success\n"); | 238 | plist_t value_node = g_node_next_sibling(result_node); |
| 241 | ret = IPHONE_E_SUCCESS; | 239 | |
| 242 | break; | 240 | plist_type result_type; |
| 243 | } | 241 | plist_type value_type; |
| 242 | |||
| 243 | char *result_value = NULL; | ||
| 244 | char *value_value = NULL; | ||
| 245 | |||
| 246 | get_type_and_value(result_node, &result_type, (void *) (&result_value)); | ||
| 247 | get_type_and_value(value_node, &value_type, (void *) (&value_value)); | ||
| 248 | |||
| 249 | if (result_type == PLIST_KEY && | ||
| 250 | value_type == PLIST_STRING && !strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { | ||
| 251 | log_debug_msg("lockdownd_hello(): success\n"); | ||
| 252 | ret = IPHONE_E_SUCCESS; | ||
| 244 | } | 253 | } |
| 245 | 254 | ||
| 246 | free_dictionary(dictionary); | ||
| 247 | return ret; | 255 | return ret; |
| 248 | } | 256 | } |
| 249 | 257 | ||
diff --git a/src/plist.c b/src/plist.c index 377646d..5b61570 100644 --- a/src/plist.c +++ b/src/plist.c | |||
| @@ -286,8 +286,6 @@ void byte_convert(char *address, size_t size) | |||
| 286 | } | 286 | } |
| 287 | } | 287 | } |
| 288 | 288 | ||
| 289 | |||
| 290 | |||
| 291 | void print_bytes(char *val, size_t size) | 289 | void print_bytes(char *val, size_t size) |
| 292 | { | 290 | { |
| 293 | int i = 0; | 291 | int i = 0; |
| @@ -421,11 +419,17 @@ void plist_free(plist_t plist) | |||
| 421 | g_node_destroy(plist); | 419 | g_node_destroy(plist); |
| 422 | } | 420 | } |
| 423 | 421 | ||
| 424 | void node_to_xml(GNode * node, gpointer data) | 422 | struct xml_node { |
| 423 | xmlNodePtr xml; | ||
| 424 | uint32_t depth; | ||
| 425 | }; | ||
| 426 | |||
| 427 | void node_to_xml(GNode * node, gpointer xml_struct) | ||
| 425 | { | 428 | { |
| 426 | if (!node) | 429 | if (!node) |
| 427 | return; | 430 | return; |
| 428 | 431 | ||
| 432 | struct xml_node *xstruct = (struct xml_node *) xml_struct; | ||
| 429 | struct plist_data *node_data = (struct plist_data *) node->data; | 433 | struct plist_data *node_data = (struct plist_data *) node->data; |
| 430 | 434 | ||
| 431 | xmlNodePtr child_node = NULL; | 435 | xmlNodePtr child_node = NULL; |
| @@ -510,12 +514,31 @@ void node_to_xml(GNode * node, gpointer data) | |||
| 510 | break; | 514 | break; |
| 511 | } | 515 | } |
| 512 | 516 | ||
| 513 | child_node = xmlNewChild(data, NULL, tag, val); | 517 | int i = 0; |
| 514 | xmlNodeAddContent(child_node, "\n"); | 518 | for (i = 0; i < xstruct->depth; i++) { |
| 519 | xmlNodeAddContent(xstruct->xml, "\t"); | ||
| 520 | } | ||
| 521 | child_node = xmlNewChild(xstruct->xml, NULL, tag, val); | ||
| 522 | xmlNodeAddContent(xstruct->xml, "\n"); | ||
| 515 | g_free(val); | 523 | g_free(val); |
| 516 | 524 | ||
| 517 | if (isStruct) | 525 | //add return for structured types |
| 518 | g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, child_node); | 526 | if (node_data->type == PLIST_ARRAY || |
| 527 | node_data->type == PLIST_DICT || node_data->type == PLIST_DATA || node_data->type == PLIST_PLIST) | ||
| 528 | xmlNodeAddContent(child_node, "\n"); | ||
| 529 | |||
| 530 | if (isStruct) { | ||
| 531 | struct xml_node child = { child_node, xstruct->depth + 1 }; | ||
| 532 | g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, &child); | ||
| 533 | } | ||
| 534 | //fix indent for structured types | ||
| 535 | if (node_data->type == PLIST_ARRAY || | ||
| 536 | node_data->type == PLIST_DICT || node_data->type == PLIST_DATA || node_data->type == PLIST_PLIST) { | ||
| 537 | |||
| 538 | for (i = 0; i < xstruct->depth; i++) { | ||
| 539 | xmlNodeAddContent(child_node, "\t"); | ||
| 540 | } | ||
| 541 | } | ||
| 519 | 542 | ||
| 520 | return; | 543 | return; |
| 521 | } | 544 | } |
| @@ -523,12 +546,18 @@ void node_to_xml(GNode * node, gpointer data) | |||
| 523 | void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) | 546 | void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) |
| 524 | { | 547 | { |
| 525 | xmlNodePtr node = NULL; | 548 | xmlNodePtr node = NULL; |
| 526 | struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); | ||
| 527 | GNode *subnode = g_node_new(data); | ||
| 528 | g_node_append(plist_node, subnode); | ||
| 529 | 549 | ||
| 530 | for (node = xml_node->children; node; node = node->next) { | 550 | for (node = xml_node->children; node; node = node->next) { |
| 531 | 551 | ||
| 552 | while (node && !xmlStrcmp(node->name, "text")) | ||
| 553 | node = node->next; | ||
| 554 | if (!node) | ||
| 555 | break; | ||
| 556 | |||
| 557 | struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); | ||
| 558 | GNode *subnode = g_node_new(data); | ||
| 559 | g_node_append(plist_node, subnode); | ||
| 560 | |||
| 532 | if (!xmlStrcmp(node->name, "true")) { | 561 | if (!xmlStrcmp(node->name, "true")) { |
| 533 | data->boolval = 1; | 562 | data->boolval = 1; |
| 534 | data->type = PLIST_BOOLEAN; | 563 | data->type = PLIST_BOOLEAN; |
| @@ -590,15 +619,15 @@ void xml_to_node(xmlNodePtr xml_node, GNode * plist_node) | |||
| 590 | } | 619 | } |
| 591 | } | 620 | } |
| 592 | 621 | ||
| 593 | void plist_to_xml(plist_t plist, char **plist_xml) | 622 | void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length) |
| 594 | { | 623 | { |
| 595 | if (!plist || !plist_xml || *plist_xml) | 624 | if (!plist || !plist_xml || *plist_xml) |
| 596 | return; | 625 | return; |
| 597 | xmlDocPtr plist_doc = new_plist(); | 626 | xmlDocPtr plist_doc = new_plist(); |
| 598 | xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); | 627 | xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); |
| 599 | g_node_children_foreach(plist, G_TRAVERSE_ALL, node_to_xml, root_node); | 628 | struct xml_node root = { root_node, 0 }; |
| 600 | int size = 0; | 629 | g_node_children_foreach(plist, G_TRAVERSE_ALL, node_to_xml, &root); |
| 601 | xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, &size); | 630 | xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, length); |
| 602 | } | 631 | } |
| 603 | 632 | ||
| 604 | GNode *parse_raw_node(const char *bpbuffer, uint32_t bplength, uint32_t * position, uint8_t ref_size) | 633 | GNode *parse_raw_node(const char *bpbuffer, uint32_t bplength, uint32_t * position, uint8_t ref_size) |
| @@ -869,13 +898,13 @@ plist_t parse_nodes(const char *bpbuffer, uint32_t bplength, uint32_t * position | |||
| 869 | return root_node; | 898 | return root_node; |
| 870 | } | 899 | } |
| 871 | 900 | ||
| 872 | void plist_to_bin(plist_t plist, char **plist_bin, int *length) | 901 | void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length) |
| 873 | { | 902 | { |
| 874 | } | 903 | } |
| 875 | 904 | ||
| 876 | void xml_to_plist(const char *plist_xml, plist_t * plist) | 905 | void xml_to_plist(const char *plist_xml, uint32_t length, plist_t * plist) |
| 877 | { | 906 | { |
| 878 | xmlDocPtr plist_doc = xmlReadMemory(plist_xml, strlen(plist_xml), NULL, NULL, 0); | 907 | xmlDocPtr plist_doc = xmlReadMemory(plist_xml, length, NULL, NULL, 0); |
| 879 | xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); | 908 | xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); |
| 880 | 909 | ||
| 881 | struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); | 910 | struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); |
| @@ -885,8 +914,84 @@ void xml_to_plist(const char *plist_xml, plist_t * plist) | |||
| 885 | 914 | ||
| 886 | } | 915 | } |
| 887 | 916 | ||
| 888 | void bin_to_plist(const char *plist_bin, int length, plist_t * plist) | 917 | void bin_to_plist(const char *plist_bin, uint32_t length, plist_t * plist) |
| 889 | { | 918 | { |
| 890 | uint32_t pos = 0; | 919 | uint32_t pos = 0; |
| 891 | *plist = parse_nodes(plist_bin, length, &pos); | 920 | *plist = parse_nodes(plist_bin, length, &pos); |
| 892 | } | 921 | } |
| 922 | |||
| 923 | |||
| 924 | GNode *find_query_node(plist_t plist, char *key, char *request) | ||
| 925 | { | ||
| 926 | if (!plist) | ||
| 927 | return NULL; | ||
| 928 | |||
| 929 | GNode *current = NULL; | ||
| 930 | for (current = plist->children; current; current = current->next) { | ||
| 931 | |||
| 932 | struct plist_data *data = (struct plist_data *) current->data; | ||
| 933 | |||
| 934 | if (data->type == PLIST_KEY && !strcmp(data->strval, key) && current->next) { | ||
| 935 | |||
| 936 | data = (struct plist_data *) current->next->data; | ||
| 937 | if (data->type == PLIST_STRING && !strcmp(data->strval, request)) | ||
| 938 | return current->next; | ||
| 939 | } | ||
| 940 | if (data->type == PLIST_DICT || data->type == PLIST_ARRAY || data->type == PLIST_PLIST) { | ||
| 941 | GNode *sub = find_query_node(current, key, request); | ||
| 942 | if (sub) | ||
| 943 | return sub; | ||
| 944 | } | ||
| 945 | } | ||
| 946 | return NULL; | ||
| 947 | } | ||
| 948 | |||
| 949 | void get_type_and_value(GNode * node, plist_type * type, void *value) | ||
| 950 | { | ||
| 951 | if (!node) | ||
| 952 | return; | ||
| 953 | |||
| 954 | struct plist_data *data = (struct plist_data *) node->data; | ||
| 955 | |||
| 956 | *type = data->type; | ||
| 957 | |||
| 958 | switch (*type) { | ||
| 959 | case PLIST_BOOLEAN: | ||
| 960 | *((char *) value) = data->boolval; | ||
| 961 | break; | ||
| 962 | case PLIST_UINT8: | ||
| 963 | *((uint8_t *) value) = data->intval8; | ||
| 964 | break; | ||
| 965 | case PLIST_UINT16: | ||
| 966 | *((uint16_t *) value) = data->intval16; | ||
| 967 | break; | ||
| 968 | case PLIST_UINT32: | ||
| 969 | *((uint32_t *) value) = data->intval32; | ||
| 970 | break; | ||
| 971 | case PLIST_UINT64: | ||
| 972 | *((uint64_t *) value) = data->intval64; | ||
| 973 | break; | ||
| 974 | case PLIST_FLOAT32: | ||
| 975 | *((float *) value) = data->realval32; | ||
| 976 | break; | ||
| 977 | case PLIST_FLOAT64: | ||
| 978 | *((double *) value) = data->realval64; | ||
| 979 | break; | ||
| 980 | case PLIST_STRING: | ||
| 981 | *((char **) value) = strdup(data->strval); | ||
| 982 | break; | ||
| 983 | case PLIST_UNICODE: | ||
| 984 | *((wchar_t **) value) = wcsdup(data->unicodeval); | ||
| 985 | break; | ||
| 986 | case PLIST_KEY: | ||
| 987 | *((char **) value) = strdup(data->strval); | ||
| 988 | break; | ||
| 989 | case PLIST_DATA: | ||
| 990 | case PLIST_ARRAY: | ||
| 991 | case PLIST_DICT: | ||
| 992 | case PLIST_DATE: | ||
| 993 | case PLIST_PLIST: | ||
| 994 | default: | ||
| 995 | break; | ||
| 996 | } | ||
| 997 | } | ||
diff --git a/src/plist.h b/src/plist.h index 1ca55f9..ffc00e4 100644 --- a/src/plist.h +++ b/src/plist.h | |||
| @@ -70,15 +70,19 @@ typedef GNode *plist_t; | |||
| 70 | typedef GNode *dict_t; | 70 | typedef GNode *dict_t; |
| 71 | typedef GNode *array_t; | 71 | typedef GNode *array_t; |
| 72 | 72 | ||
| 73 | |||
| 73 | void plist_new_plist(plist_t * plist); | 74 | void plist_new_plist(plist_t * plist); |
| 74 | void plist_new_dict_in_plist(plist_t plist, dict_t * dict); | 75 | void plist_new_dict_in_plist(plist_t plist, dict_t * dict); |
| 75 | void plist_new_array_in_plist(plist_t plist, int length, plist_type type, void **values, array_t * array); | 76 | void plist_new_array_in_plist(plist_t plist, int length, plist_type type, void **values, array_t * array); |
| 76 | void plist_add_dict_element(dict_t dict, char *key, plist_type type, void *value); | 77 | void plist_add_dict_element(dict_t dict, char *key, plist_type type, void *value); |
| 77 | void plist_free(plist_t plist); | 78 | void plist_free(plist_t plist); |
| 78 | 79 | ||
| 79 | void plist_to_xml(plist_t plist, char **plist_xml); | 80 | void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); |
| 80 | void plist_to_bin(plist_t plist, char **plist_bin, int *length); | 81 | void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length); |
| 82 | |||
| 83 | void xml_to_plist(const char *plist_xml, uint32_t length, plist_t * plist); | ||
| 84 | void bin_to_plist(const char *plist_bin, uint32_t length, plist_t * plist); | ||
| 81 | 85 | ||
| 82 | void xml_to_plist(const char *plist_xml, plist_t * plist); | 86 | GNode *find_query_node(plist_t plist, char *key, char *request); |
| 83 | void bin_to_plist(const char *plist_bin, int length, plist_t * plist); | 87 | void get_type_and_value(GNode * node, plist_type * type, void *value); |
| 84 | #endif | 88 | #endif |
