diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/mobile_image_mounter.c | 274 |
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 | ||
| 184 | mobile_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) | 184 | mobile_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 | ||
| 263 | mobile_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) | 264 | mobile_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 | ||
| 299 | mobile_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 | |||
| 304 | mobile_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 | |||
| 344 | leave_unlock: | ||
| 345 | mobile_image_mounter_unlock(client); | ||
| 346 | return res; | ||
| 347 | } | ||
| 348 | |||
| 295 | mobile_image_mounter_error_t mobile_image_mounter_hangup(mobile_image_mounter_client_t client) | 349 | mobile_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 | |||
| 382 | mobile_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 | |||
| 404 | leave_unlock: | ||
| 405 | mobile_image_mounter_unlock(client); | ||
| 406 | return res; | ||
| 407 | } | ||
| 408 | |||
| 409 | mobile_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 | |||
| 449 | leave_unlock: | ||
| 450 | mobile_image_mounter_unlock(client); | ||
| 451 | return res; | ||
| 452 | } | ||
| 453 | |||
| 454 | mobile_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 | |||
| 485 | leave_unlock: | ||
| 486 | mobile_image_mounter_unlock(client); | ||
| 487 | return res; | ||
| 488 | } | ||
| 489 | |||
| 490 | mobile_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 | |||
| 531 | leave_unlock: | ||
| 532 | mobile_image_mounter_unlock(client); | ||
| 533 | return res; | ||
| 534 | } | ||
| 535 | |||
| 536 | mobile_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 | |||
| 560 | leave_unlock: | ||
| 561 | mobile_image_mounter_unlock(client); | ||
| 562 | return res; | ||
| 563 | } | ||
| 564 | |||
| 565 | mobile_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 | |||
| 589 | leave_unlock: | ||
| 590 | mobile_image_mounter_unlock(client); | ||
| 591 | return res; | ||
| 592 | } | ||
