diff options
| author | 2009-07-25 01:39:35 +0200 | |
|---|---|---|
| committer | 2009-07-25 01:39:35 +0200 | |
| commit | 66695e6b7db9457d5ecfe6f4f6624dc195e5274d (patch) | |
| tree | ab5c432974cc2c54b5554b050879a2e3975ae6b8 | |
| parent | 028646335acca403cc8a601d77c2272e077445e0 (diff) | |
| download | libimobiledevice-66695e6b7db9457d5ecfe6f4f6624dc195e5274d.tar.gz libimobiledevice-66695e6b7db9457d5ecfe6f4f6624dc195e5274d.tar.bz2 | |
Improve API of userpref system
| -rw-r--r-- | src/lockdown.c | 58 | ||||
| -rw-r--r-- | src/userpref.c | 161 | ||||
| -rw-r--r-- | src/userpref.h | 22 |
3 files changed, 131 insertions, 110 deletions
diff --git a/src/lockdown.c b/src/lockdown.c index 3d2b04c..757a94a 100644 --- a/src/lockdown.c +++ b/src/lockdown.c | |||
| @@ -19,10 +19,6 @@ | |||
| 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA | 19 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA |
| 20 | */ | 20 | */ |
| 21 | 21 | ||
| 22 | #include "utils.h" | ||
| 23 | #include "iphone.h" | ||
| 24 | #include "lockdown.h" | ||
| 25 | #include "userpref.h" | ||
| 26 | #include <arpa/inet.h> | 22 | #include <arpa/inet.h> |
| 27 | #include <errno.h> | 23 | #include <errno.h> |
| 28 | #include <string.h> | 24 | #include <string.h> |
| @@ -30,9 +26,13 @@ | |||
| 30 | #include <glib.h> | 26 | #include <glib.h> |
| 31 | #include <libtasn1.h> | 27 | #include <libtasn1.h> |
| 32 | #include <gnutls/x509.h> | 28 | #include <gnutls/x509.h> |
| 33 | |||
| 34 | #include <plist/plist.h> | 29 | #include <plist/plist.h> |
| 35 | 30 | ||
| 31 | #include "lockdown.h" | ||
| 32 | #include "iphone.h" | ||
| 33 | #include "utils.h" | ||
| 34 | #include "userpref.h" | ||
| 35 | |||
| 36 | #define RESULT_SUCCESS 0 | 36 | #define RESULT_SUCCESS 0 |
| 37 | #define RESULT_FAILURE 1 | 37 | #define RESULT_FAILURE 1 |
| 38 | 38 | ||
| @@ -680,12 +680,12 @@ iphone_error_t lockdownd_new_client(iphone_device_t device, lockdownd_client_t * | |||
| 680 | } | 680 | } |
| 681 | log_debug_msg("%s: device uuid: %s\n", __func__, uuid); | 681 | log_debug_msg("%s: device uuid: %s\n", __func__, uuid); |
| 682 | 682 | ||
| 683 | host_id = get_host_id(); | 683 | userpref_get_host_id(&host_id); |
| 684 | if (IPHONE_E_SUCCESS == ret && !host_id) { | 684 | if (IPHONE_E_SUCCESS == ret && !host_id) { |
| 685 | ret = IPHONE_E_INVALID_CONF; | 685 | ret = IPHONE_E_INVALID_CONF; |
| 686 | } | 686 | } |
| 687 | 687 | ||
| 688 | if (IPHONE_E_SUCCESS == ret && !is_device_known(uuid)) | 688 | if (IPHONE_E_SUCCESS == ret && !userpref_has_device_public_key(uuid)) |
| 689 | ret = lockdownd_pair(client_loc, uuid, host_id); | 689 | ret = lockdownd_pair(client_loc, uuid, host_id); |
| 690 | 690 | ||
| 691 | if (uuid) { | 691 | if (uuid) { |
| @@ -780,7 +780,7 @@ iphone_error_t lockdownd_pair(lockdownd_client_t client, char *uid, char *host_i | |||
| 780 | /* store public key in config if pairing succeeded */ | 780 | /* store public key in config if pairing succeeded */ |
| 781 | if (ret == IPHONE_E_SUCCESS) { | 781 | if (ret == IPHONE_E_SUCCESS) { |
| 782 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pair success\n", __func__); | 782 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pair success\n", __func__); |
| 783 | store_device_public_key(uuid, public_key); | 783 | userpref_set_device_public_key(uuid, public_key); |
| 784 | } else { | 784 | } else { |
| 785 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pair failure\n", __func__); | 785 | log_dbg_msg(DBGMASK_LOCKDOWND, "%s: pair failure\n", __func__); |
| 786 | ret = IPHONE_E_PAIRING_FAILED; | 786 | ret = IPHONE_E_PAIRING_FAILED; |
| @@ -875,6 +875,7 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t | |||
| 875 | if (!public_key.data || !odevice_cert || !ohost_cert || !oroot_cert) | 875 | if (!public_key.data || !odevice_cert || !ohost_cert || !oroot_cert) |
| 876 | return IPHONE_E_INVALID_ARG; | 876 | return IPHONE_E_INVALID_ARG; |
| 877 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 877 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 878 | userpref_error_t uret = USERPREF_E_UNKNOWN_ERROR; | ||
| 878 | 879 | ||
| 879 | gnutls_datum_t modulus = { NULL, 0 }; | 880 | gnutls_datum_t modulus = { NULL, 0 }; |
| 880 | gnutls_datum_t exponent = { NULL, 0 }; | 881 | gnutls_datum_t exponent = { NULL, 0 }; |
| @@ -932,10 +933,9 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t | |||
| 932 | gnutls_x509_privkey_init(&root_privkey); | 933 | gnutls_x509_privkey_init(&root_privkey); |
| 933 | gnutls_x509_privkey_init(&host_privkey); | 934 | gnutls_x509_privkey_init(&host_privkey); |
| 934 | 935 | ||
| 935 | ret = get_keys_and_certs(root_privkey, root_cert, host_privkey, host_cert); | 936 | uret = userpref_get_keys_and_certs(root_privkey, root_cert, host_privkey, host_cert); |
| 936 | |||
| 937 | if (IPHONE_E_SUCCESS == ret) { | ||
| 938 | 937 | ||
| 938 | if (USERPREF_E_SUCCESS == uret) { | ||
| 939 | /* generate device certificate */ | 939 | /* generate device certificate */ |
| 940 | gnutls_x509_crt_set_key(dev_cert, fake_privkey); | 940 | gnutls_x509_crt_set_key(dev_cert, fake_privkey); |
| 941 | gnutls_x509_crt_set_serial(dev_cert, "\x00", 1); | 941 | gnutls_x509_crt_set_serial(dev_cert, "\x00", 1); |
| @@ -955,7 +955,9 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t | |||
| 955 | gnutls_datum_t pem_root_cert = { NULL, 0 }; | 955 | gnutls_datum_t pem_root_cert = { NULL, 0 }; |
| 956 | gnutls_datum_t pem_host_cert = { NULL, 0 }; | 956 | gnutls_datum_t pem_host_cert = { NULL, 0 }; |
| 957 | 957 | ||
| 958 | if ( IPHONE_E_SUCCESS == get_certs_as_pem(&pem_root_cert, &pem_host_cert) ) { | 958 | uret = userpref_get_certs_as_pem(&pem_root_cert, &pem_host_cert); |
| 959 | |||
| 960 | if (USERPREF_E_SUCCESS == uret) { | ||
| 959 | /* copy buffer for output */ | 961 | /* copy buffer for output */ |
| 960 | odevice_cert->data = malloc(dev_pem.size); | 962 | odevice_cert->data = malloc(dev_pem.size); |
| 961 | memcpy(odevice_cert->data, dev_pem.data, dev_pem.size); | 963 | memcpy(odevice_cert->data, dev_pem.data, dev_pem.size); |
| @@ -974,6 +976,19 @@ iphone_error_t lockdownd_gen_pair_cert(gnutls_datum_t public_key, gnutls_datum_t | |||
| 974 | } | 976 | } |
| 975 | } | 977 | } |
| 976 | } | 978 | } |
| 979 | |||
| 980 | switch(uret) { | ||
| 981 | case USERPREF_E_INVALID_ARG: | ||
| 982 | ret = IPHONE_E_INVALID_ARG; | ||
| 983 | break; | ||
| 984 | case USERPREF_E_INVALID_CONF: | ||
| 985 | ret = IPHONE_E_INVALID_CONF; | ||
| 986 | break; | ||
| 987 | case USERPREF_E_SSL_ERROR: | ||
| 988 | ret = IPHONE_E_SSL_ERROR; | ||
| 989 | default: | ||
| 990 | break; | ||
| 991 | } | ||
| 977 | } | 992 | } |
| 978 | } | 993 | } |
| 979 | 994 | ||
| @@ -1026,12 +1041,14 @@ iphone_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char | |||
| 1026 | plist_get_string_val(error_node, &error); | 1041 | plist_get_string_val(error_node, &error); |
| 1027 | 1042 | ||
| 1028 | if (!strcmp(error, "InvalidHostID")) { | 1043 | if (!strcmp(error, "InvalidHostID")) { |
| 1029 | //hostid is unknown. Pair and try again | 1044 | /* hostid is unknown. Pair and try again */ |
| 1030 | char *uid = NULL; | 1045 | char *uuid = NULL; |
| 1031 | char* host_id = get_host_id(); | 1046 | char *host_id = NULL; |
| 1032 | if (IPHONE_E_SUCCESS == lockdownd_get_device_uid(client, &uid) ) { | 1047 | userpref_get_host_id(&host_id); |
| 1033 | if (IPHONE_E_SUCCESS == lockdownd_pair(client, uid, host_id) ) { | 1048 | |
| 1034 | //start session again | 1049 | if (IPHONE_E_SUCCESS == lockdownd_get_device_uuid(client, &uuid) ) { |
| 1050 | if (IPHONE_E_SUCCESS == lockdownd_pair(client, uuid, host_id) ) { | ||
| 1051 | /* start session again */ | ||
| 1035 | plist_free(dict); | 1052 | plist_free(dict); |
| 1036 | dict = plist_new_dict(); | 1053 | dict = plist_new_dict(); |
| 1037 | plist_add_sub_key_el(dict, "HostID"); | 1054 | plist_add_sub_key_el(dict, "HostID"); |
| @@ -1046,7 +1063,7 @@ iphone_error_t lockdownd_start_ssl_session(lockdownd_client_t client, const char | |||
| 1046 | ret = lockdownd_recv(client, &dict); | 1063 | ret = lockdownd_recv(client, &dict); |
| 1047 | } | 1064 | } |
| 1048 | } | 1065 | } |
| 1049 | free(uid); | 1066 | free(uuid); |
| 1050 | free(host_id); | 1067 | free(host_id); |
| 1051 | } | 1068 | } |
| 1052 | free(error); | 1069 | free(error); |
| @@ -1220,7 +1237,8 @@ iphone_error_t lockdownd_start_service(lockdownd_client_t client, const char *se | |||
| 1220 | if (!client || !service || !port) | 1237 | if (!client || !service || !port) |
| 1221 | return IPHONE_E_INVALID_ARG; | 1238 | return IPHONE_E_INVALID_ARG; |
| 1222 | 1239 | ||
| 1223 | char *host_id = get_host_id(); | 1240 | char *host_id = NULL; |
| 1241 | userpref_get_host_id(&host_id); | ||
| 1224 | if (!host_id) | 1242 | if (!host_id) |
| 1225 | return IPHONE_E_INVALID_CONF; | 1243 | return IPHONE_E_INVALID_CONF; |
| 1226 | if (!client->in_SSL && !lockdownd_start_ssl_session(client, host_id)) | 1244 | if (!client->in_SSL && !lockdownd_start_ssl_session(client, host_id)) |
diff --git a/src/userpref.c b/src/userpref.c index f7ddaeb..4b6dd98 100644 --- a/src/userpref.c +++ b/src/userpref.c | |||
| @@ -22,6 +22,7 @@ | |||
| 22 | #include <glib.h> | 22 | #include <glib.h> |
| 23 | #include <glib/gprintf.h> | 23 | #include <glib/gprintf.h> |
| 24 | #include <stdio.h> | 24 | #include <stdio.h> |
| 25 | #include <stdint.h> | ||
| 25 | #include <stdlib.h> | 26 | #include <stdlib.h> |
| 26 | #include <string.h> | 27 | #include <string.h> |
| 27 | #include <gnutls/gnutls.h> | 28 | #include <gnutls/gnutls.h> |
| @@ -42,7 +43,7 @@ | |||
| 42 | 43 | ||
| 43 | /** Creates a freedesktop compatible configuration directory for libiphone. | 44 | /** Creates a freedesktop compatible configuration directory for libiphone. |
| 44 | */ | 45 | */ |
| 45 | static void create_config_dir(void) | 46 | static void userpref_create_config_dir(void) |
| 46 | { | 47 | { |
| 47 | gchar *config_dir = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, NULL); | 48 | gchar *config_dir = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, NULL); |
| 48 | 49 | ||
| @@ -62,9 +63,10 @@ static int get_rand(int min, int max) | |||
| 62 | * | 63 | * |
| 63 | * @return A null terminated string containing a valid HostID. | 64 | * @return A null terminated string containing a valid HostID. |
| 64 | */ | 65 | */ |
| 65 | static char *lockdownd_generate_hostid() | 66 | static char *userpref_generate_host_id() |
| 66 | { | 67 | { |
| 67 | char *hostid = (char *) malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long | 68 | /* HostID's are just UUID's, and UUID's are 36 characters long */ |
| 69 | char *hostid = (char *) malloc(sizeof(char) * 37); | ||
| 68 | const char *chars = "ABCDEF0123456789"; | 70 | const char *chars = "ABCDEF0123456789"; |
| 69 | srand(time(NULL)); | 71 | srand(time(NULL)); |
| 70 | int i = 0; | 72 | int i = 0; |
| @@ -77,7 +79,8 @@ static char *lockdownd_generate_hostid() | |||
| 77 | hostid[i] = chars[get_rand(0, 16)]; | 79 | hostid[i] = chars[get_rand(0, 16)]; |
| 78 | } | 80 | } |
| 79 | } | 81 | } |
| 80 | hostid[36] = '\0'; // make it a real string | 82 | /* make it a real string */ |
| 83 | hostid[36] = '\0'; | ||
| 81 | return hostid; | 84 | return hostid; |
| 82 | } | 85 | } |
| 83 | 86 | ||
| @@ -85,7 +88,7 @@ static char *lockdownd_generate_hostid() | |||
| 85 | * | 88 | * |
| 86 | * @param host_id A null terminated string containing a valid HostID. | 89 | * @param host_id A null terminated string containing a valid HostID. |
| 87 | */ | 90 | */ |
| 88 | static int write_host_id(char *host_id) | 91 | static int userpref_set_host_id(char *host_id) |
| 89 | { | 92 | { |
| 90 | GKeyFile *key_file; | 93 | GKeyFile *key_file; |
| 91 | gsize length; | 94 | gsize length; |
| @@ -96,7 +99,7 @@ static int write_host_id(char *host_id) | |||
| 96 | return 0; | 99 | return 0; |
| 97 | 100 | ||
| 98 | /* Make sure config directory exists */ | 101 | /* Make sure config directory exists */ |
| 99 | create_config_dir(); | 102 | userpref_create_config_dir(); |
| 100 | 103 | ||
| 101 | /* Now parse file to get the HostID */ | 104 | /* Now parse file to get the HostID */ |
| 102 | key_file = g_key_file_new(); | 105 | key_file = g_key_file_new(); |
| @@ -125,9 +128,8 @@ static int write_host_id(char *host_id) | |||
| 125 | * | 128 | * |
| 126 | * @return The string containing the HostID or NULL | 129 | * @return The string containing the HostID or NULL |
| 127 | */ | 130 | */ |
| 128 | char *get_host_id(void) | 131 | void userpref_get_host_id(char **host_id) |
| 129 | { | 132 | { |
| 130 | char *host_id = NULL; | ||
| 131 | gchar *config_file; | 133 | gchar *config_file; |
| 132 | GKeyFile *key_file; | 134 | GKeyFile *key_file; |
| 133 | gchar *loc_host_id; | 135 | gchar *loc_host_id; |
| @@ -140,20 +142,19 @@ char *get_host_id(void) | |||
| 140 | if (g_key_file_load_from_file(key_file, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL)) { | 142 | if (g_key_file_load_from_file(key_file, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL)) { |
| 141 | loc_host_id = g_key_file_get_value(key_file, "Global", "HostID", NULL); | 143 | loc_host_id = g_key_file_get_value(key_file, "Global", "HostID", NULL); |
| 142 | if (loc_host_id) | 144 | if (loc_host_id) |
| 143 | host_id = strdup((char *) loc_host_id); | 145 | *host_id = strdup((char *) loc_host_id); |
| 144 | g_free(loc_host_id); | 146 | g_free(loc_host_id); |
| 145 | } | 147 | } |
| 146 | g_key_file_free(key_file); | 148 | g_key_file_free(key_file); |
| 147 | g_free(config_file); | 149 | g_free(config_file); |
| 148 | 150 | ||
| 149 | if (!host_id) { | 151 | if (!host_id) { |
| 150 | //no config, generate host_id | 152 | /* no config, generate host_id */ |
| 151 | host_id = lockdownd_generate_hostid(); | 153 | *host_id = userpref_generate_host_id(); |
| 152 | write_host_id(host_id); | 154 | userpref_set_host_id(*host_id); |
| 153 | } | 155 | } |
| 154 | 156 | ||
| 155 | log_debug_msg("%s: Using %s as HostID\n", __func__, host_id); | 157 | log_debug_msg("%s: Using %s as HostID\n", __func__, *host_id); |
| 156 | return host_id; | ||
| 157 | } | 158 | } |
| 158 | 159 | ||
| 159 | /** Determines whether this iPhone has been connected to this system before. | 160 | /** Determines whether this iPhone has been connected to this system before. |
| @@ -163,13 +164,13 @@ char *get_host_id(void) | |||
| 163 | * @return 1 if the iPhone has been connected previously to this configuration | 164 | * @return 1 if the iPhone has been connected previously to this configuration |
| 164 | * or 0 otherwise. | 165 | * or 0 otherwise. |
| 165 | */ | 166 | */ |
| 166 | int is_device_known(char *uid) | 167 | int userpref_has_device_public_key(char *uuid) |
| 167 | { | 168 | { |
| 168 | int ret = 0; | 169 | int ret = 0; |
| 169 | gchar *config_file; | 170 | gchar *config_file; |
| 170 | 171 | ||
| 171 | /* first get config file */ | 172 | /* first get config file */ |
| 172 | gchar *device_file = g_strconcat(uid, ".pem", NULL); | 173 | gchar *device_file = g_strconcat(uuid, ".pem", NULL); |
| 173 | config_file = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); | 174 | config_file = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); |
| 174 | if (g_file_test(config_file, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) | 175 | if (g_file_test(config_file, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) |
| 175 | ret = 1; | 176 | ret = 1; |
| @@ -186,17 +187,19 @@ int is_device_known(char *uid) | |||
| 186 | * @return 1 on success and 0 if no public key is given or if it has already | 187 | * @return 1 on success and 0 if no public key is given or if it has already |
| 187 | * been marked as connected previously. | 188 | * been marked as connected previously. |
| 188 | */ | 189 | */ |
| 189 | int store_device_public_key(char *uid, gnutls_datum_t public_key) | 190 | userpref_error_t userpref_set_device_public_key(char *uuid, gnutls_datum_t public_key) |
| 190 | { | 191 | { |
| 191 | 192 | if (NULL == public_key.data) | |
| 192 | if (NULL == public_key.data || is_device_known(uid)) | 193 | return USERPREF_E_INVALID_ARG; |
| 193 | return 0; | 194 | |
| 195 | if (userpref_has_device_public_key(uuid)) | ||
| 196 | return USERPREF_E_SUCCESS; | ||
| 194 | 197 | ||
| 195 | /* ensure config directory exists */ | 198 | /* ensure config directory exists */ |
| 196 | create_config_dir(); | 199 | userpref_create_config_dir(); |
| 197 | 200 | ||
| 198 | /* build file path */ | 201 | /* build file path */ |
| 199 | gchar *device_file = g_strconcat(uid, ".pem", NULL); | 202 | gchar *device_file = g_strconcat(uuid, ".pem", NULL); |
| 200 | gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); | 203 | gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); |
| 201 | 204 | ||
| 202 | /* store file */ | 205 | /* store file */ |
| @@ -205,7 +208,8 @@ int store_device_public_key(char *uid, gnutls_datum_t public_key) | |||
| 205 | fclose(pFile); | 208 | fclose(pFile); |
| 206 | g_free(pem); | 209 | g_free(pem); |
| 207 | g_free(device_file); | 210 | g_free(device_file); |
| 208 | return 1; | 211 | |
| 212 | return USERPREF_E_SUCCESS; | ||
| 209 | } | 213 | } |
| 210 | 214 | ||
| 211 | /** Private function which reads the given file into a gnutls structure. | 215 | /** Private function which reads the given file into a gnutls structure. |
| @@ -215,7 +219,7 @@ int store_device_public_key(char *uid, gnutls_datum_t public_key) | |||
| 215 | * | 219 | * |
| 216 | * @return 1 if the file contents where read successfully and 0 otherwise. | 220 | * @return 1 if the file contents where read successfully and 0 otherwise. |
| 217 | */ | 221 | */ |
| 218 | static int read_file_in_confdir(const char *file, gnutls_datum_t * data) | 222 | static int userpref_get_file_contents(const char *file, gnutls_datum_t * data) |
| 219 | { | 223 | { |
| 220 | gboolean success; | 224 | gboolean success; |
| 221 | gsize size; | 225 | gsize size; |
| @@ -237,17 +241,17 @@ static int read_file_in_confdir(const char *file, gnutls_datum_t * data) | |||
| 237 | return success; | 241 | return success; |
| 238 | } | 242 | } |
| 239 | 243 | ||
| 240 | |||
| 241 | /** Private function which generate private keys and certificates. | 244 | /** Private function which generate private keys and certificates. |
| 242 | * | 245 | * |
| 243 | * @return IPHONE_E_SUCCESS if keys were successfully generated. | 246 | * @return 1 if keys were successfully generated, 0 otherwise |
| 244 | */ | 247 | */ |
| 245 | static iphone_error_t gen_keys_and_cert(void) | 248 | static userpref_error_t userpref_gen_keys_and_cert(void) |
| 246 | { | 249 | { |
| 247 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; | 250 | userpref_error_t ret = USERPREF_E_SSL_ERROR; |
| 251 | |||
| 248 | gnutls_x509_privkey_t root_privkey; | 252 | gnutls_x509_privkey_t root_privkey; |
| 249 | gnutls_x509_privkey_t host_privkey; | ||
| 250 | gnutls_x509_crt_t root_cert; | 253 | gnutls_x509_crt_t root_cert; |
| 254 | gnutls_x509_privkey_t host_privkey; | ||
| 251 | gnutls_x509_crt_t host_cert; | 255 | gnutls_x509_crt_t host_cert; |
| 252 | 256 | ||
| 253 | gnutls_global_deinit(); | 257 | gnutls_global_deinit(); |
| @@ -311,14 +315,14 @@ static iphone_error_t gen_keys_and_cert(void) | |||
| 311 | 315 | ||
| 312 | if (NULL != root_cert_pem.data && 0 != root_cert_pem.size && | 316 | if (NULL != root_cert_pem.data && 0 != root_cert_pem.size && |
| 313 | NULL != host_cert_pem.data && 0 != host_cert_pem.size) | 317 | NULL != host_cert_pem.data && 0 != host_cert_pem.size) |
| 314 | ret = IPHONE_E_SUCCESS; | 318 | ret = USERPREF_E_SUCCESS; |
| 315 | 319 | ||
| 316 | /* store values in config file */ | 320 | /* store values in config file */ |
| 317 | init_config_file( &root_key_pem, &host_key_pem, &root_cert_pem, &host_cert_pem); | 321 | userpref_set_keys_and_certs( &root_key_pem, &root_cert_pem, &host_key_pem, &host_cert_pem); |
| 318 | 322 | ||
| 319 | gnutls_free(root_key_pem.data); | 323 | gnutls_free(root_key_pem.data); |
| 320 | gnutls_free(host_key_pem.data); | ||
| 321 | gnutls_free(root_cert_pem.data); | 324 | gnutls_free(root_cert_pem.data); |
| 325 | gnutls_free(host_key_pem.data); | ||
| 322 | gnutls_free(host_cert_pem.data); | 326 | gnutls_free(host_cert_pem.data); |
| 323 | 327 | ||
| 324 | //restore gnutls env | 328 | //restore gnutls env |
| @@ -333,18 +337,18 @@ static iphone_error_t gen_keys_and_cert(void) | |||
| 333 | * @param key_name The filename of the private key to import. | 337 | * @param key_name The filename of the private key to import. |
| 334 | * @param key the gnutls key structure. | 338 | * @param key the gnutls key structure. |
| 335 | * | 339 | * |
| 336 | * @return IPHONE_E_SUCCESS if the key was successfully imported. | 340 | * @return 1 if the key was successfully imported. |
| 337 | */ | 341 | */ |
| 338 | static iphone_error_t import_key(const char* key_name, gnutls_x509_privkey_t key) | 342 | static userpref_error_t userpref_import_key(const char* key_name, gnutls_x509_privkey_t key) |
| 339 | { | 343 | { |
| 340 | iphone_error_t ret = IPHONE_E_INVALID_CONF; | 344 | userpref_error_t ret = USERPREF_E_INVALID_CONF; |
| 341 | gnutls_datum_t pem_key = { NULL, 0 }; | 345 | gnutls_datum_t pem_key = { NULL, 0 }; |
| 342 | 346 | ||
| 343 | if ( read_file_in_confdir(key_name, &pem_key) ) { | 347 | if (userpref_get_file_contents(key_name, &pem_key)) { |
| 344 | if (GNUTLS_E_SUCCESS == gnutls_x509_privkey_import(key, &pem_key, GNUTLS_X509_FMT_PEM)) | 348 | if (GNUTLS_E_SUCCESS == gnutls_x509_privkey_import(key, &pem_key, GNUTLS_X509_FMT_PEM)) |
| 345 | ret = IPHONE_E_SUCCESS; | 349 | ret = USERPREF_E_SUCCESS; |
| 346 | else | 350 | else |
| 347 | ret = IPHONE_E_SSL_ERROR; | 351 | ret = USERPREF_E_SSL_ERROR; |
| 348 | } | 352 | } |
| 349 | gnutls_free(pem_key.data); | 353 | gnutls_free(pem_key.data); |
| 350 | return ret; | 354 | return ret; |
| @@ -357,16 +361,16 @@ static iphone_error_t import_key(const char* key_name, gnutls_x509_privkey_t key | |||
| 357 | * | 361 | * |
| 358 | * @return IPHONE_E_SUCCESS if the certificate was successfully imported. | 362 | * @return IPHONE_E_SUCCESS if the certificate was successfully imported. |
| 359 | */ | 363 | */ |
| 360 | static iphone_error_t import_crt(const char* crt_name, gnutls_x509_crt_t cert) | 364 | static userpref_error_t userpref_import_crt(const char* crt_name, gnutls_x509_crt_t cert) |
| 361 | { | 365 | { |
| 362 | iphone_error_t ret = IPHONE_E_INVALID_CONF; | 366 | userpref_error_t ret = USERPREF_E_INVALID_CONF; |
| 363 | gnutls_datum_t pem_cert = { NULL, 0 }; | 367 | gnutls_datum_t pem_cert = { NULL, 0 }; |
| 364 | 368 | ||
| 365 | if ( read_file_in_confdir(crt_name, &pem_cert) ) { | 369 | if (userpref_get_file_contents(crt_name, &pem_cert)) { |
| 366 | if (GNUTLS_E_SUCCESS == gnutls_x509_crt_import(cert, &pem_cert, GNUTLS_X509_FMT_PEM)) | 370 | if (GNUTLS_E_SUCCESS == gnutls_x509_crt_import(cert, &pem_cert, GNUTLS_X509_FMT_PEM)) |
| 367 | ret = IPHONE_E_SUCCESS; | 371 | ret = USERPREF_E_SUCCESS; |
| 368 | else | 372 | else |
| 369 | ret = IPHONE_E_SSL_ERROR; | 373 | ret = USERPREF_E_SSL_ERROR; |
| 370 | } | 374 | } |
| 371 | gnutls_free(pem_cert.data); | 375 | gnutls_free(pem_cert.data); |
| 372 | return ret; | 376 | return ret; |
| @@ -382,41 +386,41 @@ static iphone_error_t import_crt(const char* crt_name, gnutls_x509_crt_t cert) | |||
| 382 | * @param host_privkey The host private key. | 386 | * @param host_privkey The host private key. |
| 383 | * @param host_crt The host certificate. | 387 | * @param host_crt The host certificate. |
| 384 | * | 388 | * |
| 385 | * @return IPHONE_E_SUCCESS if the keys and certificates were successfully retrieved. | 389 | * @return 1 if the keys and certificates were successfully retrieved, 0 otherwise |
| 386 | */ | 390 | */ |
| 387 | iphone_error_t get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt) | 391 | userpref_error_t userpref_get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt) |
| 388 | { | 392 | { |
| 389 | iphone_error_t ret = IPHONE_E_SUCCESS; | 393 | userpref_error_t ret = USERPREF_E_SUCCESS; |
| 390 | 394 | ||
| 391 | if (ret == IPHONE_E_SUCCESS) | 395 | if (ret == USERPREF_E_SUCCESS) |
| 392 | ret = import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); | 396 | ret = userpref_import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); |
| 393 | 397 | ||
| 394 | if (ret == IPHONE_E_SUCCESS) | 398 | if (ret == USERPREF_E_SUCCESS) |
| 395 | ret = import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); | 399 | ret = userpref_import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); |
| 396 | 400 | ||
| 397 | if (ret == IPHONE_E_SUCCESS) | 401 | if (ret == USERPREF_E_SUCCESS) |
| 398 | ret = import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); | 402 | ret = userpref_import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); |
| 399 | 403 | ||
| 400 | if (ret == IPHONE_E_SUCCESS) | 404 | if (ret == USERPREF_E_SUCCESS) |
| 401 | ret = import_crt(LIBIPHONE_HOST_CERTIF, host_crt); | 405 | ret = userpref_import_crt(LIBIPHONE_HOST_CERTIF, host_crt); |
| 402 | 406 | ||
| 403 | 407 | ||
| 404 | if (IPHONE_E_SUCCESS != ret) { | 408 | if (USERPREF_E_SUCCESS != ret) { |
| 405 | //we had problem reading or importing root cert | 409 | //we had problem reading or importing root cert |
| 406 | //try with a new ones. | 410 | //try with a new ones. |
| 407 | ret = gen_keys_and_cert(); | 411 | ret = userpref_gen_keys_and_cert(); |
| 408 | 412 | ||
| 409 | if (ret == IPHONE_E_SUCCESS) | 413 | if (ret == USERPREF_E_SUCCESS) |
| 410 | ret = import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); | 414 | ret = userpref_import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); |
| 411 | 415 | ||
| 412 | if (ret == IPHONE_E_SUCCESS) | 416 | if (ret == USERPREF_E_SUCCESS) |
| 413 | ret = import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); | 417 | ret = userpref_import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); |
| 414 | 418 | ||
| 415 | if (ret == IPHONE_E_SUCCESS) | 419 | if (ret == USERPREF_E_SUCCESS) |
| 416 | ret = import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); | 420 | ret = userpref_import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); |
| 417 | 421 | ||
| 418 | if (ret == IPHONE_E_SUCCESS) | 422 | if (ret == USERPREF_E_SUCCESS) |
| 419 | ret = import_crt(LIBIPHONE_HOST_CERTIF, host_crt); | 423 | ret = userpref_import_crt(LIBIPHONE_HOST_CERTIF, host_crt); |
| 420 | } | 424 | } |
| 421 | 425 | ||
| 422 | return ret; | 426 | return ret; |
| @@ -427,46 +431,43 @@ iphone_error_t get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x50 | |||
| 427 | * @param pem_root_cert The root certificate. | 431 | * @param pem_root_cert The root certificate. |
| 428 | * @param pem_host_cert The host certificate. | 432 | * @param pem_host_cert The host certificate. |
| 429 | * | 433 | * |
| 430 | * @return IPHONE_E_SUCCESS if the certificates were successfully retrieved. | 434 | * @return 1 if the certificates were successfully retrieved, 0 otherwise |
| 431 | */ | 435 | */ |
| 432 | iphone_error_t get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert) | 436 | userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert) |
| 433 | { | 437 | { |
| 434 | iphone_error_t ret = IPHONE_E_INVALID_CONF; | 438 | if (!pem_root_cert || !pem_host_cert) |
| 435 | 439 | return USERPREF_E_INVALID_ARG; | |
| 436 | if ( !pem_root_cert || !pem_host_cert) | ||
| 437 | return IPHONE_E_INVALID_ARG; | ||
| 438 | 440 | ||
| 439 | if ( read_file_in_confdir(LIBIPHONE_ROOT_CERTIF, pem_root_cert) && read_file_in_confdir(LIBIPHONE_HOST_CERTIF, pem_host_cert)) | 441 | if (userpref_get_file_contents(LIBIPHONE_ROOT_CERTIF, pem_root_cert) && userpref_get_file_contents(LIBIPHONE_HOST_CERTIF, pem_host_cert)) |
| 440 | ret = IPHONE_E_SUCCESS; | 442 | return USERPREF_E_SUCCESS; |
| 441 | else { | 443 | else { |
| 442 | g_free(pem_root_cert->data); | 444 | g_free(pem_root_cert->data); |
| 443 | g_free(pem_host_cert->data); | 445 | g_free(pem_host_cert->data); |
| 444 | } | 446 | } |
| 445 | return ret; | 447 | return USERPREF_E_INVALID_CONF; |
| 446 | } | 448 | } |
| 449 | |||
| 447 | /** Create and save a configuration file containing the given data. | 450 | /** Create and save a configuration file containing the given data. |
| 448 | * | 451 | * |
| 449 | * @note: All fields must specified and be non-null | 452 | * @note: All fields must specified and be non-null |
| 450 | * | 453 | * |
| 451 | * @param host_id The UUID of the host | ||
| 452 | * @param root_key The root key | 454 | * @param root_key The root key |
| 453 | * @param host_key The host key | ||
| 454 | * @param root_cert The root certificate | 455 | * @param root_cert The root certificate |
| 456 | * @param host_key The host key | ||
| 455 | * @param host_cert The host certificate | 457 | * @param host_cert The host certificate |
| 456 | * | 458 | * |
| 457 | * @return 1 on success and 0 otherwise. | 459 | * @return 1 on success and 0 otherwise. |
| 458 | */ | 460 | */ |
| 459 | int init_config_file( gnutls_datum_t * root_key, gnutls_datum_t * host_key, gnutls_datum_t * root_cert, | 461 | userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_datum_t * root_cert, gnutls_datum_t * host_key, gnutls_datum_t * host_cert) |
| 460 | gnutls_datum_t * host_cert) | ||
| 461 | { | 462 | { |
| 462 | FILE *pFile; | 463 | FILE *pFile; |
| 463 | gchar *pem; | 464 | gchar *pem; |
| 464 | 465 | ||
| 465 | if (!root_key || !host_key || !root_cert || !host_cert) | 466 | if (!root_key || !host_key || !root_cert || !host_cert) |
| 466 | return 0; | 467 | return USERPREF_E_INVALID_ARG; |
| 467 | 468 | ||
| 468 | /* Make sure config directory exists */ | 469 | /* Make sure config directory exists */ |
| 469 | create_config_dir(); | 470 | userpref_create_config_dir(); |
| 470 | 471 | ||
| 471 | /* Now write keys and certificates to disk */ | 472 | /* Now write keys and certificates to disk */ |
| 472 | pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_ROOT_PRIVKEY, NULL); | 473 | pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_ROOT_PRIVKEY, NULL); |
| @@ -493,5 +494,5 @@ int init_config_file( gnutls_datum_t * root_key, gnutls_datum_t * host_key, gnut | |||
| 493 | fclose(pFile); | 494 | fclose(pFile); |
| 494 | g_free(pem); | 495 | g_free(pem); |
| 495 | 496 | ||
| 496 | return 1; | 497 | return USERPREF_E_SUCCESS; |
| 497 | } | 498 | } |
diff --git a/src/userpref.h b/src/userpref.h index deced04..414c093 100644 --- a/src/userpref.h +++ b/src/userpref.h | |||
| @@ -23,19 +23,21 @@ | |||
| 23 | #define USERPREF_H | 23 | #define USERPREF_H |
| 24 | 24 | ||
| 25 | #include <gnutls/gnutls.h> | 25 | #include <gnutls/gnutls.h> |
| 26 | #include "libiphone/libiphone.h" | ||
| 27 | 26 | ||
| 27 | #define USERPREF_E_SUCCESS 0 | ||
| 28 | #define USERPREF_E_INVALID_ARG -1 | ||
| 29 | #define USERPREF_E_INVALID_CONF -2 | ||
| 30 | #define USERPREF_E_SSL_ERROR -3 | ||
| 28 | 31 | ||
| 29 | iphone_error_t get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt); | 32 | #define USERPREF_E_UNKNOWN_ERROR -256 |
| 30 | 33 | ||
| 31 | iphone_error_t get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert); | 34 | typedef int16_t userpref_error_t; |
| 32 | 35 | ||
| 33 | char *get_host_id(void); | 36 | userpref_error_t userpref_get_keys_and_certs(gnutls_x509_privkey_t root_privkey, gnutls_x509_crt_t root_crt, gnutls_x509_privkey_t host_privkey, gnutls_x509_crt_t host_crt); |
| 37 | userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_datum_t * root_cert, gnutls_datum_t * host_key, gnutls_datum_t * host_cert); | ||
| 38 | userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert); | ||
| 39 | userpref_error_t userpref_set_device_public_key(char *uuid, gnutls_datum_t public_key); | ||
| 40 | int userpref_has_device_public_key(char *uuid); | ||
| 41 | void userpref_get_host_id(char **host_id); | ||
| 34 | 42 | ||
| 35 | int is_device_known(char *uid); | ||
| 36 | |||
| 37 | int store_device_public_key(char *uid, gnutls_datum_t public_key); | ||
| 38 | |||
| 39 | int init_config_file( gnutls_datum_t * root_key, gnutls_datum_t * host_key, gnutls_datum_t * root_cert, | ||
| 40 | gnutls_datum_t * host_cert); | ||
| 41 | #endif | 43 | #endif |
