diff options
| -rw-r--r-- | src/lockdown.c | 210 | ||||
| -rw-r--r-- | src/lockdown.h | 2 | ||||
| -rw-r--r-- | src/property_list_service.c | 132 | ||||
| -rw-r--r-- | src/property_list_service.h | 7 |
4 files changed, 55 insertions, 296 deletions
diff --git a/src/lockdown.c b/src/lockdown.c index 7609426..5568f03 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -123,173 +123,6 @@ static void plist_dict_add_label(plist_t plist, const char *label) | |||
| 123 | } | 123 | } |
| 124 | } | 124 | } |
| 125 | 125 | ||
| 126 | /** gnutls callback for writing data to the device. | ||
| 127 | * | ||
| 128 | * @param transport It's really the lockdownd client, but the method signature has to match | ||
| 129 | * @param buffer The data to send | ||
| 130 | * @param length The length of data to send in bytes | ||
| 131 | * | ||
| 132 | * @return The number of bytes sent | ||
| 133 | */ | ||
| 134 | static ssize_t lockdownd_ssl_write(gnutls_transport_ptr_t transport, char *buffer, size_t length) | ||
| 135 | { | ||
| 136 | uint32_t bytes = 0; | ||
| 137 | lockdownd_client_t client; | ||
| 138 | client = (lockdownd_client_t) transport; | ||
| 139 | debug_info("pre-send length = %zi", length); | ||
| 140 | iphone_device_send(property_list_service_get_connection(client->parent), buffer, length, &bytes); | ||
| 141 | debug_info("post-send sent %i bytes", bytes); | ||
| 142 | return bytes; | ||
| 143 | } | ||
| 144 | |||
| 145 | /** gnutls callback for reading data from the device. | ||
| 146 | * | ||
| 147 | * @param transport It's really the lockdownd client, but the method signature has to match | ||
| 148 | * @param buffer The buffer to store data in | ||
| 149 | * @param length The length of data to read in bytes | ||
| 150 | * | ||
| 151 | * @return The number of bytes read | ||
| 152 | */ | ||
| 153 | static ssize_t lockdownd_ssl_read(gnutls_transport_ptr_t transport, char *buffer, size_t length) | ||
| 154 | { | ||
| 155 | int bytes = 0, pos_start_fill = 0; | ||
| 156 | size_t tbytes = 0; | ||
| 157 | int this_len = length; | ||
| 158 | iphone_error_t res; | ||
| 159 | lockdownd_client_t client; | ||
| 160 | client = (lockdownd_client_t) transport; | ||
| 161 | char *recv_buffer; | ||
| 162 | |||
| 163 | debug_info("pre-read client wants %zi bytes", length); | ||
| 164 | |||
| 165 | recv_buffer = (char *) malloc(sizeof(char) * this_len); | ||
| 166 | |||
| 167 | /* repeat until we have the full data or an error occurs */ | ||
| 168 | do { | ||
| 169 | if ((res = iphone_device_recv(property_list_service_get_connection(client->parent), recv_buffer, this_len, (uint32_t*)&bytes)) != LOCKDOWN_E_SUCCESS) { | ||
| 170 | debug_info("ERROR: iphone_device_recv returned %d", res); | ||
| 171 | return res; | ||
| 172 | } | ||
| 173 | debug_info("post-read we got %i bytes", bytes); | ||
| 174 | |||
| 175 | // increase read count | ||
| 176 | tbytes += bytes; | ||
| 177 | |||
| 178 | // fill the buffer with what we got right now | ||
| 179 | memcpy(buffer + pos_start_fill, recv_buffer, bytes); | ||
| 180 | pos_start_fill += bytes; | ||
| 181 | |||
| 182 | if (tbytes >= length) { | ||
| 183 | break; | ||
| 184 | } | ||
| 185 | |||
| 186 | this_len = length - tbytes; | ||
| 187 | debug_info("re-read trying to read missing %i bytes", this_len); | ||
| 188 | } while (tbytes < length); | ||
| 189 | |||
| 190 | if (recv_buffer) { | ||
| 191 | free(recv_buffer); | ||
| 192 | } | ||
| 193 | |||
| 194 | return tbytes; | ||
| 195 | } | ||
| 196 | |||
| 197 | /** Starts communication with lockdownd after the iPhone has been paired, | ||
| 198 | * and if the device requires it, switches to SSL mode. | ||
| 199 | * | ||
| 200 | * @param client The lockdownd client | ||
| 201 | * | ||
| 202 | * @return an error code (LOCKDOWN_E_SUCCESS on success) | ||
| 203 | */ | ||
| 204 | static lockdownd_error_t lockdownd_ssl_start_session(lockdownd_client_t client) | ||
| 205 | { | ||
| 206 | lockdownd_error_t ret = LOCKDOWN_E_SSL_ERROR; | ||
| 207 | uint32_t return_me = 0; | ||
| 208 | |||
| 209 | // Set up GnuTLS... | ||
| 210 | debug_info("enabling SSL mode"); | ||
| 211 | errno = 0; | ||
| 212 | gnutls_global_init(); | ||
| 213 | gnutls_certificate_allocate_credentials(&client->ssl_certificate); | ||
| 214 | gnutls_certificate_set_x509_trust_file(client->ssl_certificate, "hostcert.pem", GNUTLS_X509_FMT_PEM); | ||
| 215 | gnutls_init(&client->ssl_session, GNUTLS_CLIENT); | ||
| 216 | { | ||
| 217 | int protocol_priority[16] = { GNUTLS_SSL3, 0 }; | ||
| 218 | int kx_priority[16] = { GNUTLS_KX_ANON_DH, GNUTLS_KX_RSA, 0 }; | ||
| 219 | int cipher_priority[16] = { GNUTLS_CIPHER_AES_128_CBC, GNUTLS_CIPHER_AES_256_CBC, 0 }; | ||
| 220 | int mac_priority[16] = { GNUTLS_MAC_SHA1, GNUTLS_MAC_MD5, 0 }; | ||
| 221 | int comp_priority[16] = { GNUTLS_COMP_NULL, 0 }; | ||
| 222 | |||
| 223 | gnutls_cipher_set_priority(client->ssl_session, cipher_priority); | ||
| 224 | gnutls_compression_set_priority(client->ssl_session, comp_priority); | ||
| 225 | gnutls_kx_set_priority(client->ssl_session, kx_priority); | ||
| 226 | gnutls_protocol_set_priority(client->ssl_session, protocol_priority); | ||
| 227 | gnutls_mac_set_priority(client->ssl_session, mac_priority); | ||
| 228 | } | ||
| 229 | gnutls_credentials_set(client->ssl_session, GNUTLS_CRD_CERTIFICATE, client->ssl_certificate); // this part is killing me. | ||
| 230 | |||
| 231 | debug_info("GnuTLS step 1..."); | ||
| 232 | gnutls_transport_set_ptr(client->ssl_session, (gnutls_transport_ptr_t) client); | ||
| 233 | debug_info("GnuTLS step 2..."); | ||
| 234 | gnutls_transport_set_push_function(client->ssl_session, (gnutls_push_func) & lockdownd_ssl_write); | ||
| 235 | debug_info("GnuTLS step 3..."); | ||
| 236 | gnutls_transport_set_pull_function(client->ssl_session, (gnutls_pull_func) & lockdownd_ssl_read); | ||
| 237 | debug_info("GnuTLS step 4 -- now handshaking..."); | ||
| 238 | if (errno) | ||
| 239 | debug_info("WARN: errno says %s before handshake!", strerror(errno)); | ||
| 240 | return_me = gnutls_handshake(client->ssl_session); | ||
| 241 | debug_info("GnuTLS handshake done..."); | ||
| 242 | |||
| 243 | if (return_me != GNUTLS_E_SUCCESS) { | ||
| 244 | debug_info("GnuTLS reported something wrong."); | ||
| 245 | gnutls_perror(return_me); | ||
| 246 | debug_info("oh.. errno says %s", strerror(errno)); | ||
| 247 | } else { | ||
| 248 | client->ssl_enabled = 1; | ||
| 249 | ret = LOCKDOWN_E_SUCCESS; | ||
| 250 | debug_info("SSL mode enabled"); | ||
| 251 | } | ||
| 252 | |||
| 253 | return ret; | ||
| 254 | } | ||
| 255 | |||
| 256 | /** | ||
| 257 | * Shuts down the SSL session by performing a close notify, which is done | ||
| 258 | * by "gnutls_bye". | ||
| 259 | * | ||
| 260 | * @param client The lockdown client | ||
| 261 | * | ||
| 262 | * @return an error code (LOCKDOWN_E_SUCCESS on success) | ||
| 263 | */ | ||
| 264 | static lockdownd_error_t lockdownd_ssl_stop_session(lockdownd_client_t client) | ||
| 265 | { | ||
| 266 | if (!client) { | ||
| 267 | debug_info("invalid argument!"); | ||
| 268 | return LOCKDOWN_E_INVALID_ARG; | ||
| 269 | } | ||
| 270 | lockdownd_error_t ret = LOCKDOWN_E_SUCCESS; | ||
| 271 | |||
| 272 | if (client->ssl_enabled) { | ||
| 273 | debug_info("sending SSL close notify"); | ||
| 274 | gnutls_bye(client->ssl_session, GNUTLS_SHUT_RDWR); | ||
| 275 | } | ||
| 276 | if (client->ssl_session) { | ||
| 277 | gnutls_deinit(client->ssl_session); | ||
| 278 | } | ||
| 279 | if (client->ssl_certificate) { | ||
| 280 | gnutls_certificate_free_credentials(client->ssl_certificate); | ||
| 281 | } | ||
| 282 | client->ssl_enabled = 0; | ||
| 283 | |||
| 284 | if (client->session_id) | ||
| 285 | free(client->session_id); | ||
| 286 | client->session_id = NULL; | ||
| 287 | |||
| 288 | debug_info("SSL mode disabled"); | ||
| 289 | |||
| 290 | return ret; | ||
| 291 | } | ||
| 292 | |||
| 293 | /** | 126 | /** |
| 294 | * Closes the lockdownd communication session, by sending the StopSession | 127 | * Closes the lockdownd communication session, by sending the StopSession |
| 295 | * Request to the device. | 128 | * Request to the device. |
| @@ -339,10 +172,9 @@ lockdownd_error_t lockdownd_stop_session(lockdownd_client_t client, const char * | |||
| 339 | } | 172 | } |
| 340 | plist_free(dict); | 173 | plist_free(dict); |
| 341 | dict = NULL; | 174 | dict = NULL; |
| 342 | 175 | if (client->ssl_enabled) { | |
| 343 | /* stop ssl session */ | 176 | property_list_service_disable_ssl(client->parent); |
| 344 | lockdownd_ssl_stop_session(client); | 177 | } |
| 345 | |||
| 346 | return ret; | 178 | return ret; |
| 347 | } | 179 | } |
| 348 | 180 | ||
| @@ -411,16 +243,9 @@ lockdownd_error_t lockdownd_recv(lockdownd_client_t client, plist_t *plist) | |||
| 411 | lockdownd_error_t ret = LOCKDOWN_E_SUCCESS; | 243 | lockdownd_error_t ret = LOCKDOWN_E_SUCCESS; |
| 412 | property_list_service_error_t err; | 244 | property_list_service_error_t err; |
| 413 | 245 | ||
| 414 | if (!client->ssl_enabled) { | 246 | err = property_list_service_receive_plist(client->parent, plist); |
| 415 | err = property_list_service_receive_plist(client->parent, plist); | 247 | if (err != PROPERTY_LIST_SERVICE_E_SUCCESS) { |
| 416 | if (err != PROPERTY_LIST_SERVICE_E_SUCCESS) { | 248 | ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 417 | ret = LOCKDOWN_E_UNKNOWN_ERROR; | ||
| 418 | } | ||
| 419 | } else { | ||
| 420 | err = property_list_service_receive_encrypted_plist(client->ssl_session, plist); | ||
| 421 | if (err != PROPERTY_LIST_SERVICE_E_SUCCESS) { | ||
| 422 | return LOCKDOWN_E_SSL_ERROR; | ||
| 423 | } | ||
| 424 | } | 249 | } |
| 425 | 250 | ||
| 426 | if (!*plist) | 251 | if (!*plist) |
| @@ -447,16 +272,9 @@ lockdownd_error_t lockdownd_send(lockdownd_client_t client, plist_t plist) | |||
| 447 | lockdownd_error_t ret = LOCKDOWN_E_SUCCESS; | 272 | lockdownd_error_t ret = LOCKDOWN_E_SUCCESS; |
| 448 | iphone_error_t err; | 273 | iphone_error_t err; |
| 449 | 274 | ||
| 450 | if (!client->ssl_enabled) { | 275 | err = property_list_service_send_xml_plist(client->parent, plist); |
| 451 | err = property_list_service_send_xml_plist(client->parent, plist); | 276 | if (err != PROPERTY_LIST_SERVICE_E_SUCCESS) { |
| 452 | if (err != PROPERTY_LIST_SERVICE_E_SUCCESS) { | 277 | ret = LOCKDOWN_E_UNKNOWN_ERROR; |
| 453 | ret = LOCKDOWN_E_UNKNOWN_ERROR; | ||
| 454 | } | ||
| 455 | } else { | ||
| 456 | err = property_list_service_send_encrypted_xml_plist(client->ssl_session, plist); | ||
| 457 | if (err != PROPERTY_LIST_SERVICE_E_SUCCESS) { | ||
| 458 | ret = LOCKDOWN_E_SSL_ERROR; | ||
| 459 | } | ||
| 460 | } | 278 | } |
| 461 | return ret; | 279 | return ret; |
| 462 | } | 280 | } |
| @@ -775,8 +593,6 @@ lockdownd_error_t lockdownd_client_new(iphone_device_t device, lockdownd_client_ | |||
| 775 | 593 | ||
| 776 | lockdownd_client_t client_loc = (lockdownd_client_t) malloc(sizeof(struct lockdownd_client_int)); | 594 | lockdownd_client_t client_loc = (lockdownd_client_t) malloc(sizeof(struct lockdownd_client_int)); |
| 777 | client_loc->parent = plistclient; | 595 | client_loc->parent = plistclient; |
| 778 | client_loc->ssl_session = NULL; | ||
| 779 | client_loc->ssl_certificate = NULL; | ||
| 780 | client_loc->ssl_enabled = 0; | 596 | client_loc->ssl_enabled = 0; |
| 781 | client_loc->session_id = NULL; | 597 | client_loc->session_id = NULL; |
| 782 | client_loc->uuid = NULL; | 598 | client_loc->uuid = NULL; |
| @@ -848,8 +664,7 @@ lockdownd_error_t lockdownd_client_new_with_handshake(iphone_device_t device, lo | |||
| 848 | if (LOCKDOWN_E_SUCCESS == ret) { | 664 | if (LOCKDOWN_E_SUCCESS == ret) { |
| 849 | ret = lockdownd_start_session(client_loc, host_id, NULL, NULL); | 665 | ret = lockdownd_start_session(client_loc, host_id, NULL, NULL); |
| 850 | if (LOCKDOWN_E_SUCCESS != ret) { | 666 | if (LOCKDOWN_E_SUCCESS != ret) { |
| 851 | ret = LOCKDOWN_E_SSL_ERROR; | 667 | debug_info("Session opening failed."); |
| 852 | debug_info("SSL Session opening failed."); | ||
| 853 | } | 668 | } |
| 854 | 669 | ||
| 855 | if (host_id) { | 670 | if (host_id) { |
| @@ -1313,7 +1128,10 @@ lockdownd_error_t lockdownd_start_session(lockdownd_client_t client, const char | |||
| 1313 | } | 1128 | } |
| 1314 | debug_info("Enable SSL Session: %s", (use_ssl?"true":"false")); | 1129 | debug_info("Enable SSL Session: %s", (use_ssl?"true":"false")); |
| 1315 | if (use_ssl) { | 1130 | if (use_ssl) { |
| 1316 | ret = lockdownd_ssl_start_session(client); | 1131 | ret = property_list_service_enable_ssl(client->parent); |
| 1132 | if (ret == PROPERTY_LIST_SERVICE_E_SUCCESS) { | ||
| 1133 | client->ssl_enabled = 1; | ||
| 1134 | } | ||
| 1317 | } else { | 1135 | } else { |
| 1318 | client->ssl_enabled = 0; | 1136 | client->ssl_enabled = 0; |
| 1319 | ret = LOCKDOWN_E_SUCCESS; | 1137 | ret = LOCKDOWN_E_SUCCESS; |
diff --git a/src/lockdown.h b/src/lockdown.h index 9da3872..82ea01f 100644 --- a/src/lockdown.h +++ b/src/lockdown.h | |||
| @@ -30,8 +30,6 @@ | |||
| 30 | 30 | ||
| 31 | struct lockdownd_client_int { | 31 | struct lockdownd_client_int { |
| 32 | property_list_service_client_t parent; | 32 | property_list_service_client_t parent; |
| 33 | gnutls_session_t ssl_session; | ||
| 34 | gnutls_certificate_credentials_t ssl_certificate; | ||
| 35 | int ssl_enabled; | 33 | int ssl_enabled; |
| 36 | char *session_id; | 34 | char *session_id; |
| 37 | char *uuid; | 35 | char *uuid; |
diff --git a/src/property_list_service.c b/src/property_list_service.c index e39c7bb..b4c2f44 100644 --- a/src/property_list_service.c +++ b/src/property_list_service.c | |||
| @@ -43,6 +43,8 @@ static property_list_service_error_t iphone_to_property_list_service_error(iphon | |||
| 43 | return PROPERTY_LIST_SERVICE_E_SUCCESS; | 43 | return PROPERTY_LIST_SERVICE_E_SUCCESS; |
| 44 | case IPHONE_E_INVALID_ARG: | 44 | case IPHONE_E_INVALID_ARG: |
| 45 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | 45 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; |
| 46 | case IPHONE_E_SSL_ERROR: | ||
| 47 | return PROPERTY_LIST_SERVICE_E_SSL_ERROR; | ||
| 46 | default: | 48 | default: |
| 47 | break; | 49 | break; |
| 48 | } | 50 | } |
| @@ -106,12 +108,8 @@ property_list_service_error_t property_list_service_client_free(property_list_se | |||
| 106 | * Internally used generic plist send function. | 108 | * Internally used generic plist send function. |
| 107 | * | 109 | * |
| 108 | * @param client The property list service client to use for sending. | 110 | * @param client The property list service client to use for sending. |
| 109 | * Can be NULL if ssl_session is non-NULL. | ||
| 110 | * @param plist plist to send | 111 | * @param plist plist to send |
| 111 | * @param binary 1 = send binary plist, 0 = send xml plist | 112 | * @param binary 1 = send binary plist, 0 = send xml plist |
| 112 | * @param ssl_session If set to NULL, the communication will be unencrypted. | ||
| 113 | * For encrypted communication, pass a valid and properly initialized | ||
| 114 | * gnutls_session_t. client is ignored when ssl_session is non-NULL. | ||
| 115 | * | 113 | * |
| 116 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | 114 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, |
| 117 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when one or more parameters are | 115 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when one or more parameters are |
| @@ -119,7 +117,7 @@ property_list_service_error_t property_list_service_client_free(property_list_se | |||
| 119 | * plist, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified | 117 | * plist, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified |
| 120 | * error occurs. | 118 | * error occurs. |
| 121 | */ | 119 | */ |
| 122 | static property_list_service_error_t internal_plist_send(property_list_service_client_t client, plist_t plist, int binary, gnutls_session_t ssl_session) | 120 | static property_list_service_error_t internal_plist_send(property_list_service_client_t client, plist_t plist, int binary) |
| 123 | { | 121 | { |
| 124 | property_list_service_error_t res = PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; | 122 | property_list_service_error_t res = PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; |
| 125 | char *content = NULL; | 123 | char *content = NULL; |
| @@ -127,7 +125,7 @@ static property_list_service_error_t internal_plist_send(property_list_service_c | |||
| 127 | uint32_t nlen = 0; | 125 | uint32_t nlen = 0; |
| 128 | int bytes = 0; | 126 | int bytes = 0; |
| 129 | 127 | ||
| 130 | if ((!client && !ssl_session) || (client && !client->connection) || !plist) { | 128 | if (!client || (client && !client->connection) || !plist) { |
| 131 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | 129 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; |
| 132 | } | 130 | } |
| 133 | 131 | ||
| @@ -143,17 +141,9 @@ static property_list_service_error_t internal_plist_send(property_list_service_c | |||
| 143 | 141 | ||
| 144 | nlen = htonl(length); | 142 | nlen = htonl(length); |
| 145 | debug_info("sending %d bytes", length); | 143 | debug_info("sending %d bytes", length); |
| 146 | if (ssl_session) { | 144 | iphone_device_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); |
| 147 | bytes = gnutls_record_send(ssl_session, (const char*)&nlen, sizeof(nlen)); | ||
| 148 | } else { | ||
| 149 | iphone_device_send(client->connection, (const char*)&nlen, sizeof(nlen), (uint32_t*)&bytes); | ||
| 150 | } | ||
| 151 | if (bytes == sizeof(nlen)) { | 145 | if (bytes == sizeof(nlen)) { |
| 152 | if (ssl_session) { | 146 | iphone_device_send(client->connection, content, length, (uint32_t*)&bytes); |
| 153 | bytes = gnutls_record_send(ssl_session, content, length); | ||
| 154 | } else { | ||
| 155 | iphone_device_send(client->connection, content, length, (uint32_t*)&bytes); | ||
| 156 | } | ||
| 157 | if (bytes > 0) { | 147 | if (bytes > 0) { |
| 158 | debug_info("sent %d bytes", bytes); | 148 | debug_info("sent %d bytes", bytes); |
| 159 | debug_buffer(content, bytes); | 149 | debug_buffer(content, bytes); |
| @@ -186,7 +176,7 @@ static property_list_service_error_t internal_plist_send(property_list_service_c | |||
| 186 | */ | 176 | */ |
| 187 | property_list_service_error_t property_list_service_send_xml_plist(property_list_service_client_t client, plist_t plist) | 177 | property_list_service_error_t property_list_service_send_xml_plist(property_list_service_client_t client, plist_t plist) |
| 188 | { | 178 | { |
| 189 | return internal_plist_send(client, plist, 0, NULL); | 179 | return internal_plist_send(client, plist, 0); |
| 190 | } | 180 | } |
| 191 | 181 | ||
| 192 | /** | 182 | /** |
| @@ -202,39 +192,7 @@ property_list_service_error_t property_list_service_send_xml_plist(property_list | |||
| 202 | */ | 192 | */ |
| 203 | property_list_service_error_t property_list_service_send_binary_plist(property_list_service_client_t client, plist_t plist) | 193 | property_list_service_error_t property_list_service_send_binary_plist(property_list_service_client_t client, plist_t plist) |
| 204 | { | 194 | { |
| 205 | return internal_plist_send(client, plist, 1, NULL); | 195 | return internal_plist_send(client, plist, 1); |
| 206 | } | ||
| 207 | |||
| 208 | /** | ||
| 209 | * Sends an encrypted XML plist. | ||
| 210 | * | ||
| 211 | * @param ssl_session Valid and properly initialized gnutls_session_t. | ||
| 212 | * @param plist plist to send | ||
| 213 | * | ||
| 214 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | ||
| 215 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when ssl_session or plist is NULL | ||
| 216 | * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when dict is not a valid plist, | ||
| 217 | * or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified error occurs. | ||
| 218 | */ | ||
| 219 | property_list_service_error_t property_list_service_send_encrypted_xml_plist(gnutls_session_t ssl_session, plist_t plist) | ||
| 220 | { | ||
| 221 | return internal_plist_send(NULL, plist, 0, ssl_session); | ||
| 222 | } | ||
| 223 | |||
| 224 | /** | ||
| 225 | * Sends an encrypted binary plist. | ||
| 226 | * | ||
| 227 | * @param ssl_session Valid and properly initialized gnutls_session_t. | ||
| 228 | * @param plist plist to send | ||
| 229 | * | ||
| 230 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | ||
| 231 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when ssl_session or plist is NULL, | ||
| 232 | * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when dict is not a valid plist, | ||
| 233 | * or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when an unspecified error occurs. | ||
| 234 | */ | ||
| 235 | property_list_service_error_t property_list_service_send_encrypted_binary_plist(gnutls_session_t ssl_session, plist_t plist) | ||
| 236 | { | ||
| 237 | return internal_plist_send(NULL, plist, 1, ssl_session); | ||
| 238 | } | 196 | } |
| 239 | 197 | ||
| 240 | /** | 198 | /** |
| @@ -244,36 +202,26 @@ property_list_service_error_t property_list_service_send_encrypted_binary_plist( | |||
| 244 | * @param client The property list service client to use for receiving | 202 | * @param client The property list service client to use for receiving |
| 245 | * @param plist pointer to a plist_t that will point to the received plist | 203 | * @param plist pointer to a plist_t that will point to the received plist |
| 246 | * upon successful return | 204 | * upon successful return |
| 247 | * @param timeout Maximum time in milliseconds to wait for data. This parameter | 205 | * @param timeout Maximum time in milliseconds to wait for data. |
| 248 | * is ignored when ssl_session is not NULL (i.e. encrypted communication is | ||
| 249 | * used). A timeout has to be implemented inside the functions passed to | ||
| 250 | * gnutls_transport_set_push_function / gnutls_transport_set_pull_function. | ||
| 251 | * @param ssl_session If set to NULL, the communication will be unencrypted. | ||
| 252 | * For encrypted communication, pass a valid and properly initialized | ||
| 253 | * gnutls_session_t. | ||
| 254 | * | 206 | * |
| 255 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | 207 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, |
| 256 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or *plist is NULL, | 208 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when client or *plist is NULL, |
| 257 | * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be | 209 | * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be |
| 258 | * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a | 210 | * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a |
| 259 | * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when | 211 | * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR |
| 260 | * an unspecified error occurs. | 212 | * when an unspecified error occurs. |
| 261 | */ | 213 | */ |
| 262 | static property_list_service_error_t internal_plist_recv_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout, gnutls_session_t ssl_session) | 214 | static property_list_service_error_t internal_plist_recv_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout) |
| 263 | { | 215 | { |
| 264 | property_list_service_error_t res = PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; | 216 | property_list_service_error_t res = PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR; |
| 265 | uint32_t pktlen = 0; | 217 | uint32_t pktlen = 0; |
| 266 | uint32_t bytes = 0; | 218 | uint32_t bytes = 0; |
| 267 | 219 | ||
| 268 | if ((!client && !ssl_session) || (client && !client->connection) || !plist) { | 220 | if (!client || (client && !client->connection) || !plist) { |
| 269 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | 221 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; |
| 270 | } | 222 | } |
| 271 | 223 | ||
| 272 | if (ssl_session) { | 224 | iphone_device_recv_timeout(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes, timeout); |
| 273 | bytes = gnutls_record_recv(ssl_session, (char*)&pktlen, sizeof(pktlen)); | ||
| 274 | } else { | ||
| 275 | iphone_device_recv_timeout(client->connection, (char*)&pktlen, sizeof(pktlen), &bytes, timeout); | ||
| 276 | } | ||
| 277 | debug_info("initial read=%i", bytes); | 225 | debug_info("initial read=%i", bytes); |
| 278 | if (bytes < 4) { | 226 | if (bytes < 4) { |
| 279 | debug_info("initial read failed!"); | 227 | debug_info("initial read failed!"); |
| @@ -287,11 +235,7 @@ static property_list_service_error_t internal_plist_recv_timeout(property_list_s | |||
| 287 | content = (char*)malloc(pktlen); | 235 | content = (char*)malloc(pktlen); |
| 288 | 236 | ||
| 289 | while (curlen < pktlen) { | 237 | while (curlen < pktlen) { |
| 290 | if (ssl_session) { | 238 | iphone_device_recv(client->connection, content+curlen, pktlen-curlen, &bytes); |
| 291 | bytes = gnutls_record_recv(ssl_session, content+curlen, pktlen-curlen); | ||
| 292 | } else { | ||
| 293 | iphone_device_recv(client->connection, content+curlen, pktlen-curlen, &bytes); | ||
| 294 | } | ||
| 295 | if (bytes <= 0) { | 239 | if (bytes <= 0) { |
| 296 | res = PROPERTY_LIST_SERVICE_E_MUX_ERROR; | 240 | res = PROPERTY_LIST_SERVICE_E_MUX_ERROR; |
| 297 | break; | 241 | break; |
| @@ -338,7 +282,7 @@ static property_list_service_error_t internal_plist_recv_timeout(property_list_s | |||
| 338 | */ | 282 | */ |
| 339 | property_list_service_error_t property_list_service_receive_plist_with_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout) | 283 | property_list_service_error_t property_list_service_receive_plist_with_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout) |
| 340 | { | 284 | { |
| 341 | return internal_plist_recv_timeout(client, plist, timeout, NULL); | 285 | return internal_plist_recv_timeout(client, plist, timeout); |
| 342 | } | 286 | } |
| 343 | 287 | ||
| 344 | /** | 288 | /** |
| @@ -362,41 +306,41 @@ property_list_service_error_t property_list_service_receive_plist_with_timeout(p | |||
| 362 | */ | 306 | */ |
| 363 | property_list_service_error_t property_list_service_receive_plist(property_list_service_client_t client, plist_t *plist) | 307 | property_list_service_error_t property_list_service_receive_plist(property_list_service_client_t client, plist_t *plist) |
| 364 | { | 308 | { |
| 365 | return internal_plist_recv_timeout(client, plist, 10000, NULL); | 309 | return internal_plist_recv_timeout(client, plist, 10000); |
| 366 | } | 310 | } |
| 367 | 311 | ||
| 368 | /** | 312 | /** |
| 369 | * Receives an encrypted plist. | 313 | * Enable SSL for the given property list service client. |
| 370 | * Binary or XML plists are automatically handled. | ||
| 371 | * This function is like property_list_service_receive_encrypted_plist_with_timeout | ||
| 372 | * with a timeout value of 10 seconds. | ||
| 373 | * | 314 | * |
| 374 | * @param ssl_session Valid and properly initialized gnutls_session_t. | 315 | * @param client The connected property list service client for which SSL |
| 375 | * @param plist pointer to a plist_t that will point to the received plist | 316 | * should be enabled. |
| 376 | * upon successful return | ||
| 377 | * | 317 | * |
| 378 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, | 318 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, |
| 379 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG when ssl_session or *plist is NULL, | 319 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG if client or client->connection is |
| 380 | * PROPERTY_LIST_SERVICE_E_PLIST_ERROR when the received data cannot be | 320 | * NULL, PROPERTY_LIST_SERVICE_E_SSL_ERROR when SSL could not be enabled, |
| 381 | * converted to a plist, PROPERTY_LIST_SERVICE_E_MUX_ERROR when a | 321 | * or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR otherwise. |
| 382 | * communication error occurs, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR when | ||
| 383 | * an unspecified error occurs. | ||
| 384 | */ | 322 | */ |
| 385 | property_list_service_error_t property_list_service_receive_encrypted_plist(gnutls_session_t ssl_session, plist_t *plist) | 323 | property_list_service_error_t property_list_service_enable_ssl(property_list_service_client_t client) |
| 386 | { | 324 | { |
| 387 | return internal_plist_recv_timeout(NULL, plist, 10000, ssl_session); | 325 | if (!client || !client->connection) |
| 326 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; | ||
| 327 | return iphone_to_property_list_service_error(iphone_connection_enable_ssl(client->connection)); | ||
| 388 | } | 328 | } |
| 389 | 329 | ||
| 390 | /** | 330 | /** |
| 391 | * Getter for the iphone_connection_t used by this client. | 331 | * Disable SSL for the given property list service client. |
| 392 | * | 332 | * |
| 393 | * @param client The property list service client to get the connection for. | 333 | * @param client The connected property list service client for which SSL |
| 334 | * should be disabled. | ||
| 394 | * | 335 | * |
| 395 | * @return The connection used by client. | 336 | * @return PROPERTY_LIST_SERVICE_E_SUCCESS on success, |
| 337 | * PROPERTY_LIST_SERVICE_E_INVALID_ARG if client or client->connection is | ||
| 338 | * NULL, or PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR otherwise. | ||
| 396 | */ | 339 | */ |
| 397 | iphone_connection_t property_list_service_get_connection(property_list_service_client_t client) | 340 | property_list_service_error_t property_list_service_disable_ssl(property_list_service_client_t client) |
| 398 | { | 341 | { |
| 399 | if (!client) | 342 | if (!client || !client->connection) |
| 400 | return NULL; | 343 | return PROPERTY_LIST_SERVICE_E_INVALID_ARG; |
| 401 | return client->connection; | 344 | return iphone_to_property_list_service_error(iphone_connection_disable_ssl(client->connection)); |
| 402 | } | 345 | } |
| 346 | |||
diff --git a/src/property_list_service.h b/src/property_list_service.h index 39d4a0c..bc3122b 100644 --- a/src/property_list_service.h +++ b/src/property_list_service.h | |||
| @@ -28,6 +28,7 @@ | |||
| 28 | #define PROPERTY_LIST_SERVICE_E_INVALID_ARG -1 | 28 | #define PROPERTY_LIST_SERVICE_E_INVALID_ARG -1 |
| 29 | #define PROPERTY_LIST_SERVICE_E_PLIST_ERROR -2 | 29 | #define PROPERTY_LIST_SERVICE_E_PLIST_ERROR -2 |
| 30 | #define PROPERTY_LIST_SERVICE_E_MUX_ERROR -3 | 30 | #define PROPERTY_LIST_SERVICE_E_MUX_ERROR -3 |
| 31 | #define PROPERTY_LIST_SERVICE_E_SSL_ERROR -4 | ||
| 31 | 32 | ||
| 32 | #define PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR -256 | 33 | #define PROPERTY_LIST_SERVICE_E_UNKNOWN_ERROR -256 |
| 33 | 34 | ||
| @@ -46,15 +47,13 @@ property_list_service_error_t property_list_service_client_free(property_list_se | |||
| 46 | /* sending */ | 47 | /* sending */ |
| 47 | property_list_service_error_t property_list_service_send_xml_plist(property_list_service_client_t client, plist_t plist); | 48 | property_list_service_error_t property_list_service_send_xml_plist(property_list_service_client_t client, plist_t plist); |
| 48 | property_list_service_error_t property_list_service_send_binary_plist(property_list_service_client_t client, plist_t plist); | 49 | property_list_service_error_t property_list_service_send_binary_plist(property_list_service_client_t client, plist_t plist); |
| 49 | property_list_service_error_t property_list_service_send_encrypted_xml_plist(gnutls_session_t ssl_session, plist_t plist); | ||
| 50 | property_list_service_error_t property_list_service_send_encrypted_binary_plist(gnutls_session_t ssl_session, plist_t plist); | ||
| 51 | 50 | ||
| 52 | /* receiving */ | 51 | /* receiving */ |
| 53 | property_list_service_error_t property_list_service_receive_plist_with_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout); | 52 | property_list_service_error_t property_list_service_receive_plist_with_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout); |
| 54 | property_list_service_error_t property_list_service_receive_plist(property_list_service_client_t client, plist_t *plist); | 53 | property_list_service_error_t property_list_service_receive_plist(property_list_service_client_t client, plist_t *plist); |
| 55 | property_list_service_error_t property_list_service_receive_encrypted_plist(gnutls_session_t ssl_session, plist_t *plist); | ||
| 56 | 54 | ||
| 57 | /* misc */ | 55 | /* misc */ |
| 58 | iphone_connection_t property_list_service_get_connection(property_list_service_client_t client); | 56 | property_list_service_error_t property_list_service_enable_ssl(property_list_service_client_t client); |
| 57 | property_list_service_error_t property_list_service_disable_ssl(property_list_service_client_t client); | ||
| 59 | 58 | ||
| 60 | #endif | 59 | #endif |
