summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGravatar Nikias Bassen2010-01-13 00:11:43 +0100
committerGravatar Martin Szulecki2010-01-13 01:03:03 +0100
commitb578398a2883e1e81dbf5bdbd8b8ae917bf9e29d (patch)
tree03e25d7cca039f6c97fcaec4891327c6b58e23fe
parent65346c9ddd92e6ea3650040d791a411b9ac308af (diff)
downloadlibimobiledevice-b578398a2883e1e81dbf5bdbd8b8ae917bf9e29d.tar.gz
libimobiledevice-b578398a2883e1e81dbf5bdbd8b8ae917bf9e29d.tar.bz2
lockdown/property_list_service: use new SSL code
-rw-r--r--src/lockdown.c210
-rw-r--r--src/lockdown.h2
-rw-r--r--src/property_list_service.c132
-rw-r--r--src/property_list_service.h7
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 */
134static 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 */
153static 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 */
204static 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 */
264static 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
31struct lockdownd_client_int { 31struct 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 */
122static property_list_service_error_t internal_plist_send(property_list_service_client_t client, plist_t plist, int binary, gnutls_session_t ssl_session) 120static 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 */
187property_list_service_error_t property_list_service_send_xml_plist(property_list_service_client_t client, plist_t plist) 177property_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 */
203property_list_service_error_t property_list_service_send_binary_plist(property_list_service_client_t client, plist_t plist) 193property_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 */
219property_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 */
235property_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 */
262static 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) 214static 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 */
339property_list_service_error_t property_list_service_receive_plist_with_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout) 283property_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 */
363property_list_service_error_t property_list_service_receive_plist(property_list_service_client_t client, plist_t *plist) 307property_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 */
385property_list_service_error_t property_list_service_receive_encrypted_plist(gnutls_session_t ssl_session, plist_t *plist) 323property_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 */
397iphone_connection_t property_list_service_get_connection(property_list_service_client_t client) 340property_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 */
47property_list_service_error_t property_list_service_send_xml_plist(property_list_service_client_t client, plist_t plist); 48property_list_service_error_t property_list_service_send_xml_plist(property_list_service_client_t client, plist_t plist);
48property_list_service_error_t property_list_service_send_binary_plist(property_list_service_client_t client, plist_t plist); 49property_list_service_error_t property_list_service_send_binary_plist(property_list_service_client_t client, plist_t plist);
49property_list_service_error_t property_list_service_send_encrypted_xml_plist(gnutls_session_t ssl_session, plist_t plist);
50property_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 */
53property_list_service_error_t property_list_service_receive_plist_with_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout); 52property_list_service_error_t property_list_service_receive_plist_with_timeout(property_list_service_client_t client, plist_t *plist, unsigned int timeout);
54property_list_service_error_t property_list_service_receive_plist(property_list_service_client_t client, plist_t *plist); 53property_list_service_error_t property_list_service_receive_plist(property_list_service_client_t client, plist_t *plist);
55property_list_service_error_t property_list_service_receive_encrypted_plist(gnutls_session_t ssl_session, plist_t *plist);
56 54
57/* misc */ 55/* misc */
58iphone_connection_t property_list_service_get_connection(property_list_service_client_t client); 56property_list_service_error_t property_list_service_enable_ssl(property_list_service_client_t client);
57property_list_service_error_t property_list_service_disable_ssl(property_list_service_client_t client);
59 58
60#endif 59#endif