diff options
Diffstat (limited to 'src/lockdown.c')
| -rw-r--r-- | src/lockdown.c | 84 |
1 files changed, 52 insertions, 32 deletions
diff --git a/src/lockdown.c b/src/lockdown.c index 179b0a9..a22b896 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -94,15 +94,18 @@ iphone_lckd_client_t new_lockdownd_client(iphone_device_t phone) { | |||
| 94 | * | 94 | * |
| 95 | * @param control The lockdown client | 95 | * @param control The lockdown client |
| 96 | */ | 96 | */ |
| 97 | void iphone_lckd_free_client( iphone_lckd_client_t client ) { | 97 | iphone_error_t iphone_lckd_free_client( iphone_lckd_client_t client ) { |
| 98 | if (!client) return; | 98 | if (!client) return IPHONE_E_INVALID_ARG; |
| 99 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | ||
| 100 | |||
| 99 | if (client->connection) { | 101 | if (client->connection) { |
| 100 | iphone_mux_free_client(client->connection); | 102 | ret = iphone_mux_free_client(client->connection); |
| 101 | } | 103 | } |
| 102 | 104 | ||
| 103 | if (client->ssl_session) gnutls_deinit(*client->ssl_session); | 105 | if (client->ssl_session) gnutls_deinit(*client->ssl_session); |
| 104 | free(client->ssl_session); | 106 | free(client->ssl_session); |
| 105 | free(client); | 107 | free(client); |
| 108 | return ret; | ||
| 106 | } | 109 | } |
| 107 | 110 | ||
| 108 | /** Polls the iPhone for lockdownd data. | 111 | /** Polls the iPhone for lockdownd data. |
| @@ -113,20 +116,28 @@ void iphone_lckd_free_client( iphone_lckd_client_t client ) { | |||
| 113 | * | 116 | * |
| 114 | * @return The number of bytes received | 117 | * @return The number of bytes received |
| 115 | */ | 118 | */ |
| 116 | int iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data ) { | 119 | iphone_error_t iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data, uint32_t *recv_bytes ) { |
| 117 | if (!client) return 0; | 120 | if (!client || dump_data || !recv_bytes) return IPHONE_E_INVALID_ARG; |
| 121 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | ||
| 118 | char *receive; | 122 | char *receive; |
| 119 | uint32 datalen = 0, bytes = 0; | 123 | uint32 datalen = 0, bytes = 0; |
| 120 | 124 | ||
| 121 | if (!client->in_SSL) bytes = iphone_mux_recv(client->connection, (char *)&datalen, sizeof(datalen)); | 125 | if (!client->in_SSL) ret = iphone_mux_recv(client->connection, (char *)&datalen, sizeof(datalen), &bytes); |
| 122 | else bytes = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen)); | 126 | else { |
| 127 | bytes = gnutls_record_recv(*client->ssl_session, &datalen, sizeof(datalen)); | ||
| 128 | if (bytes > 0) ret = IPHONE_E_SUCCESS; | ||
| 129 | } | ||
| 123 | datalen = ntohl(datalen); | 130 | datalen = ntohl(datalen); |
| 124 | 131 | ||
| 125 | receive = (char*)malloc(sizeof(char) * datalen); | 132 | receive = (char*)malloc(sizeof(char) * datalen); |
| 126 | if (!client->in_SSL) bytes = iphone_mux_recv(client->connection, receive, datalen); | 133 | if (!client->in_SSL) ret = iphone_mux_recv(client->connection, receive, datalen, &bytes); |
| 127 | else bytes = gnutls_record_recv(*client->ssl_session, receive, datalen); | 134 | else { |
| 135 | bytes = gnutls_record_recv(*client->ssl_session, receive, datalen); | ||
| 136 | if (bytes > 0) ret = IPHONE_E_SUCCESS; | ||
| 137 | } | ||
| 128 | *dump_data = receive; | 138 | *dump_data = receive; |
| 129 | return bytes; | 139 | *recv_bytes = bytes; |
| 140 | return ret; | ||
| 130 | } | 141 | } |
| 131 | 142 | ||
| 132 | /** Sends lockdownd data to the iPhone | 143 | /** Sends lockdownd data to the iPhone |
| @@ -140,11 +151,12 @@ int iphone_lckd_recv ( iphone_lckd_client_t client, char **dump_data ) { | |||
| 140 | * | 151 | * |
| 141 | * @return The number of bytes sent | 152 | * @return The number of bytes sent |
| 142 | */ | 153 | */ |
| 143 | int iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t length ) { | 154 | iphone_error_t iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t length, uint32_t *sent_bytes ) { |
| 144 | if (!client) return 0; | 155 | if (!client || !raw_data || length == 0 || !sent_bytes) return IPHONE_E_INVALID_ARG; |
| 145 | char *real_query; | 156 | char *real_query; |
| 146 | int bytes; | 157 | int bytes; |
| 147 | 158 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | |
| 159 | |||
| 148 | real_query = (char*)malloc(sizeof(char) * (length+4)); | 160 | real_query = (char*)malloc(sizeof(char) * (length+4)); |
| 149 | length = htonl(length); | 161 | length = htonl(length); |
| 150 | memcpy(real_query, &length, sizeof(length)); | 162 | memcpy(real_query, &length, sizeof(length)); |
| @@ -157,11 +169,15 @@ int iphone_lckd_send ( iphone_lckd_client_t client, char *raw_data, uint32_t len | |||
| 157 | packet = NULL; | 169 | packet = NULL; |
| 158 | } | 170 | } |
| 159 | 171 | ||
| 160 | if (!client->in_SSL) bytes = iphone_mux_send(client->connection, real_query, ntohl(length)+sizeof(length)); | 172 | if (!client->in_SSL) ret = iphone_mux_send(client->connection, real_query, ntohl(length)+sizeof(length), &bytes); |
| 161 | else gnutls_record_send(*client->ssl_session, real_query, ntohl(length)+sizeof(length)); | 173 | else { |
| 174 | gnutls_record_send(*client->ssl_session, real_query, ntohl(length)+sizeof(length)); | ||
| 175 | ret = IPHONE_E_SUCCESS; | ||
| 176 | } | ||
| 162 | if (debug) printf("lockdownd_send(): sent it!\n"); | 177 | if (debug) printf("lockdownd_send(): sent it!\n"); |
| 163 | free(real_query); | 178 | free(real_query); |
| 164 | return bytes; | 179 | *sent_bytes = bytes; |
| 180 | return ret; | ||
| 165 | } | 181 | } |
| 166 | 182 | ||
| 167 | /** Initiates the handshake for the lockdown session. Part of the lockdownd handshake. | 183 | /** Initiates the handshake for the lockdown session. Part of the lockdownd handshake. |
| @@ -307,11 +323,11 @@ int lockdownd_get_device_public_key(iphone_lckd_client_t control, char **public_ | |||
| 307 | * | 323 | * |
| 308 | * @return 1 on success and 0 on failure | 324 | * @return 1 on success and 0 on failure |
| 309 | */ | 325 | */ |
| 310 | int iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_client_t *client ) | 326 | iphone_error_t iphone_lckd_new_client ( iphone_device_t device, iphone_lckd_client_t *client ) |
| 311 | { | 327 | { |
| 312 | if (!device || !client || (client && *client) ) | 328 | if (!device || !client || (client && *client) ) |
| 313 | return IPHONE_E_INVALID_ARG; | 329 | return IPHONE_E_INVALID_ARG; |
| 314 | int ret = IPHONE_E_SUCCESS; | 330 | iphone_error_t ret = IPHONE_E_SUCCESS; |
| 315 | char *host_id = NULL; | 331 | char *host_id = NULL; |
| 316 | 332 | ||
| 317 | iphone_lckd_client_t client_loc = new_lockdownd_client( device ); | 333 | iphone_lckd_client_t client_loc = new_lockdownd_client( device ); |
| @@ -815,14 +831,15 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_ | |||
| 815 | * | 831 | * |
| 816 | * @return The port number the service was started on or 0 on failure. | 832 | * @return The port number the service was started on or 0 on failure. |
| 817 | */ | 833 | */ |
| 818 | int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service ) { | 834 | iphone_error_t iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service, int *port ) { |
| 819 | if (!client) return 0; | 835 | if (!client || !service || !port) return IPHONE_E_INVALID_ARG; |
| 820 | 836 | ||
| 821 | char* host_id = get_host_id(); | 837 | char* host_id = get_host_id(); |
| 822 | if (host_id && !client->in_SSL && !lockdownd_start_SSL_session(client, host_id)) return 0; | 838 | if (!host_id) return IPHONE_E_INVALID_CONF; |
| 839 | if (!client->in_SSL && !lockdownd_start_SSL_session(client, host_id)) return IPHONE_E_SSL_ERROR; | ||
| 823 | 840 | ||
| 824 | char *XML_query, **dictionary; | 841 | char *XML_query, **dictionary; |
| 825 | uint32 length, i = 0, port = 0; | 842 | uint32 length, i = 0, port_loc = 0; |
| 826 | uint8 result = 0; | 843 | uint8 result = 0; |
| 827 | 844 | ||
| 828 | free(host_id); | 845 | free(host_id); |
| @@ -832,9 +849,9 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service | |||
| 832 | xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); | 849 | xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); |
| 833 | xmlNode *key; | 850 | xmlNode *key; |
| 834 | key = add_key_str_dict_element(plist, dict, "Request", "StartService", 1); | 851 | key = add_key_str_dict_element(plist, dict, "Request", "StartService", 1); |
| 835 | if (!key) { xmlFreeDoc(plist); return 0; } | 852 | if (!key) { xmlFreeDoc(plist); return IPHONE_E_UNKNOWN_ERROR; } |
| 836 | key = add_key_str_dict_element(plist, dict, "Service", service, 1); | 853 | key = add_key_str_dict_element(plist, dict, "Service", service, 1); |
| 837 | if (!key) { xmlFreeDoc(plist); return 0; } | 854 | if (!key) { xmlFreeDoc(plist); return IPHONE_E_UNKNOWN_ERROR; } |
| 838 | 855 | ||
| 839 | xmlDocDumpMemory(plist, (xmlChar **)&XML_query, &length); | 856 | xmlDocDumpMemory(plist, (xmlChar **)&XML_query, &length); |
| 840 | 857 | ||
| @@ -845,24 +862,24 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service | |||
| 845 | 862 | ||
| 846 | xmlFreeDoc(plist); | 863 | xmlFreeDoc(plist); |
| 847 | 864 | ||
| 848 | if (length <= 0) return 0; | 865 | if (length <= 0) return IPHONE_E_NOT_ENOUGH_DATA; |
| 849 | else { | 866 | else { |
| 850 | plist = xmlReadMemory(XML_query, length, NULL, NULL, 0); | 867 | plist = xmlReadMemory(XML_query, length, NULL, NULL, 0); |
| 851 | if (!plist) return 0; | 868 | if (!plist) return IPHONE_E_UNKNOWN_ERROR; |
| 852 | dict = xmlDocGetRootElement(plist); | 869 | dict = xmlDocGetRootElement(plist); |
| 853 | if (!dict) return 0; | 870 | if (!dict) return IPHONE_E_UNKNOWN_ERROR; |
| 854 | for (dict = dict->children; dict; dict = dict->next) { | 871 | for (dict = dict->children; dict; dict = dict->next) { |
| 855 | if (!xmlStrcmp(dict->name, "dict")) break; | 872 | if (!xmlStrcmp(dict->name, "dict")) break; |
| 856 | } | 873 | } |
| 857 | 874 | ||
| 858 | if (!dict) return 0; | 875 | if (!dict) return IPHONE_E_UNKNOWN_ERROR; |
| 859 | dictionary = read_dict_element_strings(dict); | 876 | dictionary = read_dict_element_strings(dict); |
| 860 | 877 | ||
| 861 | for (i = 0; dictionary[i]; i+=2) { | 878 | for (i = 0; dictionary[i]; i+=2) { |
| 862 | if (debug) printf("lockdownd_start_service() dictionary %s: %s\n", dictionary[i], dictionary[i+1]); | 879 | if (debug) printf("lockdownd_start_service() dictionary %s: %s\n", dictionary[i], dictionary[i+1]); |
| 863 | 880 | ||
| 864 | if (!xmlStrcmp(dictionary[i], "Port")) { | 881 | if (!xmlStrcmp(dictionary[i], "Port")) { |
| 865 | port = atoi(dictionary[i+1]); | 882 | port_loc = atoi(dictionary[i+1]); |
| 866 | if (debug) printf("lockdownd_start_service() atoi'd port: %i\n", port); | 883 | if (debug) printf("lockdownd_start_service() atoi'd port: %i\n", port); |
| 867 | } | 884 | } |
| 868 | 885 | ||
| @@ -882,9 +899,12 @@ int iphone_lckd_start_service ( iphone_lckd_client_t client, const char *service | |||
| 882 | free(XML_query); | 899 | free(XML_query); |
| 883 | xmlFreeDoc(plist); | 900 | xmlFreeDoc(plist); |
| 884 | free_dictionary(dictionary); | 901 | free_dictionary(dictionary); |
| 885 | if (port && result) return port; | 902 | if (port && result) { |
| 886 | else return 0; | 903 | *port = port_loc; |
| 904 | return IPHONE_E_SUCCESS; | ||
| 905 | } | ||
| 906 | else return IPHONE_E_UNKNOWN_ERROR; | ||
| 887 | } | 907 | } |
| 888 | 908 | ||
| 889 | return 0; | 909 | return IPHONE_E_UNKNOWN_ERROR; |
| 890 | } | 910 | } |
