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)  {  	if (!control)  		return IPHONE_E_INVALID_ARG; -	xmlDocPtr plist = new_plist(); -	xmlNode *dict, *key; -	char **dictionary; +  	int bytes = 0, i = 0;  	iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; +	plist_t plist = NULL; +	plist_new_plist(&plist); + +	dict_t dict = NULL; +	plist_new_dict_in_plist(plist, &dict); + +	plist_add_dict_element(dict, "Request", PLIST_STRING, (void *) "QueryType"); +  	log_debug_msg("lockdownd_hello() called\n"); -	dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); -	key = add_key_str_dict_element(plist, dict, "Request", "QueryType", 1); -	char *XML_content; -	uint32_t length; +	char *XML_content = NULL; +	uint32_t length = 0; -	xmlDocDumpMemory(plist, (xmlChar **) & XML_content, &length); +	plist_to_xml(plist, &XML_content, &length); +	log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content);  	ret = iphone_lckd_send(control, XML_content, length, &bytes);  	xmlFree(XML_content); -	xmlFreeDoc(plist); +	XML_content = NULL; +	plist_free(plist);  	plist = NULL; +  	ret = iphone_lckd_recv(control, &XML_content, &bytes); +	log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); +	xml_to_plist(XML_content, bytes, &plist); -	plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0);  	if (!plist)  		return IPHONE_E_PLIST_ERROR; -	dict = xmlDocGetRootElement(plist); -	for (dict = dict->children; dict; dict = dict->next) { -		if (!xmlStrcmp(dict->name, "dict")) -			break; -	} -	if (!dict) -		return IPHONE_E_DICT_ERROR; -	dictionary = read_dict_element_strings(dict); -	xmlFreeDoc(plist); -	free(XML_content); -	for (i = 0; dictionary[i]; i += 2) { -		if (!strcmp(dictionary[i], "Result") && !strcmp(dictionary[i + 1], "Success")) { -			log_debug_msg("lockdownd_hello(): success\n"); -			ret = IPHONE_E_SUCCESS; -			break; -		} +	plist_t query_node = find_query_node(plist, "Request", "QueryType"); +	plist_t result_node = g_node_next_sibling(query_node); +	plist_t value_node = g_node_next_sibling(result_node); + +	plist_type result_type; +	plist_type value_type; + +	char *result_value = NULL; +	char *value_value = NULL; + +	get_type_and_value(result_node, &result_type, (void *) (&result_value)); +	get_type_and_value(value_node, &value_type, (void *) (&value_value)); + +	if (result_type == PLIST_KEY && +		value_type == PLIST_STRING && !strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { +		log_debug_msg("lockdownd_hello(): success\n"); +		ret = IPHONE_E_SUCCESS;  	} -	free_dictionary(dictionary);  	return ret;  } 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)  	}  } - -  void print_bytes(char *val, size_t size)  {  	int i = 0; @@ -421,11 +419,17 @@ void plist_free(plist_t plist)  	g_node_destroy(plist);  } -void node_to_xml(GNode * node, gpointer data) +struct xml_node { +	xmlNodePtr xml; +	uint32_t depth; +}; + +void node_to_xml(GNode * node, gpointer xml_struct)  {  	if (!node)  		return; +	struct xml_node *xstruct = (struct xml_node *) xml_struct;  	struct plist_data *node_data = (struct plist_data *) node->data;  	xmlNodePtr child_node = NULL; @@ -510,12 +514,31 @@ void node_to_xml(GNode * node, gpointer data)  		break;  	} -	child_node = xmlNewChild(data, NULL, tag, val); -	xmlNodeAddContent(child_node, "\n"); +	int i = 0; +	for (i = 0; i < xstruct->depth; i++) { +		xmlNodeAddContent(xstruct->xml, "\t"); +	} +	child_node = xmlNewChild(xstruct->xml, NULL, tag, val); +	xmlNodeAddContent(xstruct->xml, "\n");  	g_free(val); -	if (isStruct) -		g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, child_node); +	//add return for structured types +	if (node_data->type == PLIST_ARRAY || +		node_data->type == PLIST_DICT || node_data->type == PLIST_DATA || node_data->type == PLIST_PLIST) +		xmlNodeAddContent(child_node, "\n"); + +	if (isStruct) { +		struct xml_node child = { child_node, xstruct->depth + 1 }; +		g_node_children_foreach(node, G_TRAVERSE_ALL, node_to_xml, &child); +	} +	//fix indent for structured types +	if (node_data->type == PLIST_ARRAY || +		node_data->type == PLIST_DICT || node_data->type == PLIST_DATA || node_data->type == PLIST_PLIST) { + +		for (i = 0; i < xstruct->depth; i++) { +			xmlNodeAddContent(child_node, "\t"); +		} +	}  	return;  } @@ -523,12 +546,18 @@ void node_to_xml(GNode * node, gpointer data)  void xml_to_node(xmlNodePtr xml_node, GNode * plist_node)  {  	xmlNodePtr node = NULL; -	struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); -	GNode *subnode = g_node_new(data); -	g_node_append(plist_node, subnode);  	for (node = xml_node->children; node; node = node->next) { +		while (node && !xmlStrcmp(node->name, "text")) +			node = node->next; +		if (!node) +			break; + +		struct plist_data *data = (struct plist_data *) calloc(sizeof(struct plist_data), 1); +		GNode *subnode = g_node_new(data); +		g_node_append(plist_node, subnode); +  		if (!xmlStrcmp(node->name, "true")) {  			data->boolval = 1;  			data->type = PLIST_BOOLEAN; @@ -590,15 +619,15 @@ void xml_to_node(xmlNodePtr xml_node, GNode * plist_node)  	}  } -void plist_to_xml(plist_t plist, char **plist_xml) +void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length)  {  	if (!plist || !plist_xml || *plist_xml)  		return;  	xmlDocPtr plist_doc = new_plist();  	xmlNodePtr root_node = xmlDocGetRootElement(plist_doc); -	g_node_children_foreach(plist, G_TRAVERSE_ALL, node_to_xml, root_node); -	int size = 0; -	xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, &size); +	struct xml_node root = { root_node, 0 }; +	g_node_children_foreach(plist, G_TRAVERSE_ALL, node_to_xml, &root); +	xmlDocDumpMemory(plist_doc, (xmlChar **) plist_xml, length);  }  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  	return root_node;  } -void plist_to_bin(plist_t plist, char **plist_bin, int *length) +void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length)  {  } -void xml_to_plist(const char *plist_xml, plist_t * plist) +void xml_to_plist(const char *plist_xml, uint32_t length, plist_t * plist)  { -	xmlDocPtr plist_doc = xmlReadMemory(plist_xml, strlen(plist_xml), NULL, NULL, 0); +	xmlDocPtr plist_doc = xmlReadMemory(plist_xml, length, NULL, NULL, 0);  	xmlNodePtr root_node = xmlDocGetRootElement(plist_doc);  	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)  } -void bin_to_plist(const char *plist_bin, int length, plist_t * plist) +void bin_to_plist(const char *plist_bin, uint32_t length, plist_t * plist)  {  	uint32_t pos = 0;  	*plist = parse_nodes(plist_bin, length, &pos);  } + + +GNode *find_query_node(plist_t plist, char *key, char *request) +{ +	if (!plist) +		return NULL; + +	GNode *current = NULL; +	for (current = plist->children; current; current = current->next) { + +		struct plist_data *data = (struct plist_data *) current->data; + +		if (data->type == PLIST_KEY && !strcmp(data->strval, key) && current->next) { + +			data = (struct plist_data *) current->next->data; +			if (data->type == PLIST_STRING && !strcmp(data->strval, request)) +				return current->next; +		} +		if (data->type == PLIST_DICT || data->type == PLIST_ARRAY || data->type == PLIST_PLIST) { +			GNode *sub = find_query_node(current, key, request); +			if (sub) +				return sub; +		} +	} +	return NULL; +} + +void get_type_and_value(GNode * node, plist_type * type, void *value) +{ +	if (!node) +		return; + +	struct plist_data *data = (struct plist_data *) node->data; + +	*type = data->type; + +	switch (*type) { +	case PLIST_BOOLEAN: +		*((char *) value) = data->boolval; +		break; +	case PLIST_UINT8: +		*((uint8_t *) value) = data->intval8; +		break; +	case PLIST_UINT16: +		*((uint16_t *) value) = data->intval16; +		break; +	case PLIST_UINT32: +		*((uint32_t *) value) = data->intval32; +		break; +	case PLIST_UINT64: +		*((uint64_t *) value) = data->intval64; +		break; +	case PLIST_FLOAT32: +		*((float *) value) = data->realval32; +		break; +	case PLIST_FLOAT64: +		*((double *) value) = data->realval64; +		break; +	case PLIST_STRING: +		*((char **) value) = strdup(data->strval); +		break; +	case PLIST_UNICODE: +		*((wchar_t **) value) = wcsdup(data->unicodeval); +		break; +	case PLIST_KEY: +		*((char **) value) = strdup(data->strval); +		break; +	case PLIST_DATA: +	case PLIST_ARRAY: +	case PLIST_DICT: +	case PLIST_DATE: +	case PLIST_PLIST: +	default: +		break; +	} +} 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;  typedef GNode *dict_t;  typedef GNode *array_t; +  void plist_new_plist(plist_t * plist);  void plist_new_dict_in_plist(plist_t plist, dict_t * dict);  void plist_new_array_in_plist(plist_t plist, int length, plist_type type, void **values, array_t * array);  void plist_add_dict_element(dict_t dict, char *key, plist_type type, void *value);  void plist_free(plist_t plist); -void plist_to_xml(plist_t plist, char **plist_xml); -void plist_to_bin(plist_t plist, char **plist_bin, int *length); +void plist_to_xml(plist_t plist, char **plist_xml, uint32_t * length); +void plist_to_bin(plist_t plist, char **plist_bin, uint32_t * length); + +void xml_to_plist(const char *plist_xml, uint32_t length, plist_t * plist); +void bin_to_plist(const char *plist_bin, uint32_t length, plist_t * plist); -void xml_to_plist(const char *plist_xml, plist_t * plist); -void bin_to_plist(const char *plist_bin, int length, plist_t * plist); +GNode *find_query_node(plist_t plist, char *key, char *request); +void get_type_and_value(GNode * node, plist_type * type, void *value);  #endif | 
