summaryrefslogtreecommitdiffstats
path: root/src/lockdown.c
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 /src/lockdown.c
parent65346c9ddd92e6ea3650040d791a411b9ac308af (diff)
downloadlibimobiledevice-b578398a2883e1e81dbf5bdbd8b8ae917bf9e29d.tar.gz
libimobiledevice-b578398a2883e1e81dbf5bdbd8b8ae917bf9e29d.tar.bz2
lockdown/property_list_service: use new SSL code
Diffstat (limited to 'src/lockdown.c')
-rw-r--r--src/lockdown.c210
1 files changed, 14 insertions, 196 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;