diff options
Diffstat (limited to 'src/lockdown.c')
| -rw-r--r-- | src/lockdown.c | 95 |
1 files changed, 90 insertions, 5 deletions
diff --git a/src/lockdown.c b/src/lockdown.c index cb57ca9..05ecc49 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -46,6 +46,10 @@ int get_rand(int min, int max) { | |||
| 46 | return retval; | 46 | return retval; |
| 47 | } | 47 | } |
| 48 | 48 | ||
| 49 | /** Generates a valid HostID (which is actually a UUID). | ||
| 50 | * | ||
| 51 | * @param A null terminated string containing a valid HostID. | ||
| 52 | */ | ||
| 49 | char *lockdownd_generate_hostid() { | 53 | char *lockdownd_generate_hostid() { |
| 50 | char *hostid = (char*)malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long | 54 | char *hostid = (char*)malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long |
| 51 | const char *chars = "ABCDEF0123456789"; | 55 | const char *chars = "ABCDEF0123456789"; |
| @@ -64,6 +68,12 @@ char *lockdownd_generate_hostid() { | |||
| 64 | return hostid; | 68 | return hostid; |
| 65 | } | 69 | } |
| 66 | 70 | ||
| 71 | /** Creates a lockdownd client for the give iPhone. | ||
| 72 | * | ||
| 73 | * @param phone The iPhone to create a lockdownd client for | ||
| 74 | * | ||
| 75 | * @return The lockdownd client. | ||
| 76 | */ | ||
| 67 | lockdownd_client *new_lockdownd_client(iPhone *phone) { | 77 | lockdownd_client *new_lockdownd_client(iPhone *phone) { |
| 68 | if (!phone) return NULL; | 78 | if (!phone) return NULL; |
| 69 | lockdownd_client *control = (lockdownd_client*)malloc(sizeof(lockdownd_client)); | 79 | lockdownd_client *control = (lockdownd_client*)malloc(sizeof(lockdownd_client)); |
| @@ -79,6 +89,10 @@ lockdownd_client *new_lockdownd_client(iPhone *phone) { | |||
| 79 | return control; | 89 | return control; |
| 80 | } | 90 | } |
| 81 | 91 | ||
| 92 | /** Closes the lockdownd client and does the necessary housekeeping. | ||
| 93 | * | ||
| 94 | * @param control The lockdown client | ||
| 95 | */ | ||
| 82 | void lockdown_close(lockdownd_client *control) { | 96 | void lockdown_close(lockdownd_client *control) { |
| 83 | if (!control) return; | 97 | if (!control) return; |
| 84 | if (control->connection) { | 98 | if (control->connection) { |
| @@ -89,7 +103,14 @@ void lockdown_close(lockdownd_client *control) { | |||
| 89 | free(control); | 103 | free(control); |
| 90 | } | 104 | } |
| 91 | 105 | ||
| 92 | 106 | /** Polls the iPhone for lockdownd data. | |
| 107 | * | ||
| 108 | * @param control The lockdownd client | ||
| 109 | * @param dump_data The pointer to the location of the buffer in which to store | ||
| 110 | * the received data | ||
| 111 | * | ||
| 112 | * @return The number of bytes received | ||
| 113 | */ | ||
| 93 | int lockdownd_recv(lockdownd_client *control, char **dump_data) { | 114 | int lockdownd_recv(lockdownd_client *control, char **dump_data) { |
| 94 | if (!control) return 0; | 115 | if (!control) return 0; |
| 95 | char *receive; | 116 | char *receive; |
| @@ -106,6 +127,17 @@ int lockdownd_recv(lockdownd_client *control, char **dump_data) { | |||
| 106 | return bytes; | 127 | return bytes; |
| 107 | } | 128 | } |
| 108 | 129 | ||
| 130 | /** Sends lockdownd data to the iPhone | ||
| 131 | * | ||
| 132 | * @note This function is low-level and should only be used if you need to send | ||
| 133 | * a new type of message. | ||
| 134 | * | ||
| 135 | * @param control The lockdownd client | ||
| 136 | * @param raw_data The null terminated string buffer to send | ||
| 137 | * @param length The length of data to send | ||
| 138 | * | ||
| 139 | * @return The number of bytes sent | ||
| 140 | */ | ||
| 109 | int lockdownd_send(lockdownd_client *control, char *raw_data, uint32 length) { | 141 | int lockdownd_send(lockdownd_client *control, char *raw_data, uint32 length) { |
| 110 | if (!control) return 0; | 142 | if (!control) return 0; |
| 111 | char *real_query; | 143 | char *real_query; |
| @@ -130,6 +162,14 @@ int lockdownd_send(lockdownd_client *control, char *raw_data, uint32 length) { | |||
| 130 | return bytes; | 162 | return bytes; |
| 131 | } | 163 | } |
| 132 | 164 | ||
| 165 | /** Initiates the handshake for the lockdown session. Part of the lockdownd handshake. | ||
| 166 | * | ||
| 167 | * @note You most likely want lockdownd_init unless you are doing something special. | ||
| 168 | * | ||
| 169 | * @param control The lockdownd client | ||
| 170 | * | ||
| 171 | * @return 1 on success and 0 on failure. | ||
| 172 | */ | ||
| 133 | int lockdownd_hello(lockdownd_client *control) { | 173 | int lockdownd_hello(lockdownd_client *control) { |
| 134 | if (!control) return 0; | 174 | if (!control) return 0; |
| 135 | xmlDocPtr plist = new_plist(); | 175 | xmlDocPtr plist = new_plist(); |
| @@ -172,7 +212,12 @@ int lockdownd_hello(lockdownd_client *control) { | |||
| 172 | free_dictionary(dictionary); | 212 | free_dictionary(dictionary); |
| 173 | return 0; | 213 | return 0; |
| 174 | } | 214 | } |
| 175 | 215 | /** Askes for the device's public key. Part of the lockdownd handshake. | |
| 216 | * | ||
| 217 | * @note You most likely want lockdownd_init unless you are doing something special. | ||
| 218 | * | ||
| 219 | * @return 1 on success and 0 on failure. | ||
| 220 | */ | ||
| 176 | int lockdownd_get_device_public_key(lockdownd_client *control, char **public_key) | 221 | int lockdownd_get_device_public_key(lockdownd_client *control, char **public_key) |
| 177 | { | 222 | { |
| 178 | xmlDocPtr plist = new_plist(); | 223 | xmlDocPtr plist = new_plist(); |
| @@ -228,7 +273,11 @@ int lockdownd_get_device_public_key(lockdownd_client *control, char **public_key | |||
| 228 | return success; | 273 | return success; |
| 229 | } | 274 | } |
| 230 | 275 | ||
| 231 | /** | 276 | /** Completes the entire lockdownd handshake. |
| 277 | * | ||
| 278 | * @param phone The iPhone | ||
| 279 | * @param lockdownd_client The pointer to the location of the lockdownd_client | ||
| 280 | * | ||
| 232 | * @return 1 on success and 0 on failure | 281 | * @return 1 on success and 0 on failure |
| 233 | */ | 282 | */ |
| 234 | int lockdownd_init(iPhone *phone, lockdownd_client **control) | 283 | int lockdownd_init(iPhone *phone, lockdownd_client **control) |
| @@ -272,7 +321,11 @@ int lockdownd_init(iPhone *phone, lockdownd_client **control) | |||
| 272 | return ret; | 321 | return ret; |
| 273 | } | 322 | } |
| 274 | 323 | ||
| 275 | /** | 324 | /** Generates the appropriate keys and pairs the device. It's part of the |
| 325 | * lockdownd handshake. | ||
| 326 | * | ||
| 327 | * @note You most likely want lockdownd_init unless you are doing something special. | ||
| 328 | * | ||
| 276 | * @return 1 on success and 0 on failure | 329 | * @return 1 on success and 0 on failure |
| 277 | */ | 330 | */ |
| 278 | int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char *host_id) | 331 | int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char *host_id) |
| @@ -359,7 +412,9 @@ int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char | |||
| 359 | return ret; | 412 | return ret; |
| 360 | } | 413 | } |
| 361 | 414 | ||
| 362 | /** | 415 | /** Generates the device certificate from the public key as well as the host |
| 416 | * and root certificates. | ||
| 417 | * | ||
| 363 | * @return 1 on success and 0 on failure. | 418 | * @return 1 on success and 0 on failure. |
| 364 | */ | 419 | */ |
| 365 | int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char **host_cert_b64, char **root_cert_b64) | 420 | int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char **host_cert_b64, char **root_cert_b64) |
| @@ -488,6 +543,13 @@ int lockdownd_gen_pair_cert(char *public_key_b64, char **device_cert_b64, char * | |||
| 488 | } | 543 | } |
| 489 | } | 544 | } |
| 490 | 545 | ||
| 546 | /** Starts SSL communication with lockdownd after the iPhone has been paired. | ||
| 547 | * | ||
| 548 | * @param control The lockdownd client | ||
| 549 | * @param HostID The HostID used with this phone | ||
| 550 | * | ||
| 551 | * @return 1 on success and 0 on failure | ||
| 552 | */ | ||
| 491 | int lockdownd_start_SSL_session(lockdownd_client *control, const char *HostID) { | 553 | int lockdownd_start_SSL_session(lockdownd_client *control, const char *HostID) { |
| 492 | xmlDocPtr plist = new_plist(); | 554 | xmlDocPtr plist = new_plist(); |
| 493 | xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); | 555 | xmlNode *dict = add_child_to_plist(plist, "dict", "\n", NULL, 0); |
| @@ -596,6 +658,14 @@ int lockdownd_start_SSL_session(lockdownd_client *control, const char *HostID) { | |||
| 596 | } | 658 | } |
| 597 | } | 659 | } |
| 598 | 660 | ||
| 661 | /** gnutls callback for writing data to the iPhone. | ||
| 662 | * | ||
| 663 | * @param transport It's really the lockdownd client, but the method signature has to match | ||
| 664 | * @param buffer The data to send | ||
| 665 | * @param length The length of data to send in bytes | ||
| 666 | * | ||
| 667 | * @return The number of bytes sent | ||
| 668 | */ | ||
| 599 | ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length) { | 669 | ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size_t length) { |
| 600 | int bytes = 0; | 670 | int bytes = 0; |
| 601 | lockdownd_client *control; | 671 | lockdownd_client *control; |
| @@ -615,6 +685,14 @@ ssize_t lockdownd_secuwrite(gnutls_transport_ptr_t transport, char *buffer, size | |||
| 615 | return bytes; | 685 | return bytes; |
| 616 | } | 686 | } |
| 617 | 687 | ||
| 688 | /** gnutls callback for reading data from the iPhone | ||
| 689 | * | ||
| 690 | * @param transport It's really the lockdownd client, but the method signature has to match | ||
| 691 | * @param buffer The buffer to store data in | ||
| 692 | * @param length The length of data to read in bytes | ||
| 693 | * | ||
| 694 | * @return The number of bytes read | ||
| 695 | */ | ||
| 618 | ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length) { | 696 | ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_t length) { |
| 619 | int bytes = 0, pos_start_fill = 0; | 697 | int bytes = 0, pos_start_fill = 0; |
| 620 | char *hackhackhack = NULL; | 698 | char *hackhackhack = NULL; |
| @@ -681,6 +759,13 @@ ssize_t lockdownd_securead(gnutls_transport_ptr_t transport, char *buffer, size_ | |||
| 681 | return bytes; | 759 | return bytes; |
| 682 | } | 760 | } |
| 683 | 761 | ||
| 762 | /** Command to start the desired service | ||
| 763 | * | ||
| 764 | * @param control The lockdownd client | ||
| 765 | * @param service The name of the service to start | ||
| 766 | * | ||
| 767 | * @return The port number the service was started on or 0 on failure. | ||
| 768 | */ | ||
| 684 | int lockdownd_start_service(lockdownd_client *control, const char *service) { | 769 | int lockdownd_start_service(lockdownd_client *control, const char *service) { |
| 685 | if (!control) return 0; | 770 | if (!control) return 0; |
| 686 | 771 | ||
