diff options
| author | 2008-08-05 23:25:35 -0700 | |
|---|---|---|
| committer | 2008-08-05 23:28:10 -0700 | |
| commit | 25e85bf5362b6f4c1878665c6037fdbfdc25c155 (patch) | |
| tree | 437979cdb4b9a7958a3d891d6a39a7be2bf61d17 | |
| parent | 4b558a53f61005b0ca49665d2da92303f6e14872 (diff) | |
| download | libimobiledevice-25e85bf5362b6f4c1878665c6037fdbfdc25c155.tar.gz libimobiledevice-25e85bf5362b6f4c1878665c6037fdbfdc25c155.tar.bz2 | |
Zack's final changes to the pairing.
| -rw-r--r-- | src/ifuse.c | 9 | ||||
| -rw-r--r-- | src/initconf.c | 31 | ||||
| -rw-r--r-- | src/lockdown.c | 46 | ||||
| -rw-r--r-- | src/main.c | 1 | ||||
| -rw-r--r-- | src/plist.h | 1 | ||||
| -rw-r--r-- | src/usbmux.c | 2 | ||||
| -rw-r--r-- | src/userpref.c | 15 |
7 files changed, 84 insertions, 21 deletions
diff --git a/src/ifuse.c b/src/ifuse.c index 900bb17..f33eaaa 100644 --- a/src/ifuse.c +++ b/src/ifuse.c | |||
| @@ -52,13 +52,12 @@ static int ifuse_getattr(const char *path, struct stat *stbuf) { | |||
| 52 | file = afc_get_file_info(afc, path); | 52 | file = afc_get_file_info(afc, path); |
| 53 | if (!file){ | 53 | if (!file){ |
| 54 | res = -ENOENT; | 54 | res = -ENOENT; |
| 55 | return res; | 55 | } else { |
| 56 | stbuf->st_mode = file->type | 0444; | ||
| 57 | stbuf->st_size = file->size; | ||
| 58 | //stbuf->st_nlink = 2; | ||
| 56 | } | 59 | } |
| 57 | 60 | ||
| 58 | stbuf->st_mode = file->type | 0444; | ||
| 59 | stbuf->st_size = file->size; | ||
| 60 | //stbuf->st_nlink = 2; | ||
| 61 | |||
| 62 | return res; | 61 | return res; |
| 63 | } | 62 | } |
| 64 | 63 | ||
diff --git a/src/initconf.c b/src/initconf.c index 960fb6b..92f8085 100644 --- a/src/initconf.c +++ b/src/initconf.c | |||
| @@ -25,11 +25,34 @@ | |||
| 25 | 25 | ||
| 26 | int debug = 1; | 26 | int debug = 1; |
| 27 | 27 | ||
| 28 | int get_rand(int min, int max) { | ||
| 29 | int retval = (rand() % (max - min)) + min; | ||
| 30 | return retval; | ||
| 31 | } | ||
| 32 | |||
| 33 | char *lockdownd_generate_hostid() { | ||
| 34 | char *hostid = (char*)malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long | ||
| 35 | const char *chars = "ABCDEF0123456789"; | ||
| 36 | srand(time(NULL)); | ||
| 37 | int i = 0; | ||
| 38 | |||
| 39 | for (i = 0; i < 36; i++) { | ||
| 40 | if (i == 8 || i == 13 || i == 18 || i == 23) { | ||
| 41 | hostid[i] = '-'; | ||
| 42 | continue; | ||
| 43 | } else { | ||
| 44 | hostid[i] = chars[get_rand(0,16)]; | ||
| 45 | } | ||
| 46 | } | ||
| 47 | hostid[36] = '\0'; | ||
| 48 | return hostid; | ||
| 49 | } | ||
| 50 | |||
| 28 | int main(int argc, char *argv[]) { | 51 | int main(int argc, char *argv[]) { |
| 29 | 52 | ||
| 30 | gnutls_global_init(); | 53 | gnutls_global_init(); |
| 31 | 54 | ||
| 32 | char* host_id = "29942970-207913891623273984"; | 55 | char* host_id = NULL; //"29942970-207913891623273984" |
| 33 | gnutls_x509_privkey_t root_privkey; | 56 | gnutls_x509_privkey_t root_privkey; |
| 34 | gnutls_x509_privkey_t host_privkey; | 57 | gnutls_x509_privkey_t host_privkey; |
| 35 | 58 | ||
| @@ -44,7 +67,8 @@ int main(int argc, char *argv[]) { | |||
| 44 | 67 | ||
| 45 | /* generate HostID */ | 68 | /* generate HostID */ |
| 46 | //TODO | 69 | //TODO |
| 47 | 70 | host_id = lockdownd_generate_hostid(); | |
| 71 | if (debug) printf("HostID: %s\n", host_id); | ||
| 48 | /* generate keys */ | 72 | /* generate keys */ |
| 49 | gnutls_x509_privkey_generate(root_privkey, GNUTLS_PK_RSA, 2048, 0); | 73 | gnutls_x509_privkey_generate(root_privkey, GNUTLS_PK_RSA, 2048, 0); |
| 50 | gnutls_x509_privkey_generate(host_privkey, GNUTLS_PK_RSA, 2048, 0); | 74 | gnutls_x509_privkey_generate(host_privkey, GNUTLS_PK_RSA, 2048, 0); |
| @@ -62,7 +86,8 @@ int main(int argc, char *argv[]) { | |||
| 62 | gnutls_x509_crt_set_key(host_cert, host_privkey); | 86 | gnutls_x509_crt_set_key(host_cert, host_privkey); |
| 63 | gnutls_x509_crt_set_serial(host_cert, "\x00", 1); | 87 | gnutls_x509_crt_set_serial(host_cert, "\x00", 1); |
| 64 | gnutls_x509_crt_set_version(host_cert, 3); | 88 | gnutls_x509_crt_set_version(host_cert, 3); |
| 65 | gnutls_x509_crt_set_ca_status(host_cert, 1); | 89 | gnutls_x509_crt_set_ca_status(host_cert, 0); |
| 90 | gnutls_x509_crt_set_key_usage(host_cert, GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_DIGITAL_SIGNATURE); | ||
| 66 | gnutls_x509_crt_set_activation_time(host_cert, time(NULL)); | 91 | gnutls_x509_crt_set_activation_time(host_cert, time(NULL)); |
| 67 | gnutls_x509_crt_set_expiration_time(host_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); | 92 | gnutls_x509_crt_set_expiration_time(host_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); |
| 68 | gnutls_x509_crt_sign(host_cert, root_cert, root_privkey); | 93 | gnutls_x509_crt_sign(host_cert, root_cert, root_privkey); |
diff --git a/src/lockdown.c b/src/lockdown.c index 095b2b4..830866d 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -39,7 +39,28 @@ const ASN1_ARRAY_TYPE pkcs1_asn1_tab[]={ | |||
| 39 | {0,0,0} | 39 | {0,0,0} |
| 40 | }; | 40 | }; |
| 41 | 41 | ||
| 42 | int get_rand(int min, int max) { | ||
| 43 | int retval = (rand() % (max - min)) + min; | ||
| 44 | return retval; | ||
| 45 | } | ||
| 42 | 46 | ||
| 47 | char *lockdownd_generate_hostid() { | ||
| 48 | char *hostid = (char*)malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long | ||
| 49 | const char *chars = "ABCDEF0123456789"; | ||
| 50 | srand(time(NULL)); | ||
| 51 | int i = 0; | ||
| 52 | |||
| 53 | for (i = 0; i < 36; i++) { | ||
| 54 | if (i == 8 || i == 13 || i == 18 || i == 23) { | ||
| 55 | hostid[i] = '-'; | ||
| 56 | continue; | ||
| 57 | } else { | ||
| 58 | hostid[i] = chars[get_rand(0,16)]; | ||
| 59 | } | ||
| 60 | } | ||
| 61 | hostid[36] = '\0'; // make it a real string | ||
| 62 | return hostid; | ||
| 63 | } | ||
| 43 | 64 | ||
| 44 | lockdownd_client *new_lockdownd_client(iPhone *phone) { | 65 | lockdownd_client *new_lockdownd_client(iPhone *phone) { |
| 45 | if (!phone) return NULL; | 66 | if (!phone) return NULL; |
| @@ -72,7 +93,7 @@ int lockdownd_recv(lockdownd_client *control, char **dump_data) { | |||
| 72 | char *receive; | 93 | char *receive; |
| 73 | uint32 datalen = 0, bytes = 0; | 94 | uint32 datalen = 0, bytes = 0; |
| 74 | 95 | ||
| 75 | if (!control->in_SSL) bytes = mux_recv(control->iphone, control->connection, (char*)&datalen, sizeof(datalen)); | 96 | if (!control->in_SSL) bytes = mux_recv(control->connection, (char *)&datalen, sizeof(datalen)); |
| 76 | else bytes = gnutls_record_recv(*control->ssl_session, &datalen, sizeof(datalen)); | 97 | else bytes = gnutls_record_recv(*control->ssl_session, &datalen, sizeof(datalen)); |
| 77 | datalen = ntohl(datalen); | 98 | datalen = ntohl(datalen); |
| 78 | 99 | ||
| @@ -120,8 +141,7 @@ int lockdownd_hello(lockdownd_client *control) { | |||
| 120 | char *XML_content; | 141 | char *XML_content; |
| 121 | uint32 length; | 142 | uint32 length; |
| 122 | 143 | ||
| 123 | xmlDocDumpMemory(plist, (xmlChar**)&XML_content, &length); | 144 | xmlDocDumpMemory(plist, (xmlChar **)&XML_content, &length); |
| 124 | |||
| 125 | bytes = lockdownd_send(control, XML_content, length); | 145 | bytes = lockdownd_send(control, XML_content, length); |
| 126 | 146 | ||
| 127 | xmlFree(XML_content); | 147 | xmlFree(XML_content); |
| @@ -135,7 +155,6 @@ int lockdownd_hello(lockdownd_client *control) { | |||
| 135 | if (!xmlStrcmp(dict->name, "dict")) break; | 155 | if (!xmlStrcmp(dict->name, "dict")) break; |
| 136 | } | 156 | } |
| 137 | if (!dict) return 0; | 157 | if (!dict) return 0; |
| 138 | |||
| 139 | dictionary = read_dict_element_strings(dict); | 158 | dictionary = read_dict_element_strings(dict); |
| 140 | xmlFreeDoc(plist); | 159 | xmlFreeDoc(plist); |
| 141 | free(XML_content); | 160 | free(XML_content); |
| @@ -226,6 +245,8 @@ int lockdownd_init(iPhone *phone, lockdownd_client **control) | |||
| 226 | } | 245 | } |
| 227 | 246 | ||
| 228 | host_id = get_host_id(); | 247 | host_id = get_host_id(); |
| 248 | if (!host_id) host_id = lockdownd_generate_hostid(); | ||
| 249 | |||
| 229 | if (!is_device_known(public_key)){ | 250 | if (!is_device_known(public_key)){ |
| 230 | ret = lockdownd_pair_device(*control, public_key, host_id); | 251 | ret = lockdownd_pair_device(*control, public_key, host_id); |
| 231 | } | 252 | } |
| @@ -284,6 +305,12 @@ int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char | |||
| 284 | /* Now get iPhone's answer */ | 305 | /* Now get iPhone's answer */ |
| 285 | bytes = lockdownd_recv(control, &XML_content); | 306 | bytes = lockdownd_recv(control, &XML_content); |
| 286 | 307 | ||
| 308 | if (debug) { | ||
| 309 | printf("lockdown_pair_device: iPhone's response to our pair request:\n"); | ||
| 310 | fwrite(XML_content, 1, bytes, stdout); | ||
| 311 | printf("\n\n"); | ||
| 312 | } | ||
| 313 | |||
| 287 | plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); | 314 | plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); |
| 288 | if (!plist) return 0; | 315 | if (!plist) return 0; |
| 289 | dict = xmlDocGetRootElement(plist); | 316 | dict = xmlDocGetRootElement(plist); |
| @@ -303,15 +330,20 @@ int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char | |||
| 303 | success = 1; | 330 | success = 1; |
| 304 | } | 331 | } |
| 305 | } | 332 | } |
| 306 | 333 | ||
| 307 | if (dictionary) { | 334 | if (dictionary) { |
| 308 | free_dictionary(dictionary); | 335 | free_dictionary(dictionary); |
| 309 | dictionary = NULL; | 336 | dictionary = NULL; |
| 310 | } | 337 | } |
| 311 | 338 | ||
| 312 | /* store public key in config if pairing succeeded */ | 339 | /* store public key in config if pairing succeeded */ |
| 313 | if (success) | 340 | if (success) { |
| 341 | if (debug) printf("lockdownd_pair_device: pair success\n"); | ||
| 314 | store_device_public_key(public_key_b64); | 342 | store_device_public_key(public_key_b64); |
| 343 | ret = 1; | ||
| 344 | } else { | ||
| 345 | if (debug) printf("lockdownd_pair_device: pair failure\n"); | ||
| 346 | } | ||
| 315 | return ret; | 347 | return ret; |
| 316 | } | 348 | } |
| 317 | 349 | ||
| @@ -480,6 +512,7 @@ int lockdownd_start_SSL_session(lockdownd_client *control, const char *HostID) { | |||
| 480 | // Set up GnuTLS... | 512 | // Set up GnuTLS... |
| 481 | //gnutls_anon_client_credentials_t anoncred; | 513 | //gnutls_anon_client_credentials_t anoncred; |
| 482 | gnutls_certificate_credentials_t xcred; | 514 | gnutls_certificate_credentials_t xcred; |
| 515 | |||
| 483 | if (debug) printf("We started the session OK, now trying GnuTLS\n"); | 516 | if (debug) printf("We started the session OK, now trying GnuTLS\n"); |
| 484 | errno = 0; | 517 | errno = 0; |
| 485 | gnutls_global_init(); | 518 | gnutls_global_init(); |
| @@ -703,4 +736,3 @@ int lockdownd_start_service(lockdownd_client *control, const char *service) { | |||
| 703 | 736 | ||
| 704 | return 0; | 737 | return 0; |
| 705 | } | 738 | } |
| 706 | |||
| @@ -57,6 +57,7 @@ int main(int argc, char *argv[]) { | |||
| 57 | } | 57 | } |
| 58 | 58 | ||
| 59 | printf("Now starting SSL.\n"); | 59 | printf("Now starting SSL.\n"); |
| 60 | |||
| 60 | host_id = get_host_id(); | 61 | host_id = get_host_id(); |
| 61 | if (host_id && !lockdownd_start_SSL_session(control, host_id)) { | 62 | if (host_id && !lockdownd_start_SSL_session(control, host_id)) { |
| 62 | printf("Error happened in GnuTLS...\n"); | 63 | printf("Error happened in GnuTLS...\n"); |
diff --git a/src/plist.h b/src/plist.h index a2f558e..db014ca 100644 --- a/src/plist.h +++ b/src/plist.h | |||
| @@ -33,4 +33,5 @@ void free_plist(xmlDocPtr plist); | |||
| 33 | xmlDocPtr new_plist(); | 33 | xmlDocPtr new_plist(); |
| 34 | char **read_dict_element_strings(xmlNode *dict); | 34 | char **read_dict_element_strings(xmlNode *dict); |
| 35 | void free_dictionary(char **dictionary); | 35 | void free_dictionary(char **dictionary); |
| 36 | char **read_dict_element_strings(xmlNode *dict); | ||
| 36 | #endif | 37 | #endif |
diff --git a/src/usbmux.c b/src/usbmux.c index 043f8af..cbae760 100644 --- a/src/usbmux.c +++ b/src/usbmux.c | |||
| @@ -224,7 +224,7 @@ int mux_send(usbmux_connection *connection, const char *data, uint32 datalen) { | |||
| 224 | connection->header->length16 = ntohs(connection->header->length16); | 224 | connection->header->length16 = ntohs(connection->header->length16); |
| 225 | 225 | ||
| 226 | // Now return the bytes. | 226 | // Now return the bytes. |
| 227 | if (bytes < sizeof(*connection)+datalen) { | 227 | if (bytes < sizeof(usbmux_tcp_header)+datalen) { |
| 228 | return -1; // blah | 228 | return -1; // blah |
| 229 | } else { | 229 | } else { |
| 230 | return bytes - 28; // actual length sent. :/ | 230 | return bytes - 28; // actual length sent. :/ |
diff --git a/src/userpref.c b/src/userpref.c index 12ff8f3..1a9ebc9 100644 --- a/src/userpref.c +++ b/src/userpref.c | |||
| @@ -23,6 +23,8 @@ | |||
| 23 | #include <stdio.h> | 23 | #include <stdio.h> |
| 24 | #include <string.h> | 24 | #include <string.h> |
| 25 | #include "userpref.h" | 25 | #include "userpref.h" |
| 26 | #include <string.h> | ||
| 27 | #include <stdio.h> | ||
| 26 | 28 | ||
| 27 | 29 | ||
| 28 | #define LIBIPHONE_CONF_DIR "libiphone" | 30 | #define LIBIPHONE_CONF_DIR "libiphone" |
| @@ -87,7 +89,7 @@ int is_device_known(char* public_key) | |||
| 87 | g_io_channel_read_to_end (keyfile, &stored_key, NULL, NULL); | 89 | g_io_channel_read_to_end (keyfile, &stored_key, NULL, NULL); |
| 88 | 90 | ||
| 89 | /* now compare to input */ | 91 | /* now compare to input */ |
| 90 | if (strcmp(public_key, stored_key) == 2) | 92 | if (strcmp(public_key, stored_key) == 2 || !strcmp(public_key, stored_key)) |
| 91 | ret = 1; | 93 | ret = 1; |
| 92 | g_free(stored_key); | 94 | g_free(stored_key); |
| 93 | g_io_channel_shutdown(keyfile, FALSE, NULL); | 95 | g_io_channel_shutdown(keyfile, FALSE, NULL); |
| @@ -118,6 +120,7 @@ int store_device_public_key(char* public_key) | |||
| 118 | gchar** devices_list = g_key_file_get_string_list (key_file, "Global", "DevicesList", NULL, NULL); | 120 | gchar** devices_list = g_key_file_get_string_list (key_file, "Global", "DevicesList", NULL, NULL); |
| 119 | 121 | ||
| 120 | guint length = 0; | 122 | guint length = 0; |
| 123 | guint wlength = 0; | ||
| 121 | if (devices_list) | 124 | if (devices_list) |
| 122 | g_strv_length(devices_list); | 125 | g_strv_length(devices_list); |
| 123 | g_strfreev(devices_list); | 126 | g_strfreev(devices_list); |
| @@ -127,8 +130,9 @@ int store_device_public_key(char* public_key) | |||
| 127 | 130 | ||
| 128 | gchar* device_file = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, dev_file, NULL); | 131 | gchar* device_file = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, dev_file, NULL); |
| 129 | GIOChannel* file = g_io_channel_new_file (device_file, "w", NULL); | 132 | GIOChannel* file = g_io_channel_new_file (device_file, "w", NULL); |
| 130 | g_io_channel_write_chars (file, public_key, length, NULL, NULL); | 133 | wlength = strlen(public_key); // why this wasn't discovered before... ugh |
| 131 | g_io_channel_shutdown(file, FALSE, NULL); | 134 | g_io_channel_write_chars (file, public_key, wlength, NULL, NULL); |
| 135 | g_io_channel_shutdown(file, TRUE, NULL); | ||
| 132 | 136 | ||
| 133 | /* append device to list */ | 137 | /* append device to list */ |
| 134 | gchar** new_devices_list = (gchar**)g_malloc(sizeof(gchar*)* (length + 1)); | 138 | gchar** new_devices_list = (gchar**)g_malloc(sizeof(gchar*)* (length + 1)); |
| @@ -145,7 +149,7 @@ int store_device_public_key(char* public_key) | |||
| 145 | gchar* buf = g_key_file_to_data (key_file, &length,NULL); | 149 | gchar* buf = g_key_file_to_data (key_file, &length,NULL); |
| 146 | GIOChannel* file = g_io_channel_new_file (config_file, "w", NULL); | 150 | GIOChannel* file = g_io_channel_new_file (config_file, "w", NULL); |
| 147 | g_io_channel_write_chars (file, buf, length, NULL, NULL); | 151 | g_io_channel_write_chars (file, buf, length, NULL, NULL); |
| 148 | g_io_channel_shutdown(file, FALSE, NULL); | 152 | g_io_channel_shutdown(file, TRUE, NULL); |
| 149 | g_key_file_free(key_file); | 153 | g_key_file_free(key_file); |
| 150 | } | 154 | } |
| 151 | 155 | ||
| @@ -215,6 +219,7 @@ int init_config_file(char* host_id, gnutls_datum_t* root_key, gnutls_datum_t* ho | |||
| 215 | GKeyFile* key_file = g_key_file_new (); | 219 | GKeyFile* key_file = g_key_file_new (); |
| 216 | 220 | ||
| 217 | /* store in config file */ | 221 | /* store in config file */ |
| 222 | if (debug) printf("init_config_file setting hostID to %s\n", host_id); | ||
| 218 | g_key_file_set_value (key_file, "Global", "HostID", host_id); | 223 | g_key_file_set_value (key_file, "Global", "HostID", host_id); |
| 219 | 224 | ||
| 220 | /* write config file on disk */ | 225 | /* write config file on disk */ |
| @@ -222,7 +227,7 @@ int init_config_file(char* host_id, gnutls_datum_t* root_key, gnutls_datum_t* ho | |||
| 222 | gchar* buf = g_key_file_to_data (key_file, &length,NULL); | 227 | gchar* buf = g_key_file_to_data (key_file, &length,NULL); |
| 223 | GIOChannel* file = g_io_channel_new_file (config_file, "w", NULL); | 228 | GIOChannel* file = g_io_channel_new_file (config_file, "w", NULL); |
| 224 | g_io_channel_write_chars (file, buf, length, NULL, NULL); | 229 | g_io_channel_write_chars (file, buf, length, NULL, NULL); |
| 225 | g_io_channel_shutdown(file, FALSE, NULL); | 230 | g_io_channel_shutdown(file, TRUE, NULL); |
| 226 | 231 | ||
| 227 | g_key_file_free(key_file); | 232 | g_key_file_free(key_file); |
| 228 | 233 | ||
