summaryrefslogtreecommitdiffstats
path: root/src/mobile_image_mounter.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/mobile_image_mounter.c')
-rw-r--r--src/mobile_image_mounter.c274
1 files changed, 270 insertions, 4 deletions
diff --git a/src/mobile_image_mounter.c b/src/mobile_image_mounter.c
index 5df8e86..6df50c4 100644
--- a/src/mobile_image_mounter.c
+++ b/src/mobile_image_mounter.c
@@ -181,7 +181,7 @@ static mobile_image_mounter_error_t process_result(plist_t result, const char *e
181 return res; 181 return res;
182} 182}
183 183
184mobile_image_mounter_error_t mobile_image_mounter_upload_image(mobile_image_mounter_client_t client, const char *image_type, size_t image_size, const char *signature, uint16_t signature_size, mobile_image_mounter_upload_cb_t upload_cb, void* userdata) 184mobile_image_mounter_error_t mobile_image_mounter_upload_image(mobile_image_mounter_client_t client, const char *image_type, size_t image_size, const unsigned char *signature, unsigned int signature_size, mobile_image_mounter_upload_cb_t upload_cb, void* userdata)
185{ 185{
186 if (!client || !image_type || (image_size == 0) || !upload_cb) { 186 if (!client || !image_type || (image_size == 0) || !upload_cb) {
187 return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG; 187 return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG;
@@ -192,7 +192,7 @@ mobile_image_mounter_error_t mobile_image_mounter_upload_image(mobile_image_moun
192 plist_t dict = plist_new_dict(); 192 plist_t dict = plist_new_dict();
193 plist_dict_set_item(dict, "Command", plist_new_string("ReceiveBytes")); 193 plist_dict_set_item(dict, "Command", plist_new_string("ReceiveBytes"));
194 if (signature && signature_size != 0) 194 if (signature && signature_size != 0)
195 plist_dict_set_item(dict, "ImageSignature", plist_new_data(signature, signature_size)); 195 plist_dict_set_item(dict, "ImageSignature", plist_new_data((char*)signature, signature_size));
196 plist_dict_set_item(dict, "ImageSize", plist_new_uint(image_size)); 196 plist_dict_set_item(dict, "ImageSize", plist_new_uint(image_size));
197 plist_dict_set_item(dict, "ImageType", plist_new_string(image_type)); 197 plist_dict_set_item(dict, "ImageType", plist_new_string(image_type));
198 198
@@ -241,6 +241,7 @@ mobile_image_mounter_error_t mobile_image_mounter_upload_image(mobile_image_moun
241 free(buf); 241 free(buf);
242 if (tx < image_size) { 242 if (tx < image_size) {
243 debug_info("Error: failed to upload image"); 243 debug_info("Error: failed to upload image");
244 res = MOBILE_IMAGE_MOUNTER_E_COMMAND_FAILED;
244 goto leave_unlock; 245 goto leave_unlock;
245 } 246 }
246 debug_info("image uploaded"); 247 debug_info("image uploaded");
@@ -260,7 +261,7 @@ leave_unlock:
260 261
261} 262}
262 263
263mobile_image_mounter_error_t mobile_image_mounter_mount_image(mobile_image_mounter_client_t client, const char *image_path, const char *signature, uint16_t signature_size, const char *image_type, plist_t *result) 264mobile_image_mounter_error_t mobile_image_mounter_mount_image_with_options(mobile_image_mounter_client_t client, const char *image_path, const unsigned char *signature, unsigned int signature_size, const char *image_type, plist_t options, plist_t *result)
264{ 265{
265 if (!client || !image_path || !image_type || !result) { 266 if (!client || !image_path || !image_type || !result) {
266 return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG; 267 return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG;
@@ -271,8 +272,11 @@ mobile_image_mounter_error_t mobile_image_mounter_mount_image(mobile_image_mount
271 plist_dict_set_item(dict, "Command", plist_new_string("MountImage")); 272 plist_dict_set_item(dict, "Command", plist_new_string("MountImage"));
272 plist_dict_set_item(dict, "ImagePath", plist_new_string(image_path)); 273 plist_dict_set_item(dict, "ImagePath", plist_new_string(image_path));
273 if (signature && signature_size != 0) 274 if (signature && signature_size != 0)
274 plist_dict_set_item(dict, "ImageSignature", plist_new_data(signature, signature_size)); 275 plist_dict_set_item(dict, "ImageSignature", plist_new_data((char*)signature, signature_size));
275 plist_dict_set_item(dict, "ImageType", plist_new_string(image_type)); 276 plist_dict_set_item(dict, "ImageType", plist_new_string(image_type));
277 if (PLIST_IS_DICT(options)) {
278 plist_dict_merge(&dict, options);
279 }
276 280
277 mobile_image_mounter_error_t res = mobile_image_mounter_error(property_list_service_send_xml_plist(client->parent, dict)); 281 mobile_image_mounter_error_t res = mobile_image_mounter_error(property_list_service_send_xml_plist(client->parent, dict));
278 plist_free(dict); 282 plist_free(dict);
@@ -292,6 +296,56 @@ leave_unlock:
292 return res; 296 return res;
293} 297}
294 298
299mobile_image_mounter_error_t mobile_image_mounter_mount_image(mobile_image_mounter_client_t client, const char *image_path, const unsigned char *signature, unsigned int signature_size, const char *image_type, plist_t *result)
300{
301 return mobile_image_mounter_mount_image_with_options(client, image_path, signature, signature_size, image_type, NULL, result);
302}
303
304mobile_image_mounter_error_t mobile_image_mounter_unmount_image(mobile_image_mounter_client_t client, const char *mount_path)
305{
306 if (!client || !mount_path) {
307 return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG;
308 }
309 mobile_image_mounter_lock(client);
310
311 plist_t dict = plist_new_dict();
312 plist_dict_set_item(dict, "Command", plist_new_string("UnmountImage"));
313 plist_dict_set_item(dict, "MountPath", plist_new_string(mount_path));
314 mobile_image_mounter_error_t res = mobile_image_mounter_error(property_list_service_send_xml_plist(client->parent, dict));
315 plist_free(dict);
316
317 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
318 debug_info("%s: Error sending XML plist to device!", __func__);
319 goto leave_unlock;
320 }
321
322 plist_t result = NULL;
323 res = mobile_image_mounter_error(property_list_service_receive_plist(client->parent, &result));
324 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
325 debug_info("%s: Error receiving response from device!", __func__);
326 } else {
327 plist_t p_error = plist_dict_get_item(result, "Error");
328 if (p_error) {
329 plist_t p_detailed = plist_dict_get_item(result, "DetailedError");
330 const char* detailederr = (p_detailed) ? plist_get_string_ptr(p_detailed, NULL) : "";
331 const char* errstr = plist_get_string_ptr(p_error, NULL);
332 if (errstr && !strcmp(errstr, "UnknownCommand")) {
333 res = MOBILE_IMAGE_MOUNTER_E_NOT_SUPPORTED;
334 } else if (errstr && !strcmp(errstr, "DeviceLocked")) {
335 res = MOBILE_IMAGE_MOUNTER_E_DEVICE_LOCKED;
336 } else if (strstr(detailederr, "no matching entry")) {
337 res = MOBILE_IMAGE_MOUNTER_E_COMMAND_FAILED;
338 } else {
339 res = MOBILE_IMAGE_MOUNTER_E_UNKNOWN_ERROR;
340 }
341 }
342 }
343
344leave_unlock:
345 mobile_image_mounter_unlock(client);
346 return res;
347}
348
295mobile_image_mounter_error_t mobile_image_mounter_hangup(mobile_image_mounter_client_t client) 349mobile_image_mounter_error_t mobile_image_mounter_hangup(mobile_image_mounter_client_t client)
296{ 350{
297 if (!client) { 351 if (!client) {
@@ -324,3 +378,215 @@ leave_unlock:
324 mobile_image_mounter_unlock(client); 378 mobile_image_mounter_unlock(client);
325 return res; 379 return res;
326} 380}
381
382mobile_image_mounter_error_t mobile_image_mounter_query_developer_mode_status(mobile_image_mounter_client_t client, plist_t *result)
383{
384 if (!client || !result) {
385 return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG;
386 }
387 mobile_image_mounter_lock(client);
388
389 plist_t dict = plist_new_dict();
390 plist_dict_set_item(dict, "Command", plist_new_string("QueryDeveloperModeStatus"));
391 mobile_image_mounter_error_t res = mobile_image_mounter_error(property_list_service_send_xml_plist(client->parent, dict));
392 plist_free(dict);
393
394 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
395 debug_info("%s: Error sending XML plist to device!", __func__);
396 goto leave_unlock;
397 }
398
399 res = mobile_image_mounter_error(property_list_service_receive_plist(client->parent, result));
400 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
401 debug_info("%s: Error receiving response from device!", __func__);
402 }
403
404leave_unlock:
405 mobile_image_mounter_unlock(client);
406 return res;
407}
408
409mobile_image_mounter_error_t mobile_image_mounter_query_nonce(mobile_image_mounter_client_t client, const char* image_type, unsigned char** nonce, unsigned int* nonce_size)
410{
411 if (!client || !nonce || !nonce_size) {
412 return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG;
413 }
414 mobile_image_mounter_lock(client);
415
416 plist_t dict = plist_new_dict();
417 plist_dict_set_item(dict, "Command", plist_new_string("QueryNonce"));
418 if (image_type) {
419 plist_dict_set_item(dict, "PersonalizedImageType", plist_new_string(image_type));
420 }
421 mobile_image_mounter_error_t res = mobile_image_mounter_error(property_list_service_send_xml_plist(client->parent, dict));
422 plist_free(dict);
423
424 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
425 debug_info("%s: Error sending XML plist to device!", __func__);
426 goto leave_unlock;
427 }
428
429 plist_t result = NULL;
430 res = mobile_image_mounter_error(property_list_service_receive_plist(client->parent, &result));
431 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
432 debug_info("%s: Error receiving response from device!", __func__);
433 } else {
434 plist_t p_nonce = plist_dict_get_item(result, "PersonalizationNonce");
435 if (!p_nonce) {
436 res = MOBILE_IMAGE_MOUNTER_E_NOT_SUPPORTED;
437 } else {
438 uint64_t nonce_size_ = 0;
439 plist_get_data_val(p_nonce, (char**)nonce, &nonce_size_);
440 if (*nonce) {
441 *nonce_size = (unsigned int)nonce_size_;
442 } else {
443 res = MOBILE_IMAGE_MOUNTER_E_COMMAND_FAILED;
444 }
445 }
446 }
447 plist_free(result);
448
449leave_unlock:
450 mobile_image_mounter_unlock(client);
451 return res;
452}
453
454mobile_image_mounter_error_t mobile_image_mounter_query_personalization_identifiers(mobile_image_mounter_client_t client, const char* image_type, plist_t *result)
455{
456 if (!client || !result) {
457 return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG;
458 }
459 mobile_image_mounter_lock(client);
460
461 plist_t dict = plist_new_dict();
462 plist_dict_set_item(dict, "Command", plist_new_string("QueryPersonalizationIdentifiers"));
463 if (image_type) {
464 plist_dict_set_item(dict, "PersonalizedImageType", plist_new_string(image_type));
465 }
466 mobile_image_mounter_error_t res = mobile_image_mounter_error(property_list_service_send_xml_plist(client->parent, dict));
467 plist_free(dict);
468
469 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
470 debug_info("%s: Error sending XML plist to device!", __func__);
471 goto leave_unlock;
472 }
473
474 plist_t _result = NULL;
475 res = mobile_image_mounter_error(property_list_service_receive_plist(client->parent, &_result));
476 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
477 debug_info("%s: Error receiving response from device!", __func__);
478 }
479 *result = plist_copy(plist_dict_get_item(_result, "PersonalizationIdentifiers"));
480 if (!*result) {
481 debug_info("%s: Response did not contain PersonalizationIdentifiers!", __func__);
482 res = MOBILE_IMAGE_MOUNTER_E_COMMAND_FAILED;
483 }
484
485leave_unlock:
486 mobile_image_mounter_unlock(client);
487 return res;
488}
489
490mobile_image_mounter_error_t mobile_image_mounter_query_personalization_manifest(mobile_image_mounter_client_t client, const char* image_type, const unsigned char* signature, unsigned int signature_size, unsigned char** manifest, unsigned int* manifest_size)
491{
492 if (!client || !image_type || !signature || !signature_size || !manifest || !manifest_size) {
493 return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG;
494 }
495 mobile_image_mounter_lock(client);
496
497 plist_t dict = plist_new_dict();
498 plist_dict_set_item(dict, "Command", plist_new_string("QueryPersonalizationManifest"));
499 plist_dict_set_item(dict, "PersonalizedImageType", plist_new_string(image_type));
500 plist_dict_set_item(dict, "ImageType", plist_new_string(image_type));
501 plist_dict_set_item(dict, "ImageSignature", plist_new_data((char*)signature, signature_size));
502
503 mobile_image_mounter_error_t res = mobile_image_mounter_error(property_list_service_send_xml_plist(client->parent, dict));
504 plist_free(dict);
505
506 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
507 debug_info("%s: Error sending XML plist to device!", __func__);
508 goto leave_unlock;
509 }
510
511 plist_t result = NULL;
512 res = mobile_image_mounter_error(property_list_service_receive_plist(client->parent, &result));
513 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
514 debug_info("%s: Error receiving response from device!", __func__);
515 } else {
516 plist_t p_manifest = plist_dict_get_item(result, "ImageSignature");
517 if (!p_manifest) {
518 res = MOBILE_IMAGE_MOUNTER_E_NOT_SUPPORTED;
519 } else {
520 uint64_t manifest_size_ = 0;
521 plist_get_data_val(p_manifest, (char**)manifest, &manifest_size_);
522 if (*manifest) {
523 *manifest_size = (unsigned int)manifest_size_;
524 } else {
525 res = MOBILE_IMAGE_MOUNTER_E_COMMAND_FAILED;
526 }
527 }
528 }
529 plist_free(result);
530
531leave_unlock:
532 mobile_image_mounter_unlock(client);
533 return res;
534}
535
536mobile_image_mounter_error_t mobile_image_mounter_roll_personalization_nonce(mobile_image_mounter_client_t client)
537{
538 if (!client) {
539 return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG;
540 }
541 mobile_image_mounter_lock(client);
542
543 plist_t dict = plist_new_dict();
544 plist_dict_set_item(dict, "Command", plist_new_string("RollPersonalizationNonce"));
545 mobile_image_mounter_error_t res = mobile_image_mounter_error(property_list_service_send_xml_plist(client->parent, dict));
546 plist_free(dict);
547
548 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
549 debug_info("%s: Error sending XML plist to device!", __func__);
550 goto leave_unlock;
551 }
552
553 plist_t result = NULL;
554 res = mobile_image_mounter_error(property_list_service_receive_plist(client->parent, &result));
555 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
556 debug_info("%s: Error receiving response from device!", __func__);
557 }
558 plist_free(result);
559
560leave_unlock:
561 mobile_image_mounter_unlock(client);
562 return res;
563}
564
565mobile_image_mounter_error_t mobile_image_mounter_roll_cryptex_nonce(mobile_image_mounter_client_t client)
566{
567 if (!client) {
568 return MOBILE_IMAGE_MOUNTER_E_INVALID_ARG;
569 }
570 mobile_image_mounter_lock(client);
571
572 plist_t dict = plist_new_dict();
573 plist_dict_set_item(dict, "Command", plist_new_string("RollCryptexNonce"));
574 mobile_image_mounter_error_t res = mobile_image_mounter_error(property_list_service_send_xml_plist(client->parent, dict));
575 plist_free(dict);
576
577 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
578 debug_info("%s: Error sending XML plist to device!", __func__);
579 goto leave_unlock;
580 }
581
582 plist_t result = NULL;
583 res = mobile_image_mounter_error(property_list_service_receive_plist(client->parent, &result));
584 if (res != MOBILE_IMAGE_MOUNTER_E_SUCCESS) {
585 debug_info("%s: Error receiving response from device!", __func__);
586 }
587 plist_free(result);
588
589leave_unlock:
590 mobile_image_mounter_unlock(client);
591 return res;
592}