diff options
-rw-r--r-- | dev/main.c | 3 | ||||
-rw-r--r-- | include/libiphone/libiphone.h | 5 | ||||
-rw-r--r-- | src/lockdown.c | 617 | ||||
-rw-r--r-- | src/utils.h | 2 |
4 files changed, 295 insertions, 332 deletions
@@ -28,6 +28,7 @@ #include <libxml/tree.h> #include <libiphone/libiphone.h> +#include "../src/utils.h" int main(int argc, char *argv[]) @@ -38,8 +39,10 @@ int main(int argc, char *argv[]) if (argc > 1 && !strcasecmp(argv[1], "--debug")) { iphone_set_debug(1); + iphone_set_debug_mask(DBGMASK_ALL); } else { iphone_set_debug(0); + iphone_set_debug_mask(DBGMASK_NONE); } 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" { #include <stdint.h> #include <sys/types.h> #include <sys/stat.h> +#include <plist/plist.h> //general errors #define IPHONE_E_SUCCESS 0 @@ -88,8 +89,8 @@ iphone_error_t iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_clie iphone_error_t iphone_lckd_free_client( iphone_lckd_client_t client ); iphone_error_t iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service, int *port ); -iphone_error_t iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data, uint32_t *recv_bytes ); -iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t length, uint32_t *recv_bytes ); +iphone_error_t iphone_lckd_recv ( iphone_lckd_client_t client, plist_t* plist); +iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, plist_t plist); //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 @@ #include <plist/plist.h> + const ASN1_ARRAY_TYPE pkcs1_asn1_tab[] = { {"PKCS1", 536872976, 0}, {0, 1073741836, 0}, @@ -80,53 +81,49 @@ static void iphone_lckd_stop_session(iphone_lckd_client_t control) iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; plist_t dict = plist_new_dict(); - plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); - plist_add_sub_element(dict, PLIST_STRING, (void *) "StopSession", strlen("StopSession")); - plist_add_sub_element(dict, PLIST_KEY, (void *) "SessionID", strlen("SessionID")); - plist_add_sub_element(dict, PLIST_STRING, (void *) control->session_id, strlen(control->session_id)); + plist_add_sub_key_el(dict, "Request"); + plist_add_sub_string_el(dict, "StopSession"); + plist_add_sub_key_el(dict, "SessionID"); + plist_add_sub_string_el(dict, control->session_id); - log_debug_msg("iphone_lckd_stop_session() called\n"); - char *XML_content = NULL; - uint32_t length = 0; + log_dbg_msg(DBGMASK_LOCKDOWND, "iphone_lckd_stop_session() called\n"); - plist_to_xml(dict, &XML_content, &length); - log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); - ret = iphone_lckd_send(control, XML_content, length, &bytes); + ret = iphone_lckd_send(control, dict); - free(XML_content); - XML_content = NULL; plist_free(dict); dict = NULL; - ret = iphone_lckd_recv(control, &XML_content, &bytes); - log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); - plist_from_xml(XML_content, bytes, &dict); + ret = iphone_lckd_recv(control, &dict); if (!dict) { - log_debug_msg("lockdownd_stop_session(): IPHONE_E_PLIST_ERROR\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_stop_session(): IPHONE_E_PLIST_ERROR\n"); return; // IPHONE_E_PLIST_ERROR; } - plist_t query_node = plist_find_node(dict, PLIST_STRING, "StopSession", strlen("StopSession")); + plist_t query_node = plist_find_node_by_string(dict, "StopSession"); plist_t result_node = plist_get_next_sibling(query_node); plist_t value_node = plist_get_next_sibling(result_node); - plist_type result_type; - plist_type value_type; + plist_type result_type = plist_get_node_type(result_node); + plist_type value_type = plist_get_node_type(value_node); + + if (result_type == PLIST_KEY && value_type == PLIST_STRING) { - char *result_value = NULL; - char *value_value = NULL; - uint64_t result_length = 0; - uint64_t value_length = 0; + char *result_value = NULL; + char *value_value = NULL; - plist_get_type_and_value(result_node, &result_type, (void *) (&result_value), &result_length); - plist_get_type_and_value(value_node, &value_type, (void *) (&value_value), &value_length); + plist_get_key_val(result_node, &result_value); + plist_get_string_val(value_node, &value_value); - if (result_type == PLIST_KEY && - value_type == PLIST_STRING && !strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { - log_debug_msg("lockdownd_stop_session(): success\n"); - ret = IPHONE_E_SUCCESS; + if (!strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_stop_session(): success\n"); + ret = IPHONE_E_SUCCESS; + } + free(result_value); + free(value_value); } + plist_free(dict); + dict = NULL; return; // ret; } @@ -142,14 +139,14 @@ static void iphone_lckd_stop_session(iphone_lckd_client_t control) static void iphone_lckd_stop_SSL_session(iphone_lckd_client_t client) { if (!client) { - log_debug_msg("lockdownd_stop_SSL_session(): invalid argument!\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_stop_SSL_session(): invalid argument!\n"); return; } if (client->in_SSL) { - log_debug_msg("Stopping SSL Session\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "Stopping SSL Session\n"); iphone_lckd_stop_session(client); - log_debug_msg("Sending SSL close notify\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "Sending SSL close notify\n"); gnutls_bye(*client->ssl_session, GNUTLS_SHUT_RDWR); } if (client->ssl_session) { @@ -196,9 +193,9 @@ iphone_error_t iphone_lckd_free_client(iphone_lckd_client_t client) * * @return The number of bytes received */ -iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, char **dump_data, uint32_t * recv_bytes) +iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, plist_t * plist) { - if (!client || !dump_data || !recv_bytes) + if (!client || !plist || (plist && *plist)) return IPHONE_E_INVALID_ARG; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; char *receive; @@ -221,8 +218,18 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, char **dump_data, u if (bytes > 0) ret = IPHONE_E_SUCCESS; } - *dump_data = receive; - *recv_bytes = bytes; + + if (bytes <= 0) { + free(receive); + return IPHONE_E_NOT_ENOUGH_DATA; + } + + plist_from_xml(receive, bytes, plist); + free(receive); + + if (!*plist) + ret = IPHONE_E_PLIST_ERROR; + return ret; } @@ -231,26 +238,31 @@ iphone_error_t iphone_lckd_recv(iphone_lckd_client_t client, char **dump_data, u * @note This function is low-level and should only be used if you need to send * a new type of message. * - * @param control The lockdownd client - * @param raw_data The null terminated string buffer to send - * @param length The length of data to send + * @param client The lockdownd client + * @param plist The plist to send * - * @return The number of bytes sent + * @return an error code (IPHONE_E_SUCCESS on success) */ -iphone_error_t iphone_lckd_send(iphone_lckd_client_t client, char *raw_data, uint32_t length, uint32_t * sent_bytes) +iphone_error_t iphone_lckd_send(iphone_lckd_client_t client, plist_t plist) { - if (!client || !raw_data || length == 0 || !sent_bytes) + if (!client || !plist) return IPHONE_E_INVALID_ARG; char *real_query; int bytes; + char *XMLContent = NULL; + uint32_t length = 0; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; + plist_to_xml(plist, &XMLContent, &length); + log_dbg_msg(DBGMASK_LOCKDOWND, "Send msg :\nsize : %i\nbuffer :\n%s\n", length, XMLContent); + + real_query = (char *) malloc(sizeof(char) * (length + 4)); length = htonl(length); memcpy(real_query, &length, sizeof(length)); - memcpy(real_query + 4, raw_data, ntohl(length)); - log_debug_msg("lockdownd_send(): made the query, sending it along\n"); - dump_debug_buffer("grpkt", real_query, ntohl(length) + 4); + memcpy(real_query + 4, XMLContent, ntohl(length)); + free(XMLContent); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): made the query, sending it along\n"); if (!client->in_SSL) 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 gnutls_record_send(*client->ssl_session, real_query, ntohl(length) + sizeof(length)); ret = IPHONE_E_SUCCESS; } - log_debug_msg("lockdownd_send(): sent it!\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_send(): sent it!\n"); free(real_query); - *sent_bytes = bytes; + return ret; } @@ -277,54 +289,49 @@ iphone_error_t lockdownd_hello(iphone_lckd_client_t control) if (!control) return IPHONE_E_INVALID_ARG; - int bytes = 0, i = 0; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; plist_t dict = plist_new_dict(); - plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); - plist_add_sub_element(dict, PLIST_STRING, (void *) "QueryType", strlen("QueryType")); + plist_add_sub_key_el(dict, "Request"); + plist_add_sub_string_el(dict, "QueryType"); - log_debug_msg("lockdownd_hello() called\n"); - char *XML_content = NULL; - uint32_t length = 0; - - plist_to_xml(dict, &XML_content, &length); - log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); - ret = iphone_lckd_send(control, XML_content, length, &bytes); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_hello() called\n"); + ret = iphone_lckd_send(control, dict); - free(XML_content); - XML_content = NULL; plist_free(dict); dict = NULL; - ret = iphone_lckd_recv(control, &XML_content, &bytes); - log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); - plist_from_xml(XML_content, bytes, &dict); + ret = iphone_lckd_recv(control, &dict); - if (!dict) - return IPHONE_E_PLIST_ERROR; + if (IPHONE_E_SUCCESS != ret) + return ret; - plist_t query_node = plist_find_node(dict, PLIST_STRING, "QueryType", strlen("QueryType")); + plist_t query_node = plist_find_node_by_string(dict, "QueryType"); plist_t result_node = plist_get_next_sibling(query_node); plist_t value_node = plist_get_next_sibling(result_node); - plist_type result_type; - plist_type value_type; + plist_type result_type = plist_get_node_type(result_node); + plist_type value_type = plist_get_node_type(value_node); + + if (result_type == PLIST_KEY && value_type == PLIST_STRING) { - char *result_value = NULL; - char *value_value = NULL; - uint64_t result_length = 0; - uint64_t value_length = 0; + char *result_value = NULL; + char *value_value = NULL; - plist_get_type_and_value(result_node, &result_type, (void *) (&result_value), &result_length); - plist_get_type_and_value(value_node, &value_type, (void *) (&value_value), &value_length); + plist_get_key_val(result_node, &result_value); + plist_get_string_val(value_node, &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; + if (!strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_hello(): success\n"); + ret = IPHONE_E_SUCCESS; + } + free(result_value); + free(value_value); } + plist_free(dict); + dict = NULL; + return ret; } @@ -343,25 +350,18 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const c return IPHONE_E_INVALID_ARG; plist_t dict = NULL; - int bytes = 0, i = 0; - char *XML_content = NULL; - uint32_t length = 0; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; /* Setup DevicePublicKey request plist */ dict = plist_new_dict(); - plist_add_sub_element(dict, PLIST_KEY, (void *) req_key, strlen(req_key)); - plist_add_sub_element(dict, PLIST_STRING, (void *) req_string, strlen(req_string)); - plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); - plist_add_sub_element(dict, PLIST_STRING, (void *) "GetValue", strlen("GetValue")); - plist_to_xml(dict, &XML_content, &length); + plist_add_sub_key_el(dict, req_key); + plist_add_sub_string_el(dict, req_string); + plist_add_sub_key_el(dict, "Request"); + plist_add_sub_string_el(dict, "GetValue"); /* send to iPhone */ - log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); - ret = iphone_lckd_send(control, XML_content, length, &bytes); + ret = iphone_lckd_send(control, dict); - free(XML_content); - XML_content = NULL; plist_free(dict); dict = NULL; @@ -369,61 +369,65 @@ iphone_error_t lockdownd_generic_get_value(iphone_lckd_client_t control, const c return ret; /* Now get iPhone's answer */ - ret = iphone_lckd_recv(control, &XML_content, &bytes); - log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); + ret = iphone_lckd_recv(control, &dict); if (ret != IPHONE_E_SUCCESS) return ret; - plist_from_xml(XML_content, bytes, &dict); - if (!dict) - return IPHONE_E_PLIST_ERROR; - - plist_t query_node = plist_find_node(dict, PLIST_STRING, "GetValue", strlen("GetValue")); + plist_t query_node = plist_find_node_by_string(dict, "GetValue"); plist_t result_key_node = plist_get_next_sibling(query_node); plist_t result_value_node = plist_get_next_sibling(result_key_node); - plist_type result_key_type; - plist_type result_value_type; - char *result_key = NULL; - char *result_value = NULL; - uint64_t result_length = 0; - uint64_t value_length = 0; + plist_type result_key_type = plist_get_node_type(result_key_node); + plist_type result_value_type = plist_get_node_type(result_value_node); - plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &result_length); - plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &value_length); + if (result_key_type == PLIST_KEY && result_value_type == PLIST_STRING) { - if (result_key_type == PLIST_KEY && - result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { - log_debug_msg("lockdownd_generic_get_value(): success\n"); - ret = IPHONE_E_SUCCESS; - } + char *result_key = NULL; + char *result_value = NULL; + ret = IPHONE_E_DICT_ERROR; + + plist_get_key_val(result_key_node, &result_key); + plist_get_string_val(result_value_node, &result_value); + if (!strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_generic_get_value(): success\n"); + ret = IPHONE_E_SUCCESS; + } + free(result_key); + free(result_value); + } if (ret != IPHONE_E_SUCCESS) { - return IPHONE_E_DICT_ERROR; + return ret; } plist_t value_key_node = plist_get_next_sibling(result_key_node); plist_t value_value_node = plist_get_next_sibling(value_key_node); - plist_type value_key_type; - plist_type value_value_type; - char *value_key = NULL; - char *value_value = NULL; - uint64_t key_length = 0; - uint64_t valval_length = 0; - - plist_get_type_and_value(value_key_node, &value_key_type, (void *) (&value_key), &key_length); - plist_get_type_and_value(value_value_node, &value_value_type, (void *) (&value_value), &valval_length); - - if (value_key_type == PLIST_KEY && !strcmp(result_key, "Value")) { - log_debug_msg("lockdownd_generic_get_value(): success\n"); - value->data = value_value; - value->size = valval_length; - ret = IPHONE_E_SUCCESS; + + plist_type value_key_type = plist_get_node_type(value_key_node); + + if (value_key_type == PLIST_KEY) { + + char *result_key = NULL; + plist_get_key_val(value_key_node, &result_key); + + if (!strcmp(result_key, "Value")) { + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_generic_get_value(): success\n"); + + plist_type value_value_type; + char *value_value = NULL; + uint64_t valval_length = 0; + + plist_get_type_and_value(value_value_node, &value_value_type, (void *) (&value_value), &valval_length); + + value->data = value_value; + value->size = valval_length; + ret = IPHONE_E_SUCCESS; + } + free(result_key); } plist_free(dict); - free(XML_content); return ret; } @@ -520,9 +524,6 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; plist_t dict = NULL; plist_t dict_record = NULL; - int bytes = 0, i = 0; - char *XML_content = NULL; - uint32_t length = 0; gnutls_datum_t device_cert = { NULL, 0 }; 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 /* Setup Pair request plist */ dict = plist_new_dict(); - plist_add_sub_element(dict, PLIST_KEY, (void *) "PairRecord", strlen("PairRecord")); - dict_record = plist_add_sub_element(dict, PLIST_DICT, NULL, 0); - plist_add_sub_element(dict_record, PLIST_KEY, (void *) "DeviceCertificate", strlen("DeviceCertificate")); - plist_add_sub_element(dict_record, PLIST_DATA, (void *) device_cert.data, device_cert.size); - plist_add_sub_element(dict_record, PLIST_KEY, (void *) "HostCertificate", strlen("HostCertificate")); - plist_add_sub_element(dict_record, PLIST_DATA, (void *) host_cert.data, host_cert.size); - plist_add_sub_element(dict_record, PLIST_KEY, (void *) "HostID", strlen("HostID")); - plist_add_sub_element(dict_record, PLIST_STRING, (void *) host_id, strlen(host_id)); - plist_add_sub_element(dict_record, PLIST_KEY, (void *) "RootCertificate", strlen("RootCertificate")); - plist_add_sub_element(dict_record, PLIST_DATA, (void *) root_cert.data, root_cert.size); - plist_add_sub_element(dict_record, PLIST_KEY, (void *) "Request", strlen("Request")); - plist_add_sub_element(dict_record, PLIST_STRING, (void *) "Pair", strlen("Pair")); - plist_to_xml(dict, &XML_content, &length); - log_debug_msg("XML Pairing request :\nsize : %i\nxml :\n %s", length, XML_content); + plist_add_sub_key_el(dict, "PairRecord"); + dict_record = plist_new_dict(); + plist_add_sub_node(dict, dict_record); + plist_add_sub_key_el(dict_record, "DeviceCertificate"); + plist_add_sub_data_el(dict_record, device_cert.data, device_cert.size); + plist_add_sub_key_el(dict_record, "HostCertificate"); + plist_add_sub_data_el(dict_record, host_cert.data, host_cert.size); + plist_add_sub_key_el(dict_record, "HostID"); + plist_add_sub_string_el(dict_record, host_id); + plist_add_sub_key_el(dict_record, "RootCertificate"); + plist_add_sub_data_el(dict_record, root_cert.data, root_cert.size); + plist_add_sub_key_el(dict_record, "Request"); + plist_add_sub_string_el(dict_record, "Pair"); /* send to iPhone */ - ret = iphone_lckd_send(control, XML_content, length, &bytes); - - free(XML_content); + ret = iphone_lckd_send(control, dict); plist_free(dict); dict = NULL; @@ -569,45 +567,43 @@ iphone_error_t lockdownd_pair_device(iphone_lckd_client_t control, char *uid, ch return ret; /* Now get iPhone's answer */ - ret = iphone_lckd_recv(control, &XML_content, &bytes); + ret = iphone_lckd_recv(control, &dict); if (ret != IPHONE_E_SUCCESS) return ret; - log_debug_msg("lockdown_pair_device: iPhone's response to our pair request:\n"); - log_debug_msg(XML_content); - log_debug_msg("\n\n"); - - plist_from_xml(XML_content, bytes, &dict); - if (!dict) - return IPHONE_E_PLIST_ERROR; - - plist_t query_node = plist_find_node(dict, PLIST_STRING, "Pair", strlen("Pair")); + plist_t query_node = plist_find_node_by_string(dict, "Pair"); plist_t result_key_node = plist_get_next_sibling(query_node); plist_t result_value_node = plist_get_next_sibling(result_key_node); - plist_type result_key_type; - plist_type result_value_type; - char *result_key = NULL; - char *result_value = NULL; - uint64_t key_length = 0; - uint64_t val_length = 0; + plist_type result_key_type = plist_get_node_type(result_key_node); + plist_type result_value_type = plist_get_node_type(result_value_node); - plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &key_length); - plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &val_length); + if (result_key_type == PLIST_KEY && result_value_type == PLIST_STRING) { - if (result_key_type == PLIST_KEY && - result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { - ret = IPHONE_E_SUCCESS; + char *result_key = NULL; + char *result_value = NULL; + + plist_get_key_val(result_key_node, &result_key); + plist_get_string_val(result_value_node, &result_value); + + if (!strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { + ret = IPHONE_E_SUCCESS; + } + + free(result_key); + free(result_value); } + plist_free(dict); + dict = NULL; /* store public key in config if pairing succeeded */ if (ret == IPHONE_E_SUCCESS) { - log_debug_msg("lockdownd_pair_device: pair success\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_pair_device: pair success\n"); store_device_public_key(uid, public_key); ret = IPHONE_E_SUCCESS; } else { - log_debug_msg("lockdownd_pair_device: pair failure\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_pair_device: pair failure\n"); ret = IPHONE_E_PAIRING_FAILED; } free(public_key.data); @@ -625,56 +621,48 @@ void lockdownd_close(iphone_lckd_client_t control) if (!control) return; //IPHONE_E_INVALID_ARG; - int bytes = 0, i = 0; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; plist_t dict = plist_new_dict(); - plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); - plist_add_sub_element(dict, PLIST_STRING, (void *) "Goodbye", strlen("Goodbye")); - - log_debug_msg("lockdownd_close() called\n"); - char *XML_content = NULL; - uint32_t length = 0; + plist_add_sub_key_el(dict, "Request"); + plist_add_sub_string_el(dict, "Goodbye"); - plist_to_xml(dict, &XML_content, &length); - log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); - ret = iphone_lckd_send(control, XML_content, length, &bytes); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_close() called\n"); - free(XML_content); - XML_content = NULL; + ret = iphone_lckd_send(control, dict); plist_free(dict); dict = NULL; - ret = iphone_lckd_recv(control, &XML_content, &bytes); - log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); - plist_from_xml(XML_content, bytes, &dict); + ret = iphone_lckd_recv(control, &dict); if (!dict) { - log_debug_msg("lockdownd_close(): IPHONE_E_PLIST_ERROR\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_close(): IPHONE_E_PLIST_ERROR\n"); return; // IPHONE_E_PLIST_ERROR; } - plist_t query_node = plist_find_node(dict, PLIST_STRING, "Goodbye", strlen("Goodbye")); + plist_t query_node = plist_find_node_by_string(dict, "Goodbye"); plist_t result_node = plist_get_next_sibling(query_node); plist_t value_node = plist_get_next_sibling(result_node); - plist_type result_type; - plist_type value_type; + plist_type result_type = plist_get_node_type(result_node); + plist_type value_type = plist_get_node_type(value_node); - char *result_value = NULL; - char *value_value = NULL; - uint64_t result_length = 0; - uint64_t value_length = 0; + if (result_type == PLIST_KEY && value_type == PLIST_STRING) { + char *result_value = NULL; + char *value_value = NULL; - plist_get_type_and_value(result_node, &result_type, (void *) (&result_value), &result_length); - plist_get_type_and_value(value_node, &value_type, (void *) (&value_value), &value_length); + plist_get_key_val(result_node, &result_value); + plist_get_string_val(value_node, &value_value); - if (result_type == PLIST_KEY && - value_type == PLIST_STRING && !strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { - log_debug_msg("lockdownd_close(): success\n"); - ret = IPHONE_E_SUCCESS; + if (!strcmp(result_value, "Result") && !strcmp(value_value, "Success")) { + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_close(): success\n"); + ret = IPHONE_E_SUCCESS; + } + free(result_value); + free(value_value); } - + plist_free(dict); + dict = NULL; return; // ret; } @@ -824,54 +812,44 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c /* Setup DevicePublicKey request plist */ dict = plist_new_dict(); - plist_add_sub_element(dict, PLIST_KEY, (void *) "HostID", strlen("HostID")); - plist_add_sub_element(dict, PLIST_STRING, (void *) HostID, strlen(HostID)); - plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); - plist_add_sub_element(dict, PLIST_STRING, (void *) "StartSession", strlen("StartSession")); - plist_to_xml(dict, &XML_content, &length); - log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); + plist_add_sub_key_el(dict, "HostID"); + plist_add_sub_string_el(dict, HostID); + plist_add_sub_key_el(dict, "Request"); + plist_add_sub_string_el(dict, "StartSession"); - ret = iphone_lckd_send(control, XML_content, length, &bytes); - - free(XML_content); - XML_content = NULL; + ret = iphone_lckd_send(control, dict); plist_free(dict); dict = NULL; if (ret != IPHONE_E_SUCCESS) return ret; - if (bytes > 0) { - ret = iphone_lckd_recv(control, &XML_content, &bytes); - log_debug_msg("Receive msg :\nsize : %i\nxml : %s", bytes, XML_content); - plist_from_xml(XML_content, bytes, &dict); - free(XML_content); - XML_content = NULL; - if (!dict) - return IPHONE_E_PLIST_ERROR; - - plist_t query_node = plist_find_node(dict, PLIST_STRING, "StartSession", strlen("StartSession")); - plist_t result_key_node = plist_get_next_sibling(query_node); - plist_t result_value_node = plist_get_next_sibling(result_key_node); - - plist_type result_key_type; - plist_type result_value_type; + ret = iphone_lckd_recv(control, &dict); + + if (!dict) + return IPHONE_E_PLIST_ERROR; + + plist_t query_node = plist_find_node(dict, PLIST_STRING, "StartSession", strlen("StartSession")); + plist_t result_key_node = plist_get_next_sibling(query_node); + plist_t result_value_node = plist_get_next_sibling(result_key_node); + + plist_type result_key_type = plist_get_node_type(result_key_node); + plist_type result_value_type = plist_get_node_type(result_value_node); + + if (result_key_type == PLIST_KEY && result_value_type == PLIST_STRING) { char *result_key = NULL; char *result_value = NULL; - uint64_t key_length = 0; - uint64_t val_length = 0; - plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &key_length); - plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &val_length); + plist_get_key_val(result_key_node, &result_key); + plist_get_string_val(result_value_node, &result_value); ret = IPHONE_E_SSL_ERROR; - if (result_key_type == PLIST_KEY && - result_value_type == PLIST_STRING && !strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { + if (!strcmp(result_key, "Result") && !strcmp(result_value, "Success")) { // Set up GnuTLS... //gnutls_anon_client_credentials_t anoncred; gnutls_certificate_credentials_t xcred; - log_debug_msg("We started the session OK, now trying GnuTLS\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "We started the session OK, now trying GnuTLS\n"); errno = 0; gnutls_global_init(); //gnutls_anon_allocate_client_credentials(&anoncred); @@ -894,59 +872,59 @@ iphone_error_t lockdownd_start_SSL_session(iphone_lckd_client_t control, const c } gnutls_credentials_set(*control->ssl_session, GNUTLS_CRD_CERTIFICATE, xcred); // this part is killing me. - log_debug_msg("GnuTLS step 1...\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 1...\n"); gnutls_transport_set_ptr(*control->ssl_session, (gnutls_transport_ptr_t) control); - log_debug_msg("GnuTLS step 2...\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 2...\n"); gnutls_transport_set_push_function(*control->ssl_session, (gnutls_push_func) & lockdownd_secuwrite); - log_debug_msg("GnuTLS step 3...\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 3...\n"); gnutls_transport_set_pull_function(*control->ssl_session, (gnutls_pull_func) & lockdownd_securead); - log_debug_msg("GnuTLS step 4 -- now handshaking...\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS step 4 -- now handshaking...\n"); if (errno) - log_debug_msg("WARN: errno says %s before handshake!\n", strerror(errno)); + log_dbg_msg(DBGMASK_LOCKDOWND, "WARN: errno says %s before handshake!\n", strerror(errno)); return_me = gnutls_handshake(*control->ssl_session); - log_debug_msg("GnuTLS handshake done...\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS handshake done...\n"); if (return_me != GNUTLS_E_SUCCESS) { - log_debug_msg("GnuTLS reported something wrong.\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "GnuTLS reported something wrong.\n"); gnutls_perror(return_me); - log_debug_msg("oh.. errno says %s\n", strerror(errno)); + log_dbg_msg(DBGMASK_LOCKDOWND, "oh.. errno says %s\n", strerror(errno)); return IPHONE_E_SSL_ERROR; } else { control->in_SSL = 1; ret = IPHONE_E_SUCCESS; } } - //store session id - plist_t session_node = plist_find_node(dict, PLIST_KEY, "SessionID", strlen("SessionID")); - if (session_node) { + } + //store session id + plist_t session_node = plist_find_node_by_key(dict, "SessionID"); + if (session_node) { + + plist_t session_node_val = plist_get_next_sibling(session_node); + plist_type session_node_val_type = plist_get_node_type(session_node_val); + + if (session_node_val_type == PLIST_STRING) { - plist_type session_node_val_type; char *session_id = NULL; - uint64_t session_id_length = 0; - plist_t session_node_val = plist_get_next_sibling(session_node); + plist_get_string_val(session_node_val, &session_id); - plist_get_type_and_value(session_node_val, &session_node_val_type, (void *) (&session_id), - &session_id_length); - if (session_node_val_type == PLIST_STRING && session_id_length > 0) { + if (session_node_val_type == PLIST_STRING && session_id) { // we need to store the session ID for StopSession strcpy(control->session_id, session_id); - log_debug_msg("SessionID: %s\n", control->session_id); + log_dbg_msg(DBGMASK_LOCKDOWND, "SessionID: %s\n", control->session_id); } - } else - log_debug_msg("Failed to get SessionID!\n"); - plist_free(dict); - dict = NULL; + free(session_id); + } + } else + log_dbg_msg(DBGMASK_LOCKDOWND, "Failed to get SessionID!\n"); + plist_free(dict); + dict = NULL; - if (ret == IPHONE_E_SUCCESS) - return ret; + if (ret == IPHONE_E_SUCCESS) + return ret; - log_debug_msg("Apparently failed negotiating with lockdownd.\n"); - return IPHONE_E_SSL_ERROR; - } else { - log_debug_msg("Didn't get enough bytes.\n"); - return IPHONE_E_NOT_ENOUGH_DATA; - } + log_dbg_msg(DBGMASK_LOCKDOWND, "Apparently failed negotiating with lockdownd.\n"); + return IPHONE_E_SSL_ERROR; } /** gnutls callback for writing data to the iPhone. @@ -962,10 +940,10 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size int bytes = 0; iphone_lckd_client_t control; control = (iphone_lckd_client_t) transport; - log_debug_msg("lockdownd_secuwrite() called\n"); - log_debug_msg("pre-send\nlength = %zi\n", length); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_secuwrite() called\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "pre-send\nlength = %zi\n", length); iphone_mux_send(control->connection, buffer, length, &bytes); - log_debug_msg("post-send\nsent %i bytes\n", bytes); + log_dbg_msg(DBGMASK_LOCKDOWND, "post-send\nsent %i bytes\n", bytes); dump_debug_buffer("sslpacketwrite.out", buffer, length); return bytes; @@ -985,7 +963,7 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_ char *hackhackhack = NULL; iphone_lckd_client_t control; control = (iphone_lckd_client_t) transport; - log_debug_msg("lockdownd_securead() called\nlength = %zi\n", length); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_securead() called\nlength = %zi\n", length); // Buffering hack! Throw what we've got in our "buffer" into the stream first, then get more. if (control->gtls_buffer_hack_len > 0) { 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_ memcpy(buffer, control->gtls_buffer_hack, control->gtls_buffer_hack_len); // Fill their buffer partially free(control->gtls_buffer_hack); // free our memory, it's not chained anymore control->gtls_buffer_hack_len = 0; // we don't have a hack buffer anymore - log_debug_msg("Did a partial fill to help quench thirst for data\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "Did a partial fill to help quench thirst for data\n"); } else if (length < control->gtls_buffer_hack_len) { // If it's asking for less... control->gtls_buffer_hack_len -= length; // subtract what they're asking for 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_ free(control->gtls_buffer_hack); // Free the old one control->gtls_buffer_hack = hackhackhack; // And make it the new one. hackhackhack = NULL; - log_debug_msg("Quenched the thirst for data; new hack length is %i\n", control->gtls_buffer_hack_len); + log_dbg_msg(DBGMASK_LOCKDOWND, "Quenched the thirst for data; new hack length is %i\n", + control->gtls_buffer_hack_len); return length; // hand it over. } else { // length == hack length memcpy(buffer, control->gtls_buffer_hack, length); // copy our buffer into theirs free(control->gtls_buffer_hack); // free our "obligation" control->gtls_buffer_hack_len = 0; // free our "obligation" - log_debug_msg("Satiated the thirst for data; now we have to eventually receive again.\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "Satiated the thirst for data; now we have to eventually receive again.\n"); return length; // hand it over } } // End buffering hack! char *recv_buffer = (char *) malloc(sizeof(char) * (length * 1000)); // ensuring nothing stupid happens - log_debug_msg("pre-read\nclient wants %zi bytes\n", length); + log_dbg_msg(DBGMASK_LOCKDOWND, "pre-read\nclient wants %zi bytes\n", length); iphone_mux_recv(control->connection, recv_buffer, (length * 1000), &bytes); - log_debug_msg("post-read\nwe got %i bytes\n", bytes); + log_dbg_msg(DBGMASK_LOCKDOWND, "post-read\nwe got %i bytes\n", bytes); if (bytes < 0) { - log_debug_msg("lockdownd_securead(): uh oh\n"); - log_debug_msg - ("I believe what we have here is a failure to communicate... libusb says %s but strerror says %s\n", - usb_strerror(), strerror(errno)); + log_dbg_msg(DBGMASK_LOCKDOWND, "lockdownd_securead(): uh oh\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, + "I believe what we have here is a failure to communicate... libusb says %s but strerror says %s\n", + usb_strerror(), strerror(errno)); return bytes + 28; // an errno } if (bytes >= length) { if (bytes > length) { - log_debug_msg - ("lockdownd_securead: Client deliberately read less data than was there; resorting to GnuTLS buffering hack.\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, + "lockdownd_securead: Client deliberately read less data than was there; resorting to GnuTLS buffering hack.\n"); if (!control->gtls_buffer_hack_len) { // if there's no hack buffer yet //control->gtls_buffer_hack = strndup(recv_buffer+length, bytes-length); // strndup is NOT a good solution! control->gtls_buffer_hack_len += bytes - length; @@ -1045,10 +1024,11 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_ memcpy(buffer + pos_start_fill, recv_buffer, length); free(recv_buffer); if (bytes == length) { - log_debug_msg("Returning how much we received.\n"); + log_dbg_msg(DBGMASK_LOCKDOWND, "Returning how much we received.\n"); return bytes; } else { - log_debug_msg("Returning what they want to hear.\nHack length: %i\n", control->gtls_buffer_hack_len); + log_dbg_msg(DBGMASK_LOCKDOWND, "Returning what they want to hear.\nHack length: %i\n", + control->gtls_buffer_hack_len); return length; } } @@ -1073,95 +1053,72 @@ iphone_error_t iphone_lckd_start_service(iphone_lckd_client_t client, const char if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id)) return IPHONE_E_SSL_ERROR; - plist_t dict = NULL; - char *XML_content = NULL; - uint32_t length, i = 0, port_loc = 0, bytes = 0; + uint32_t port_loc = 0; iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; free(host_id); host_id = NULL; dict = plist_new_dict(); - plist_add_sub_element(dict, PLIST_KEY, (void *) "Request", strlen("Request")); - plist_add_sub_element(dict, PLIST_STRING, (void *) "StartService", strlen("StartService")); - plist_add_sub_element(dict, PLIST_KEY, (void *) "Service", strlen("Service")); - plist_add_sub_element(dict, PLIST_STRING, (void *) service, strlen(service)); - plist_to_xml(dict, &XML_content, &length); + plist_add_sub_key_el(dict, "Request"); + plist_add_sub_string_el(dict, "StartService"); + plist_add_sub_key_el(dict, "Service"); + plist_add_sub_string_el(dict, service); /* send to iPhone */ - log_debug_msg("Send msg :\nsize : %i\nxml : %s", length, XML_content); - ret = iphone_lckd_send(client, XML_content, length, &bytes); - - free(XML_content); - XML_content = NULL; + ret = iphone_lckd_send(client, dict); plist_free(dict); dict = NULL; if (IPHONE_E_SUCCESS != ret) return ret; - ret = iphone_lckd_recv(client, &XML_content, &bytes); + ret = iphone_lckd_recv(client, &dict); if (IPHONE_E_SUCCESS != ret) return ret; - plist_from_xml(XML_content, bytes, &dict); if (!dict) return IPHONE_E_PLIST_ERROR; + plist_t query_node = plist_find_node_by_string(dict, "StartService"); + plist_t result_key_node = plist_get_next_sibling(query_node); + plist_t result_value_node = plist_get_next_sibling(result_key_node); - if (bytes <= 0) - return IPHONE_E_NOT_ENOUGH_DATA; - else { + plist_t port_key_node = plist_find_node_by_key(dict, "Port"); + plist_t port_value_node = plist_get_next_sibling(port_key_node); - plist_t query_node = plist_find_node(dict, PLIST_STRING, "StartService", strlen("StartService")); - plist_t result_key_node = plist_get_next_sibling(query_node); - plist_t result_value_node = plist_get_next_sibling(result_key_node); + plist_type result_key_type = plist_get_node_type(result_key_node); + plist_type result_value_type = plist_get_node_type(result_value_node); + plist_type port_key_type = plist_get_node_type(port_key_node); + plist_type port_value_type = plist_get_node_type(port_value_node); - plist_t port_key_node = plist_find_node(dict, PLIST_KEY, "Port", strlen("Port")); - plist_t port_value_node = plist_get_next_sibling(port_key_node); + if (result_key_type == PLIST_KEY && result_value_type == PLIST_STRING && port_key_type == PLIST_KEY + && port_value_type == PLIST_UINT) { - plist_type result_key_type; - plist_type result_value_type; - plist_type port_key_type; - plist_type port_value_type; char *result_key = NULL; char *result_value = NULL; char *port_key = NULL; - uint64_t res_key_length = 0; - uint64_t res_val_length = 0; - uint64_t port_key_length = 0; - uint64_t port_val_length = 0; uint64_t port_value = 0; - plist_get_type_and_value(result_key_node, &result_key_type, (void *) (&result_key), &res_key_length); - plist_get_type_and_value(result_value_node, &result_value_type, (void *) (&result_value), &res_val_length); - plist_get_type_and_value(port_key_node, &port_key_type, (void *) (&port_key), &port_key_length); - plist_get_type_and_value(port_value_node, &port_value_type, (void *) (&port_value), &port_val_length); + plist_get_key_val(result_key_node, &result_key); + plist_get_string_val(result_value_node, &result_value); + plist_get_key_val(port_key_node, &port_key); + plist_get_uint_val(port_value_node, &port_value); - if (result_key_type == PLIST_KEY && - result_value_type == PLIST_STRING && - port_key_type == PLIST_KEY && - port_value_type == PLIST_UINT && - !strcmp(result_key, "Result") && !strcmp(result_value, "Success") && !strcmp(port_key, "Port")) { + if (!strcmp(result_key, "Result") && !strcmp(result_value, "Success") && !strcmp(port_key, "Port")) { port_loc = port_value; ret = IPHONE_E_SUCCESS; } - log_debug_msg("lockdownd_start_service(): DATA RECEIVED:\n\n"); - log_debug_msg(XML_content); - log_debug_msg("end data received by lockdownd_start_service()\n"); - - free(XML_content); - plist_free(dict); - dict = NULL; - if (port && ret == IPHONE_E_SUCCESS) { + if (port && ret == IPHONE_E_SUCCESS) *port = port_loc; - return IPHONE_E_SUCCESS; - } else - return IPHONE_E_UNKNOWN_ERROR; + else + ret = IPHONE_E_UNKNOWN_ERROR; } - return IPHONE_E_UNKNOWN_ERROR; + plist_free(dict); + dict = NULL; + return ret; } 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 @@ #include "libiphone/libiphone.h" +#define DBGMASK_ALL 0xFFFF +#define DBGMASK_NONE 0x0000 #define DBGMASK_USBMUX (1 << 1) #define DBGMASK_LOCKDOWND (1 << 2) #define DBGMASK_MOBILESYNC (1 << 3) |