From 25e85bf5362b6f4c1878665c6037fdbfdc25c155 Mon Sep 17 00:00:00 2001 From: Matt Colyer Date: Tue, 5 Aug 2008 23:25:35 -0700 Subject: Zack's final changes to the pairing. --- src/ifuse.c | 9 ++++----- src/initconf.c | 31 ++++++++++++++++++++++++++++--- src/lockdown.c | 46 +++++++++++++++++++++++++++++++++++++++------- src/main.c | 1 + src/plist.h | 1 + src/usbmux.c | 2 +- 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) { file = afc_get_file_info(afc, path); if (!file){ res = -ENOENT; - return res; + } else { + stbuf->st_mode = file->type | 0444; + stbuf->st_size = file->size; + //stbuf->st_nlink = 2; } - stbuf->st_mode = file->type | 0444; - stbuf->st_size = file->size; - //stbuf->st_nlink = 2; - return res; } 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 @@ int debug = 1; +int get_rand(int min, int max) { + int retval = (rand() % (max - min)) + min; + return retval; +} + +char *lockdownd_generate_hostid() { + char *hostid = (char*)malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long + const char *chars = "ABCDEF0123456789"; + srand(time(NULL)); + int i = 0; + + for (i = 0; i < 36; i++) { + if (i == 8 || i == 13 || i == 18 || i == 23) { + hostid[i] = '-'; + continue; + } else { + hostid[i] = chars[get_rand(0,16)]; + } + } + hostid[36] = '\0'; + return hostid; +} + int main(int argc, char *argv[]) { gnutls_global_init(); - char* host_id = "29942970-207913891623273984"; + char* host_id = NULL; //"29942970-207913891623273984" gnutls_x509_privkey_t root_privkey; gnutls_x509_privkey_t host_privkey; @@ -44,7 +67,8 @@ int main(int argc, char *argv[]) { /* generate HostID */ //TODO - + host_id = lockdownd_generate_hostid(); + if (debug) printf("HostID: %s\n", host_id); /* generate keys */ gnutls_x509_privkey_generate(root_privkey, GNUTLS_PK_RSA, 2048, 0); gnutls_x509_privkey_generate(host_privkey, GNUTLS_PK_RSA, 2048, 0); @@ -62,7 +86,8 @@ int main(int argc, char *argv[]) { gnutls_x509_crt_set_key(host_cert, host_privkey); gnutls_x509_crt_set_serial(host_cert, "\x00", 1); gnutls_x509_crt_set_version(host_cert, 3); - gnutls_x509_crt_set_ca_status(host_cert, 1); + gnutls_x509_crt_set_ca_status(host_cert, 0); + gnutls_x509_crt_set_key_usage(host_cert, GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_DIGITAL_SIGNATURE); gnutls_x509_crt_set_activation_time(host_cert, time(NULL)); gnutls_x509_crt_set_expiration_time(host_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); 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[]={ {0,0,0} }; +int get_rand(int min, int max) { + int retval = (rand() % (max - min)) + min; + return retval; +} +char *lockdownd_generate_hostid() { + char *hostid = (char*)malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long + const char *chars = "ABCDEF0123456789"; + srand(time(NULL)); + int i = 0; + + for (i = 0; i < 36; i++) { + if (i == 8 || i == 13 || i == 18 || i == 23) { + hostid[i] = '-'; + continue; + } else { + hostid[i] = chars[get_rand(0,16)]; + } + } + hostid[36] = '\0'; // make it a real string + return hostid; +} lockdownd_client *new_lockdownd_client(iPhone *phone) { if (!phone) return NULL; @@ -72,7 +93,7 @@ int lockdownd_recv(lockdownd_client *control, char **dump_data) { char *receive; uint32 datalen = 0, bytes = 0; - if (!control->in_SSL) bytes = mux_recv(control->iphone, control->connection, (char*)&datalen, sizeof(datalen)); + if (!control->in_SSL) bytes = mux_recv(control->connection, (char *)&datalen, sizeof(datalen)); else bytes = gnutls_record_recv(*control->ssl_session, &datalen, sizeof(datalen)); datalen = ntohl(datalen); @@ -120,8 +141,7 @@ int lockdownd_hello(lockdownd_client *control) { char *XML_content; uint32 length; - xmlDocDumpMemory(plist, (xmlChar**)&XML_content, &length); - + xmlDocDumpMemory(plist, (xmlChar **)&XML_content, &length); bytes = lockdownd_send(control, XML_content, length); xmlFree(XML_content); @@ -135,7 +155,6 @@ int lockdownd_hello(lockdownd_client *control) { if (!xmlStrcmp(dict->name, "dict")) break; } if (!dict) return 0; - dictionary = read_dict_element_strings(dict); xmlFreeDoc(plist); free(XML_content); @@ -226,6 +245,8 @@ int lockdownd_init(iPhone *phone, lockdownd_client **control) } host_id = get_host_id(); + if (!host_id) host_id = lockdownd_generate_hostid(); + if (!is_device_known(public_key)){ ret = lockdownd_pair_device(*control, public_key, host_id); } @@ -284,6 +305,12 @@ int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char /* Now get iPhone's answer */ bytes = lockdownd_recv(control, &XML_content); + if (debug) { + printf("lockdown_pair_device: iPhone's response to our pair request:\n"); + fwrite(XML_content, 1, bytes, stdout); + printf("\n\n"); + } + plist = xmlReadMemory(XML_content, bytes, NULL, NULL, 0); if (!plist) return 0; dict = xmlDocGetRootElement(plist); @@ -303,15 +330,20 @@ int lockdownd_pair_device(lockdownd_client *control, char *public_key_b64, char success = 1; } } - + if (dictionary) { free_dictionary(dictionary); dictionary = NULL; } /* store public key in config if pairing succeeded */ - if (success) + if (success) { + if (debug) printf("lockdownd_pair_device: pair success\n"); store_device_public_key(public_key_b64); + ret = 1; + } else { + if (debug) printf("lockdownd_pair_device: pair failure\n"); + } return ret; } @@ -480,6 +512,7 @@ int lockdownd_start_SSL_session(lockdownd_client *control, const char *HostID) { // Set up GnuTLS... //gnutls_anon_client_credentials_t anoncred; gnutls_certificate_credentials_t xcred; + if (debug) printf("We started the session OK, now trying GnuTLS\n"); errno = 0; gnutls_global_init(); @@ -703,4 +736,3 @@ int lockdownd_start_service(lockdownd_client *control, const char *service) { return 0; } - diff --git a/src/main.c b/src/main.c index 1efc228..ea7c390 100644 --- a/src/main.c +++ b/src/main.c @@ -57,6 +57,7 @@ int main(int argc, char *argv[]) { } printf("Now starting SSL.\n"); + host_id = get_host_id(); if (host_id && !lockdownd_start_SSL_session(control, host_id)) { 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); xmlDocPtr new_plist(); char **read_dict_element_strings(xmlNode *dict); void free_dictionary(char **dictionary); +char **read_dict_element_strings(xmlNode *dict); #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) { connection->header->length16 = ntohs(connection->header->length16); // Now return the bytes. - if (bytes < sizeof(*connection)+datalen) { + if (bytes < sizeof(usbmux_tcp_header)+datalen) { return -1; // blah } else { 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 @@ #include #include #include "userpref.h" +#include +#include #define LIBIPHONE_CONF_DIR "libiphone" @@ -87,7 +89,7 @@ int is_device_known(char* public_key) g_io_channel_read_to_end (keyfile, &stored_key, NULL, NULL); /* now compare to input */ - if (strcmp(public_key, stored_key) == 2) + if (strcmp(public_key, stored_key) == 2 || !strcmp(public_key, stored_key)) ret = 1; g_free(stored_key); g_io_channel_shutdown(keyfile, FALSE, NULL); @@ -118,6 +120,7 @@ int store_device_public_key(char* public_key) gchar** devices_list = g_key_file_get_string_list (key_file, "Global", "DevicesList", NULL, NULL); guint length = 0; + guint wlength = 0; if (devices_list) g_strv_length(devices_list); g_strfreev(devices_list); @@ -127,8 +130,9 @@ int store_device_public_key(char* public_key) gchar* device_file = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, dev_file, NULL); GIOChannel* file = g_io_channel_new_file (device_file, "w", NULL); - g_io_channel_write_chars (file, public_key, length, NULL, NULL); - g_io_channel_shutdown(file, FALSE, NULL); + wlength = strlen(public_key); // why this wasn't discovered before... ugh + g_io_channel_write_chars (file, public_key, wlength, NULL, NULL); + g_io_channel_shutdown(file, TRUE, NULL); /* append device to list */ gchar** new_devices_list = (gchar**)g_malloc(sizeof(gchar*)* (length + 1)); @@ -145,7 +149,7 @@ int store_device_public_key(char* public_key) gchar* buf = g_key_file_to_data (key_file, &length,NULL); GIOChannel* file = g_io_channel_new_file (config_file, "w", NULL); g_io_channel_write_chars (file, buf, length, NULL, NULL); - g_io_channel_shutdown(file, FALSE, NULL); + g_io_channel_shutdown(file, TRUE, NULL); g_key_file_free(key_file); } @@ -215,6 +219,7 @@ int init_config_file(char* host_id, gnutls_datum_t* root_key, gnutls_datum_t* ho GKeyFile* key_file = g_key_file_new (); /* store in config file */ + if (debug) printf("init_config_file setting hostID to %s\n", host_id); g_key_file_set_value (key_file, "Global", "HostID", host_id); /* 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 gchar* buf = g_key_file_to_data (key_file, &length,NULL); GIOChannel* file = g_io_channel_new_file (config_file, "w", NULL); g_io_channel_write_chars (file, buf, length, NULL, NULL); - g_io_channel_shutdown(file, FALSE, NULL); + g_io_channel_shutdown(file, TRUE, NULL); g_key_file_free(key_file); -- cgit v1.1-32-gdbae