diff options
| author | 2009-04-13 08:48:00 -0700 | |
|---|---|---|
| committer | 2009-04-13 08:48:00 -0700 | |
| commit | 6671ca3d6de6a1fd27853e3b1ce7a81d568703f0 (patch) | |
| tree | 735c5ace7ed57cd4e19f2fde423b22e6104eaa98 /src/userpref.c | |
| parent | bd31783d7fde0b5bd101f4a3f97ca1aca2aa6fab (diff) | |
| parent | 288929f45cb2641690879b52ec514097995cd41a (diff) | |
| download | libimobiledevice-6671ca3d6de6a1fd27853e3b1ce7a81d568703f0.tar.gz libimobiledevice-6671ca3d6de6a1fd27853e3b1ce7a81d568703f0.tar.bz2 | |
Merged in Jonathan's libplist libiphone. [#2 state:resolved]
Diffstat (limited to 'src/userpref.c')
| -rw-r--r-- | src/userpref.c | 334 |
1 files changed, 273 insertions, 61 deletions
diff --git a/src/userpref.c b/src/userpref.c index 5f227b0..0e83133 100644 --- a/src/userpref.c +++ b/src/userpref.c | |||
| @@ -8,25 +8,28 @@ | |||
| 8 | * modify it under the terms of the GNU Lesser General Public | 8 | * modify it under the terms of the GNU Lesser General Public |
| 9 | * License as published by the Free Software Foundation; either | 9 | * License as published by the Free Software Foundation; either |
| 10 | * version 2.1 of the License, or (at your option) any later version. | 10 | * version 2.1 of the License, or (at your option) any later version. |
| 11 | * | 11 | * |
| 12 | * This library is distributed in the hope that it will be useful, | 12 | * This library is distributed in the hope that it will be useful, |
| 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | 13 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | 14 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU |
| 15 | * Lesser General Public License for more details. | 15 | * Lesser General Public License for more details. |
| 16 | * | 16 | * |
| 17 | * You should have received a copy of the GNU Lesser General Public | 17 | * You should have received a copy of the GNU Lesser General Public |
| 18 | * License along with this library; if not, write to the Free Software | 18 | * License along with this library; if not, write to the Free Software |
| 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 <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 <stdlib.h> | ||
| 25 | #include <string.h> | 26 | #include <string.h> |
| 27 | #include <gnutls/gnutls.h> | ||
| 28 | #include <gnutls/x509.h> | ||
| 29 | #include <gcrypt.h> | ||
| 30 | |||
| 26 | #include "userpref.h" | 31 | #include "userpref.h" |
| 27 | #include "utils.h" | 32 | #include "utils.h" |
| 28 | #include <string.h> | ||
| 29 | #include <stdlib.h> | ||
| 30 | 33 | ||
| 31 | #define LIBIPHONE_CONF_DIR "libiphone" | 34 | #define LIBIPHONE_CONF_DIR "libiphone" |
| 32 | #define LIBIPHONE_CONF_FILE "libiphonerc" | 35 | #define LIBIPHONE_CONF_FILE "libiphonerc" |
| @@ -49,9 +52,75 @@ static void create_config_dir(void) | |||
| 49 | g_free(config_dir); | 52 | g_free(config_dir); |
| 50 | } | 53 | } |
| 51 | 54 | ||
| 55 | static int get_rand(int min, int max) | ||
| 56 | { | ||
| 57 | int retval = (rand() % (max - min)) + min; | ||
| 58 | return retval; | ||
| 59 | } | ||
| 60 | |||
| 61 | /** Generates a valid HostID (which is actually a UUID). | ||
| 62 | * | ||
| 63 | * @return A null terminated string containing a valid HostID. | ||
| 64 | */ | ||
| 65 | static char *lockdownd_generate_hostid() | ||
| 66 | { | ||
| 67 | char *hostid = (char *) malloc(sizeof(char) * 37); // HostID's are just UUID's, and UUID's are 36 characters long | ||
| 68 | const char *chars = "ABCDEF0123456789"; | ||
| 69 | srand(time(NULL)); | ||
| 70 | int i = 0; | ||
| 71 | |||
| 72 | for (i = 0; i < 36; i++) { | ||
| 73 | if (i == 8 || i == 13 || i == 18 || i == 23) { | ||
| 74 | hostid[i] = '-'; | ||
| 75 | continue; | ||
| 76 | } else { | ||
| 77 | hostid[i] = chars[get_rand(0, 16)]; | ||
| 78 | } | ||
| 79 | } | ||
| 80 | hostid[36] = '\0'; // make it a real string | ||
| 81 | return hostid; | ||
| 82 | } | ||
| 83 | |||
| 84 | /** Store HostID in config file. | ||
| 85 | * | ||
| 86 | * @param host_id A null terminated string containing a valid HostID. | ||
| 87 | */ | ||
| 88 | static int write_host_id(char *host_id) | ||
| 89 | { | ||
| 90 | GKeyFile *key_file; | ||
| 91 | gsize length; | ||
| 92 | gchar *buf, *config_file; | ||
| 93 | GIOChannel *file; | ||
| 94 | |||
| 95 | if (!host_id) | ||
| 96 | return 0; | ||
| 97 | |||
| 98 | /* Make sure config directory exists */ | ||
| 99 | create_config_dir(); | ||
| 100 | |||
| 101 | /* Now parse file to get the HostID */ | ||
| 102 | key_file = g_key_file_new(); | ||
| 52 | 103 | ||
| 53 | /** Reads the HostID from a previously generated configuration file. | 104 | /* Store in config file */ |
| 54 | * | 105 | log_debug_msg("init_config_file(): setting hostID to %s\n", host_id); |
| 106 | g_key_file_set_value(key_file, "Global", "HostID", host_id); | ||
| 107 | |||
| 108 | /* Write config file on disk */ | ||
| 109 | buf = g_key_file_to_data(key_file, &length, NULL); | ||
| 110 | config_file = | ||
| 111 | g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_CONF_FILE, NULL); | ||
| 112 | file = g_io_channel_new_file(config_file, "w", NULL); | ||
| 113 | g_free(config_file); | ||
| 114 | g_io_channel_write_chars(file, buf, length, NULL, NULL); | ||
| 115 | g_io_channel_shutdown(file, TRUE, NULL); | ||
| 116 | g_io_channel_unref(file); | ||
| 117 | |||
| 118 | g_key_file_free(key_file); | ||
| 119 | return 1; | ||
| 120 | } | ||
| 121 | |||
| 122 | /** Reads the HostID from a previously generated configuration file. | ||
| 123 | * | ||
| 55 | * @note It is the responsibility of the calling function to free the returned host_id | 124 | * @note It is the responsibility of the calling function to free the returned host_id |
| 56 | * | 125 | * |
| 57 | * @return The string containing the HostID or NULL | 126 | * @return The string containing the HostID or NULL |
| @@ -77,6 +146,12 @@ char *get_host_id(void) | |||
| 77 | g_key_file_free(key_file); | 146 | g_key_file_free(key_file); |
| 78 | g_free(config_file); | 147 | g_free(config_file); |
| 79 | 148 | ||
| 149 | if (!host_id) { | ||
| 150 | //no config, generate host_id | ||
| 151 | host_id = lockdownd_generate_hostid(); | ||
| 152 | write_host_id(host_id); | ||
| 153 | } | ||
| 154 | |||
| 80 | log_debug_msg("get_host_id(): Using %s as HostID\n", host_id); | 155 | log_debug_msg("get_host_id(): Using %s as HostID\n", host_id); |
| 81 | return host_id; | 156 | return host_id; |
| 82 | } | 157 | } |
| @@ -111,10 +186,10 @@ int is_device_known(char *uid) | |||
| 111 | * @return 1 on success and 0 if no public key is given or if it has already | 186 | * @return 1 on success and 0 if no public key is given or if it has already |
| 112 | * been marked as connected previously. | 187 | * been marked as connected previously. |
| 113 | */ | 188 | */ |
| 114 | int store_device_public_key(char *uid, char *public_key) | 189 | int store_device_public_key(char *uid, gnutls_datum_t public_key) |
| 115 | { | 190 | { |
| 116 | 191 | ||
| 117 | if (NULL == public_key || is_device_known(uid)) | 192 | if (NULL == public_key.data || is_device_known(uid)) |
| 118 | return 0; | 193 | return 0; |
| 119 | 194 | ||
| 120 | /* ensure config directory exists */ | 195 | /* ensure config directory exists */ |
| @@ -124,15 +199,11 @@ int store_device_public_key(char *uid, char *public_key) | |||
| 124 | gchar *device_file = g_strconcat(uid, ".pem", NULL); | 199 | gchar *device_file = g_strconcat(uid, ".pem", NULL); |
| 125 | gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); | 200 | gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, device_file, NULL); |
| 126 | 201 | ||
| 127 | /* decode public key for storing */ | ||
| 128 | gsize decoded_size; | ||
| 129 | gchar *data = g_base64_decode(public_key, &decoded_size); | ||
| 130 | /* store file */ | 202 | /* store file */ |
| 131 | FILE *pFile = fopen(pem, "wb"); | 203 | FILE *pFile = fopen(pem, "wb"); |
| 132 | fwrite(data, 1, decoded_size, pFile); | 204 | fwrite(public_key.data, 1, public_key.size, pFile); |
| 133 | fclose(pFile); | 205 | fclose(pFile); |
| 134 | g_free(pem); | 206 | g_free(pem); |
| 135 | g_free(data); | ||
| 136 | g_free(device_file); | 207 | g_free(device_file); |
| 137 | return 1; | 208 | return 1; |
| 138 | } | 209 | } |
| @@ -160,56 +231,220 @@ static int read_file_in_confdir(const char *file, gnutls_datum_t * data) | |||
| 160 | g_free(filepath); | 231 | g_free(filepath); |
| 161 | 232 | ||
| 162 | /* Add it to the gnutls_datnum_t structure */ | 233 | /* Add it to the gnutls_datnum_t structure */ |
| 163 | data->data = content; | 234 | data->data = (uint8_t*) content; |
| 164 | data->size = size; | 235 | data->size = size; |
| 165 | 236 | ||
| 166 | return success; | 237 | return success; |
| 167 | } | 238 | } |
| 168 | 239 | ||
| 169 | /** Read the root private key | 240 | |
| 170 | * | 241 | /** Private function which generate private keys and certificates. |
| 171 | * @param root_privkey A pointer to the appropriate gnutls structure | ||
| 172 | * | 242 | * |
| 173 | * @return 1 if the file was successfully read and 0 otherwise. | 243 | * @return IPHONE_E_SUCCESS if keys were successfully generated. |
| 174 | */ | 244 | */ |
| 175 | int get_root_private_key(gnutls_datum_t * root_privkey) | 245 | static iphone_error_t gen_keys_and_cert(void) |
| 176 | { | 246 | { |
| 177 | return read_file_in_confdir(LIBIPHONE_ROOT_PRIVKEY, root_privkey); | 247 | iphone_error_t ret = IPHONE_E_UNKNOWN_ERROR; |
| 248 | gnutls_x509_privkey_t root_privkey; | ||
| 249 | gnutls_x509_privkey_t host_privkey; | ||
| 250 | gnutls_x509_crt_t root_cert; | ||
| 251 | gnutls_x509_crt_t host_cert; | ||
| 252 | |||
| 253 | gnutls_global_deinit(); | ||
| 254 | gnutls_global_init(); | ||
| 255 | |||
| 256 | //use less secure random to speed up key generation | ||
| 257 | gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM); | ||
| 258 | |||
| 259 | gnutls_x509_privkey_init(&root_privkey); | ||
| 260 | gnutls_x509_privkey_init(&host_privkey); | ||
| 261 | |||
| 262 | gnutls_x509_crt_init(&root_cert); | ||
| 263 | gnutls_x509_crt_init(&host_cert); | ||
| 264 | |||
| 265 | /* generate root key */ | ||
| 266 | gnutls_x509_privkey_generate(root_privkey, GNUTLS_PK_RSA, 2048, 0); | ||
| 267 | gnutls_x509_privkey_generate(host_privkey, GNUTLS_PK_RSA, 2048, 0); | ||
| 268 | |||
| 269 | /* generate certificates */ | ||
| 270 | gnutls_x509_crt_set_key(root_cert, root_privkey); | ||
| 271 | gnutls_x509_crt_set_serial(root_cert, "\x00", 1); | ||
| 272 | gnutls_x509_crt_set_version(root_cert, 3); | ||
| 273 | gnutls_x509_crt_set_ca_status(root_cert, 1); | ||
| 274 | gnutls_x509_crt_set_activation_time(root_cert, time(NULL)); | ||
| 275 | gnutls_x509_crt_set_expiration_time(root_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); | ||
| 276 | gnutls_x509_crt_sign(root_cert, root_cert, root_privkey); | ||
| 277 | |||
| 278 | |||
| 279 | gnutls_x509_crt_set_key(host_cert, host_privkey); | ||
| 280 | gnutls_x509_crt_set_serial(host_cert, "\x00", 1); | ||
| 281 | gnutls_x509_crt_set_version(host_cert, 3); | ||
| 282 | gnutls_x509_crt_set_ca_status(host_cert, 0); | ||
| 283 | gnutls_x509_crt_set_key_usage(host_cert, GNUTLS_KEY_KEY_ENCIPHERMENT | GNUTLS_KEY_DIGITAL_SIGNATURE); | ||
| 284 | gnutls_x509_crt_set_activation_time(host_cert, time(NULL)); | ||
| 285 | gnutls_x509_crt_set_expiration_time(host_cert, time(NULL) + (60 * 60 * 24 * 365 * 10)); | ||
| 286 | gnutls_x509_crt_sign(host_cert, root_cert, root_privkey); | ||
| 287 | |||
| 288 | /* export to PEM format */ | ||
| 289 | gnutls_datum_t root_key_pem = { NULL, 0 }; | ||
| 290 | gnutls_datum_t host_key_pem = { NULL, 0 }; | ||
| 291 | |||
| 292 | gnutls_x509_privkey_export(root_privkey, GNUTLS_X509_FMT_PEM, NULL, &root_key_pem.size); | ||
| 293 | gnutls_x509_privkey_export(host_privkey, GNUTLS_X509_FMT_PEM, NULL, &host_key_pem.size); | ||
| 294 | |||
| 295 | root_key_pem.data = gnutls_malloc(root_key_pem.size); | ||
| 296 | host_key_pem.data = gnutls_malloc(host_key_pem.size); | ||
| 297 | |||
| 298 | gnutls_x509_privkey_export(root_privkey, GNUTLS_X509_FMT_PEM, root_key_pem.data, &root_key_pem.size); | ||
| 299 | gnutls_x509_privkey_export(host_privkey, GNUTLS_X509_FMT_PEM, host_key_pem.data, &host_key_pem.size); | ||
| 300 | |||
| 301 | gnutls_datum_t root_cert_pem = { NULL, 0 }; | ||
| 302 | gnutls_datum_t host_cert_pem = { NULL, 0 }; | ||
| 303 | |||
| 304 | gnutls_x509_crt_export(root_cert, GNUTLS_X509_FMT_PEM, NULL, &root_cert_pem.size); | ||
| 305 | gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, NULL, &host_cert_pem.size); | ||
| 306 | |||
| 307 | root_cert_pem.data = gnutls_malloc(root_cert_pem.size); | ||
| 308 | host_cert_pem.data = gnutls_malloc(host_cert_pem.size); | ||
| 309 | |||
| 310 | gnutls_x509_crt_export(root_cert, GNUTLS_X509_FMT_PEM, root_cert_pem.data, &root_cert_pem.size); | ||
| 311 | gnutls_x509_crt_export(host_cert, GNUTLS_X509_FMT_PEM, host_cert_pem.data, &host_cert_pem.size); | ||
| 312 | |||
| 313 | if (NULL != root_cert_pem.data && 0 != root_cert_pem.size && | ||
| 314 | NULL != host_cert_pem.data && 0 != host_cert_pem.size) | ||
| 315 | ret = IPHONE_E_SUCCESS; | ||
| 316 | |||
| 317 | /* store values in config file */ | ||
| 318 | init_config_file( &root_key_pem, &host_key_pem, &root_cert_pem, &host_cert_pem); | ||
| 319 | |||
| 320 | gnutls_free(root_key_pem.data); | ||
| 321 | gnutls_free(host_key_pem.data); | ||
| 322 | gnutls_free(root_cert_pem.data); | ||
| 323 | gnutls_free(host_cert_pem.data); | ||
| 324 | |||
| 325 | //restore gnutls env | ||
| 326 | gnutls_global_deinit(); | ||
| 327 | gnutls_global_init(); | ||
| 328 | |||
| 329 | return ret; | ||
| 178 | } | 330 | } |
| 179 | 331 | ||
| 180 | /** Read the host private key | 332 | /** Private function which import the given key into a gnutls structure. |
| 181 | * | 333 | * |
| 182 | * @param host_privkey A pointer to the appropriate gnutls structure | 334 | * @param key_name The filename of the private key to import. |
| 335 | * @param key the gnutls key structure. | ||
| 183 | * | 336 | * |
| 184 | * @return 1 if the file was successfully read and 0 otherwise. | 337 | * @return IPHONE_E_SUCCESS if the key was successfully imported. |
| 185 | */ | 338 | */ |
| 186 | int get_host_private_key(gnutls_datum_t * host_privkey) | 339 | static iphone_error_t import_key(const char* key_name, gnutls_x509_privkey_t key) |
| 187 | { | 340 | { |
| 188 | return read_file_in_confdir(LIBIPHONE_HOST_PRIVKEY, host_privkey); | 341 | iphone_error_t ret = IPHONE_E_INVALID_CONF; |
| 342 | gnutls_datum_t pem_key = { NULL, 0 }; | ||
| 343 | |||
| 344 | if ( read_file_in_confdir(key_name, &pem_key) ) { | ||
| 345 | if (GNUTLS_E_SUCCESS == gnutls_x509_privkey_import(key, &pem_key, GNUTLS_X509_FMT_PEM)) | ||
| 346 | ret = IPHONE_E_SUCCESS; | ||
| 347 | else | ||
| 348 | ret = IPHONE_E_SSL_ERROR; | ||
| 349 | } | ||
| 350 | gnutls_free(pem_key.data); | ||
| 351 | return ret; | ||
| 189 | } | 352 | } |
| 190 | 353 | ||
| 191 | /** Read the root certificate | 354 | /** Private function which import the given certificate into a gnutls structure. |
| 192 | * | 355 | * |
| 193 | * @param root_privkey A pointer to the appropriate gnutls structure | 356 | * @param crt_name The filename of the certificate to import. |
| 357 | * @param cert the gnutls certificate structure. | ||
| 194 | * | 358 | * |
| 195 | * @return 1 if the file was successfully read and 0 otherwise. | 359 | * @return IPHONE_E_SUCCESS if the certificate was successfully imported. |
| 196 | */ | 360 | */ |
| 197 | int get_root_certificate(gnutls_datum_t * root_cert) | 361 | static iphone_error_t import_crt(const char* crt_name, gnutls_x509_crt_t cert) |
| 198 | { | 362 | { |
| 199 | return read_file_in_confdir(LIBIPHONE_ROOT_CERTIF, root_cert); | 363 | iphone_error_t ret = IPHONE_E_INVALID_CONF; |
| 364 | gnutls_datum_t pem_cert = { NULL, 0 }; | ||
| 365 | |||
| 366 | if ( read_file_in_confdir(crt_name, &pem_cert) ) { | ||
| 367 | if (GNUTLS_E_SUCCESS == gnutls_x509_crt_import(cert, &pem_cert, GNUTLS_X509_FMT_PEM)) | ||
| 368 | ret = IPHONE_E_SUCCESS; | ||
| 369 | else | ||
| 370 | ret = IPHONE_E_SSL_ERROR; | ||
| 371 | } | ||
| 372 | gnutls_free(pem_cert.data); | ||
| 373 | return ret; | ||
| 200 | } | 374 | } |
| 201 | 375 | ||
| 202 | /** Read the host certificate | 376 | /** Function to retrieve host keys and certificates. |
| 377 | * This function trigger key generation if they do not exists yet or are invalid. | ||
| 203 | * | 378 | * |
| 204 | * @param root_privkey A pointer to the appropriate gnutls structure | 379 | * @note This function can take few seconds to complete (typically 5 seconds) |
| 205 | * | 380 | * |
| 206 | * @return 1 if the file was successfully read and 0 otherwise. | 381 | * @param root_privkey The root private key. |
| 382 | * @param root_crt The root certificate. | ||
| 383 | * @param host_privkey The host private key. | ||
| 384 | * @param host_crt The host certificate. | ||
| 385 | * | ||
| 386 | * @return IPHONE_E_SUCCESS if the keys and certificates were successfully retrieved. | ||
| 207 | */ | 387 | */ |
| 208 | int get_host_certificate(gnutls_datum_t * host_cert) | 388 | 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) |
| 209 | { | 389 | { |
| 210 | return read_file_in_confdir(LIBIPHONE_HOST_CERTIF, host_cert); | 390 | iphone_error_t ret = IPHONE_E_SUCCESS; |
| 391 | |||
| 392 | if (ret == IPHONE_E_SUCCESS) | ||
| 393 | ret = import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); | ||
| 394 | |||
| 395 | if (ret == IPHONE_E_SUCCESS) | ||
| 396 | ret = import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); | ||
| 397 | |||
| 398 | if (ret == IPHONE_E_SUCCESS) | ||
| 399 | ret = import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); | ||
| 400 | |||
| 401 | if (ret == IPHONE_E_SUCCESS) | ||
| 402 | ret = import_crt(LIBIPHONE_HOST_CERTIF, host_crt); | ||
| 403 | |||
| 404 | |||
| 405 | if (IPHONE_E_SUCCESS != ret) { | ||
| 406 | //we had problem reading or importing root cert | ||
| 407 | //try with a new ones. | ||
| 408 | ret = gen_keys_and_cert(); | ||
| 409 | |||
| 410 | if (ret == IPHONE_E_SUCCESS) | ||
| 411 | ret = import_key(LIBIPHONE_ROOT_PRIVKEY, root_privkey); | ||
| 412 | |||
| 413 | if (ret == IPHONE_E_SUCCESS) | ||
| 414 | ret = import_key(LIBIPHONE_HOST_PRIVKEY, host_privkey); | ||
| 415 | |||
| 416 | if (ret == IPHONE_E_SUCCESS) | ||
| 417 | ret = import_crt(LIBIPHONE_ROOT_CERTIF, root_crt); | ||
| 418 | |||
| 419 | if (ret == IPHONE_E_SUCCESS) | ||
| 420 | ret = import_crt(LIBIPHONE_HOST_CERTIF, host_crt); | ||
| 421 | } | ||
| 422 | |||
| 423 | return ret; | ||
| 211 | } | 424 | } |
| 212 | 425 | ||
| 426 | /** Function to retrieve certificates encoded in PEM format. | ||
| 427 | * | ||
| 428 | * @param pem_root_cert The root certificate. | ||
| 429 | * @param pem_host_cert The host certificate. | ||
| 430 | * | ||
| 431 | * @return IPHONE_E_SUCCESS if the certificates were successfully retrieved. | ||
| 432 | */ | ||
| 433 | iphone_error_t get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls_datum_t *pem_host_cert) | ||
| 434 | { | ||
| 435 | iphone_error_t ret = IPHONE_E_INVALID_CONF; | ||
| 436 | |||
| 437 | if ( !pem_root_cert || !pem_host_cert) | ||
| 438 | return IPHONE_E_INVALID_ARG; | ||
| 439 | |||
| 440 | if ( read_file_in_confdir(LIBIPHONE_ROOT_CERTIF, pem_root_cert) && read_file_in_confdir(LIBIPHONE_HOST_CERTIF, pem_host_cert)) | ||
| 441 | ret = IPHONE_E_SUCCESS; | ||
| 442 | else { | ||
| 443 | g_free(pem_root_cert->data); | ||
| 444 | g_free(pem_host_cert->data); | ||
| 445 | } | ||
| 446 | return ret; | ||
| 447 | } | ||
| 213 | /** Create and save a configuration file containing the given data. | 448 | /** Create and save a configuration file containing the given data. |
| 214 | * | 449 | * |
| 215 | * @note: All fields must specified and be non-null | 450 | * @note: All fields must specified and be non-null |
| @@ -222,41 +457,18 @@ int get_host_certificate(gnutls_datum_t * host_cert) | |||
| 222 | * | 457 | * |
| 223 | * @return 1 on success and 0 otherwise. | 458 | * @return 1 on success and 0 otherwise. |
| 224 | */ | 459 | */ |
| 225 | int init_config_file(char *host_id, gnutls_datum_t * root_key, gnutls_datum_t * host_key, gnutls_datum_t * root_cert, | 460 | int init_config_file( gnutls_datum_t * root_key, gnutls_datum_t * host_key, gnutls_datum_t * root_cert, |
| 226 | gnutls_datum_t * host_cert) | 461 | gnutls_datum_t * host_cert) |
| 227 | { | 462 | { |
| 228 | FILE *pFile; | 463 | FILE *pFile; |
| 229 | gchar *pem; | 464 | gchar *pem; |
| 230 | GKeyFile *key_file; | ||
| 231 | gsize length; | ||
| 232 | gchar *buf, *config_file; | ||
| 233 | GIOChannel *file; | ||
| 234 | 465 | ||
| 235 | if (!host_id || !root_key || !host_key || !root_cert || !host_cert) | 466 | if (!root_key || !host_key || !root_cert || !host_cert) |
| 236 | return 0; | 467 | return 0; |
| 237 | 468 | ||
| 238 | /* Make sure config directory exists */ | 469 | /* Make sure config directory exists */ |
| 239 | create_config_dir(); | 470 | create_config_dir(); |
| 240 | 471 | ||
| 241 | /* Now parse file to get the HostID */ | ||
| 242 | key_file = g_key_file_new(); | ||
| 243 | |||
| 244 | /* Store in config file */ | ||
| 245 | log_debug_msg("init_config_file(): setting hostID to %s\n", host_id); | ||
| 246 | g_key_file_set_value(key_file, "Global", "HostID", host_id); | ||
| 247 | |||
| 248 | /* Write config file on disk */ | ||
| 249 | buf = g_key_file_to_data(key_file, &length, NULL); | ||
| 250 | config_file = | ||
| 251 | g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIPHONE_CONF_DIR, LIBIPHONE_CONF_FILE, NULL); | ||
| 252 | file = g_io_channel_new_file(config_file, "w", NULL); | ||
| 253 | g_free(config_file); | ||
| 254 | g_io_channel_write_chars(file, buf, length, NULL, NULL); | ||
| 255 | g_io_channel_shutdown(file, TRUE, NULL); | ||
| 256 | g_io_channel_unref(file); | ||
| 257 | |||
| 258 | g_key_file_free(key_file); | ||
| 259 | |||
| 260 | /* Now write keys and certificates to disk */ | 472 | /* Now write keys and certificates to disk */ |
| 261 | 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); |
| 262 | pFile = fopen(pem, "wb"); | 474 | pFile = fopen(pem, "wb"); |
