summaryrefslogtreecommitdiffstats
path: root/src/userpref.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/userpref.c')
-rw-r--r--src/userpref.c492
1 files changed, 404 insertions, 88 deletions
diff --git a/src/userpref.c b/src/userpref.c
index 4aab67b..d44d5aa 100644
--- a/src/userpref.c
+++ b/src/userpref.c
@@ -19,9 +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 <glib.h>
23#include <glib/gstdio.h>
24#include <glib/gprintf.h>
25#include <stdio.h> 22#include <stdio.h>
26#include <stdint.h> 23#include <stdint.h>
27#include <stdlib.h> 24#include <stdlib.h>
@@ -30,6 +27,15 @@
30#include <gnutls/x509.h> 27#include <gnutls/x509.h>
31#include <gcrypt.h> 28#include <gcrypt.h>
32 29
30#include <dirent.h>
31#include <libgen.h>
32#include <sys/stat.h>
33#include <errno.h>
34
35#ifdef WIN32
36#include <shlobj.h>
37#endif
38
33#include "userpref.h" 39#include "userpref.h"
34#include "debug.h" 40#include "debug.h"
35 41
@@ -41,18 +47,239 @@
41#define LIBIMOBILEDEVICE_ROOT_CERTIF "RootCertificate.pem" 47#define LIBIMOBILEDEVICE_ROOT_CERTIF "RootCertificate.pem"
42#define LIBIMOBILEDEVICE_HOST_CERTIF "HostCertificate.pem" 48#define LIBIMOBILEDEVICE_HOST_CERTIF "HostCertificate.pem"
43 49
50#ifdef WIN32
51#define DIR_SEP '\\'
52#define DIR_SEP_S "\\"
53#else
54#define DIR_SEP '/'
55#define DIR_SEP_S "/"
56#endif
57
58static char __config_dir[512] = {0, };
59
60#ifdef WIN32
61static char *userpref_utf16_to_utf8(wchar_t *unistr, long len, long *items_read, long *items_written)
62{
63 if (!unistr || (len <= 0)) return NULL;
64 char *outbuf = (char*)malloc(3*(len+1));
65 int p = 0;
66 int i = 0;
67
68 wchar_t wc;
69
70 while (i < len) {
71 wc = unistr[i++];
72 if (wc >= 0x800) {
73 outbuf[p++] = (char)(0xE0 + ((wc >> 12) & 0xF));
74 outbuf[p++] = (char)(0x80 + ((wc >> 6) & 0x3F));
75 outbuf[p++] = (char)(0x80 + (wc & 0x3F));
76 } else if (wc >= 0x80) {
77 outbuf[p++] = (char)(0xC0 + ((wc >> 6) & 0x1F));
78 outbuf[p++] = (char)(0x80 + (wc & 0x3F));
79 } else {
80 outbuf[p++] = (char)(wc & 0x7F);
81 }
82 }
83 if (items_read) {
84 *items_read = i;
85 }
86 if (items_written) {
87 *items_written = p;
88 }
89 outbuf[p] = 0;
90
91 return outbuf;
92}
93#endif
94
95static const char *userpref_get_config_dir()
96{
97 if (__config_dir[0]) return __config_dir;
98#ifdef WIN32
99 wchar_t path[MAX_PATH+1];
100 HRESULT hr;
101 LPITEMIDLIST pidl = NULL;
102 BOOL b = FALSE;
103
104 hr = SHGetSpecialFolderLocation (NULL, CSIDL_LOCAL_APPDATA, &pidl);
105 if (hr == S_OK) {
106 b = SHGetPathFromIDListW (pidl, path);
107 if (b) {
108 char *cdir = userpref_utf16_to_utf8 (path, wcslen(path), NULL, NULL);
109 strcpy(__config_dir, cdir);
110 free(cdir);
111 CoTaskMemFree (pidl);
112 }
113 }
114#else
115 const char *cdir = getenv("XDG_CONFIG_HOME");
116 if (!cdir) {
117 cdir = getenv("HOME");
118 strcpy(__config_dir, cdir);
119 strcat(__config_dir, DIR_SEP_S);
120 strcat(__config_dir, ".config");
121 } else {
122 strcpy(__config_dir, cdir);
123 }
124#endif
125 strcat(__config_dir, DIR_SEP_S);
126 strcat(__config_dir, LIBIMOBILEDEVICE_CONF_DIR);
127
128 int i = strlen(__config_dir)-1;
129 while ((i > 0) && (__config_dir[i] == DIR_SEP)) {
130 __config_dir[i--] = '\0';
131 }
132
133 return __config_dir;
134}
135
136static int mkdir_with_parents(const char *dir, int mode)
137{
138 if (!dir) return -1;
139 if (mkdir(dir, mode) == 0) {
140 return 0;
141 } else {
142 if (errno == EEXIST) return 0;
143 }
144 int res;
145 char *parent = strdup(dir);
146 parent = dirname(parent);
147 if (parent) {
148 res = mkdir_with_parents(parent, mode);
149 } else {
150 res = -1;
151 }
152 free(parent);
153 if (res == 0) {
154 mkdir_with_parents(dir, mode);
155 }
156 return res;
157}
158
159static int config_write(const char *cfgfile, plist_t dict)
160{
161 if (!cfgfile || !dict || (plist_get_node_type(dict) != PLIST_DICT)) {
162 return -1;
163 }
164 int res = -1;
165
166#if 1 // old style config
167 plist_t hostid = plist_dict_get_item(dict, "HostID");
168 if (hostid && (plist_get_node_type(hostid) == PLIST_STRING)) {
169 char *hostidstr = NULL;
170 plist_get_string_val(hostid, &hostidstr);
171 if (hostidstr) {
172 FILE *fd = fopen(cfgfile, "w");
173 if (fd) {
174 fprintf(fd, "\n[Global]\nHostID=%s\n", hostidstr);
175 fclose(fd);
176 res = 0;
177 }
178 free(hostidstr);
179 }
180 }
181#endif
182#if 0
183 char *xml = NULL;
184 uint32_t length = 0;
185
186 plist_to_xml(dict, &xml, &length);
187 if (!xml) {
188 return res;
189 }
190
191 FILE *fd = fopen(cfgfile, "w");
192 if (!fd) {
193 free(xml);
194 return res;
195 }
196
197 if (fwrite(xml, 1, length, fd) == length) {
198 res = 0;
199 } else {
200 fprintf(stderr, "%s: ERROR: failed to write configuration to '%s'\n", __func__, cfgfile);
201 }
202 fclose(fd);
203
204 free(xml);
205#endif
206 return res;
207}
208
209static int config_read(const char *cfgfile, plist_t *dict)
210{
211 if (!cfgfile || !dict) {
212 return -1;
213 }
214
215 int res = -1;
216 FILE *fd = fopen(cfgfile, "r+");
217 if (!fd) {
218 return -1;
219 }
220
221 fseek(fd, 0, SEEK_END);
222 unsigned long int size = ftell(fd);
223 fseek(fd, 0, SEEK_SET);
224 unsigned char *contents = NULL;
225
226 contents = malloc(size);
227 if (fread(contents, 1, size, fd) != size) {
228 free(contents);
229 fclose(fd);
230 return -1;
231 }
232 plist_t plist = NULL;
233
234 if (!memcmp(contents, "bplist00", 8)) {
235 plist_from_bin((const char*)contents, (uint32_t)size, &plist);
236 fclose(fd);
237 } else {
238 if (memchr(contents, '<', size)) {
239 plist_from_xml((const char*)contents, (uint32_t)size, &plist);
240 }
241 if (plist) {
242 fclose(fd);
243 } else {
244 // try parsing old format config file
245 char line[256];
246 fseek(fd, 0, SEEK_SET);
247 while (fgets(line, 256, fd)) {
248 size_t llen = strlen(line)-1;
249 while ((llen > 0) && ((line[llen] == '\n') || (line[llen] == '\r'))) {
250 line[llen] = '\0';
251 }
252 if (!strncmp(line, "HostID=", 7)) {
253 plist = plist_new_dict();
254 plist_dict_insert_item(plist, "HostID", plist_new_string(line+7));
255 break;
256 }
257 }
258 fclose(fd);
259 if (plist) {
260 // write new format config
261 config_write(cfgfile, plist);
262 }
263 }
264 }
265 free(contents);
266 if (plist) {
267 *dict = plist;
268 res = 0;
269 }
270 return res;
271}
44 272
45/** 273/**
46 * Creates a freedesktop compatible configuration directory. 274 * Creates a freedesktop compatible configuration directory.
47 */ 275 */
48static void userpref_create_config_dir(void) 276static void userpref_create_config_dir(void)
49{ 277{
50 gchar *config_dir = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, NULL); 278 const char *config_path = userpref_get_config_dir();
51 279 struct stat st;
52 if (!g_file_test(config_dir, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_DIR))) 280 if (stat(config_path, &st) != 0) {
53 g_mkdir_with_parents(config_dir, 0755); 281 mkdir_with_parents(config_path, 0755);
54 282 }
55 g_free(config_dir);
56} 283}
57 284
58static int get_rand(int min, int max) 285static int get_rand(int min, int max)
@@ -94,10 +321,8 @@ static char *userpref_generate_host_id()
94 */ 321 */
95static int userpref_set_host_id(const char *host_id) 322static int userpref_set_host_id(const char *host_id)
96{ 323{
97 GKeyFile *key_file; 324 const char *config_path;
98 gsize length; 325 char *config_file;
99 gchar *buf, *config_file;
100 GIOChannel *file;
101 326
102 if (!host_id) 327 if (!host_id)
103 return 0; 328 return 0;
@@ -105,24 +330,34 @@ static int userpref_set_host_id(const char *host_id)
105 /* Make sure config directory exists */ 330 /* Make sure config directory exists */
106 userpref_create_config_dir(); 331 userpref_create_config_dir();
107 332
333 config_path = userpref_get_config_dir();
334 config_file = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_CONF_FILE)+1);
335 strcpy(config_file, config_path);
336 strcat(config_file, DIR_SEP_S);
337 strcat(config_file, LIBIMOBILEDEVICE_CONF_FILE);
338
108 /* Now parse file to get the HostID */ 339 /* Now parse file to get the HostID */
109 key_file = g_key_file_new(); 340 plist_t config = NULL;
341 config_read(config_file, &config);
342 if (!config) {
343 config = plist_new_dict();
344 plist_dict_insert_item(config, "HostID", plist_new_string(host_id));
345 } else {
346 plist_t n = plist_dict_get_item(config, "HostID");
347 if (n) {
348 plist_set_string_val(n, host_id);
349 } else {
350 plist_dict_insert_item(config, "HostID", plist_new_string(host_id));
351 }
352 }
110 353
111 /* Store in config file */ 354 /* Store in config file */
112 debug_info("setting hostID to %s", host_id); 355 debug_info("setting hostID to %s", host_id);
113 g_key_file_set_value(key_file, "Global", "HostID", host_id); 356
114 357 config_write(config_file, config);
115 /* Write config file on disk */ 358 plist_free(config);
116 buf = g_key_file_to_data(key_file, &length, NULL); 359
117 config_file = 360 free(config_file);
118 g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_CONF_FILE, NULL);
119 file = g_io_channel_new_file(config_file, "w", NULL);
120 g_free(config_file);
121 g_io_channel_write_chars(file, buf, length, NULL, NULL);
122 g_io_channel_shutdown(file, TRUE, NULL);
123 g_io_channel_unref(file);
124
125 g_key_file_free(key_file);
126 return 1; 361 return 1;
127} 362}
128 363
@@ -135,23 +370,25 @@ static int userpref_set_host_id(const char *host_id)
135 */ 370 */
136void userpref_get_host_id(char **host_id) 371void userpref_get_host_id(char **host_id)
137{ 372{
138 gchar *config_file; 373 const char *config_path;
139 GKeyFile *key_file; 374 char *config_file;
140 gchar *loc_host_id;
141 375
142 config_file = 376 config_path = userpref_get_config_dir();
143 g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_CONF_FILE, NULL); 377 config_file = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_CONF_FILE)+1);
378 strcpy(config_file, config_path);
379 strcat(config_file, DIR_SEP_S);
380 strcat(config_file, LIBIMOBILEDEVICE_CONF_FILE);
144 381
145 /* now parse file to get the HostID */ 382 /* now parse file to get the HostID */
146 key_file = g_key_file_new(); 383 plist_t config = NULL;
147 if (g_key_file_load_from_file(key_file, config_file, G_KEY_FILE_KEEP_COMMENTS, NULL)) { 384 if (config_read(config_file, &config) == 0) {
148 loc_host_id = g_key_file_get_value(key_file, "Global", "HostID", NULL); 385 plist_t n_host_id = plist_dict_get_item(config, "HostID");
149 if (loc_host_id) 386 if (n_host_id && (plist_get_node_type(n_host_id) == PLIST_STRING)) {
150 *host_id = strdup((char *) loc_host_id); 387 plist_get_string_val(n_host_id, host_id);
151 g_free(loc_host_id); 388 }
152 } 389 }
153 g_key_file_free(key_file); 390 plist_free(config);
154 g_free(config_file); 391 free(config_file);
155 392
156 if (!*host_id) { 393 if (!*host_id) {
157 /* no config, generate host_id */ 394 /* no config, generate host_id */
@@ -173,15 +410,23 @@ void userpref_get_host_id(char **host_id)
173int userpref_has_device_public_key(const char *uuid) 410int userpref_has_device_public_key(const char *uuid)
174{ 411{
175 int ret = 0; 412 int ret = 0;
176 gchar *config_file; 413 const char *config_path;
414 char *config_file;
415 struct stat st;
416
417 if (!uuid) return 0;
177 418
178 /* first get config file */ 419 /* first get config file */
179 gchar *device_file = g_strconcat(uuid, ".pem", NULL); 420 config_path = userpref_get_config_dir();
180 config_file = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, device_file, NULL); 421 config_file = (char*)malloc(strlen(config_path)+1+strlen(uuid)+4+1);
181 if (g_file_test(config_file, (G_FILE_TEST_EXISTS | G_FILE_TEST_IS_REGULAR))) 422 strcpy(config_file, config_path);
423 strcat(config_file, DIR_SEP_S);
424 strcat(config_file, uuid);
425 strcat(config_file, ".pem");
426
427 if ((stat(config_file, &st) == 0) && S_ISREG(st.st_mode))
182 ret = 1; 428 ret = 1;
183 g_free(config_file); 429 free(config_file);
184 g_free(device_file);
185 return ret; 430 return ret;
186} 431}
187 432
@@ -202,10 +447,13 @@ int userpref_has_device_public_key(const char *uuid)
202 */ 447 */
203userpref_error_t userpref_get_paired_uuids(char ***list, unsigned int *count) 448userpref_error_t userpref_get_paired_uuids(char ***list, unsigned int *count)
204{ 449{
205 GDir *config_dir; 450 struct slist_t {
206 gchar *config_path; 451 char *name;
207 const gchar *dir_file; 452 void *next;
208 GList *uuids = NULL; 453 };
454 DIR *config_dir;
455 const char *config_path;
456 struct slist_t *uuids = NULL;
209 unsigned int i; 457 unsigned int i;
210 unsigned int found = 0; 458 unsigned int found = 0;
211 459
@@ -218,29 +466,44 @@ userpref_error_t userpref_get_paired_uuids(char ***list, unsigned int *count)
218 *count = 0; 466 *count = 0;
219 } 467 }
220 468
221 config_path = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, NULL); 469 config_path = userpref_get_config_dir();
222 470 config_dir = opendir(config_path);
223 config_dir = g_dir_open(config_path,0,NULL);
224 if (config_dir) { 471 if (config_dir) {
225 while ((dir_file = g_dir_read_name(config_dir))) { 472 struct dirent *entry;
226 if (g_str_has_suffix(dir_file, ".pem") && (strlen(dir_file) == 44)) { 473 struct slist_t *listp = uuids;
227 uuids = g_list_append(uuids, g_strndup(dir_file, strlen(dir_file)-4)); 474 while ((entry = readdir(config_dir))) {
475 char *ext = strstr(entry->d_name, ".pem");
476 if (ext && ((ext - entry->d_name) == 40) && (strlen(entry->d_name) == 44)) {
477 struct slist_t *ne = (struct slist_t*)malloc(sizeof(struct slist_t));
478 ne->name = (char*)malloc(41);
479 strncpy(ne->name, entry->d_name, 40);
480 ne->name[40] = 0;
481 ne->next = NULL;
482 if (!listp) {
483 listp = ne;
484 uuids = listp;
485 } else {
486 listp->next = ne;
487 listp = listp->next;
488 }
228 found++; 489 found++;
229 } 490 }
230 } 491 }
231 g_dir_close(config_dir); 492 closedir(config_dir);
232 } 493 }
233 *list = (char**)malloc(sizeof(char*) * (found+1)); 494 *list = (char**)malloc(sizeof(char*) * (found+1));
234 for (i = 0; i < found; i++) { 495 i = 0;
235 (*list)[i] = g_list_nth_data(uuids, i); 496 while (uuids) {
497 (*list)[i++] = uuids->name;
498 struct slist_t *old = uuids;
499 uuids = uuids->next;
500 free(old);
236 } 501 }
237 (*list)[i] = NULL; 502 (*list)[i] = NULL;
238 503
239 if (count) { 504 if (count) {
240 *count = found; 505 *count = found;
241 } 506 }
242 g_list_free(uuids);
243 g_free(config_path);
244 507
245 return USERPREF_E_SUCCESS; 508 return USERPREF_E_SUCCESS;
246} 509}
@@ -266,15 +529,18 @@ userpref_error_t userpref_set_device_public_key(const char *uuid, gnutls_datum_t
266 userpref_create_config_dir(); 529 userpref_create_config_dir();
267 530
268 /* build file path */ 531 /* build file path */
269 gchar *device_file = g_strconcat(uuid, ".pem", NULL); 532 const char *config_path = userpref_get_config_dir();
270 gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, device_file, NULL); 533 char *pem = (char*)malloc(strlen(config_path)+1+strlen(uuid)+4+1);
534 strcpy(pem, config_path);
535 strcat(pem, DIR_SEP_S);
536 strcat(pem, uuid);
537 strcat(pem, ".pem");
271 538
272 /* store file */ 539 /* store file */
273 FILE *pFile = fopen(pem, "wb"); 540 FILE *pFile = fopen(pem, "wb");
274 fwrite(public_key.data, 1, public_key.size, pFile); 541 fwrite(public_key.data, 1, public_key.size, pFile);
275 fclose(pFile); 542 fclose(pFile);
276 g_free(pem); 543 free(pem);
277 g_free(device_file);
278 544
279 return USERPREF_E_SUCCESS; 545 return USERPREF_E_SUCCESS;
280} 546}
@@ -292,14 +558,17 @@ userpref_error_t userpref_remove_device_public_key(const char *uuid)
292 return USERPREF_E_SUCCESS; 558 return USERPREF_E_SUCCESS;
293 559
294 /* build file path */ 560 /* build file path */
295 gchar *device_file = g_strconcat(uuid, ".pem", NULL); 561 const char *config_path = userpref_get_config_dir();
296 gchar *pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, device_file, NULL); 562 char *pem = (char*)malloc(strlen(config_path)+1+strlen(uuid)+4+1);
563 strcpy(pem, config_path);
564 strcat(pem, DIR_SEP_S);
565 strcat(pem, uuid);
566 strcat(pem, ".pem");
297 567
298 /* remove file */ 568 /* remove file */
299 g_remove(pem); 569 remove(pem);
300 570
301 g_free(pem); 571 free(pem);
302 g_free(device_file);
303 572
304 return USERPREF_E_SUCCESS; 573 return USERPREF_E_SUCCESS;
305} 574}
@@ -314,18 +583,50 @@ userpref_error_t userpref_remove_device_public_key(const char *uuid)
314 */ 583 */
315static int userpref_get_file_contents(const char *file, gnutls_datum_t * data) 584static int userpref_get_file_contents(const char *file, gnutls_datum_t * data)
316{ 585{
317 gboolean success; 586 int success;
318 gsize size; 587 unsigned long int size = 0;
319 char *content; 588 unsigned char *content = NULL;
320 gchar *filepath; 589 const char *config_path;
590 char *filepath;
591 FILE *fd;
321 592
322 if (NULL == file || NULL == data) 593 if (NULL == file || NULL == data)
323 return 0; 594 return 0;
324 595
325 /* Read file */ 596 /* Read file */
326 filepath = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, file, NULL); 597 config_path = userpref_get_config_dir();
327 success = g_file_get_contents(filepath, &content, &size, NULL); 598 filepath = (char*)malloc(strlen(config_path)+1+strlen(file)+1);
328 g_free(filepath); 599 strcpy(filepath, config_path);
600 strcat(filepath, DIR_SEP_S);
601 strcat(filepath, file);
602
603 fd = fopen(filepath, "rb");
604 if (fd) {
605 fseek(fd, 0, SEEK_END);
606 size = ftell(fd);
607 fseek(fd, 0, SEEK_SET);
608
609 // prevent huge files
610 if (size > 0xFFFFFF) {
611 fprintf(stderr, "%s: file is too big (> 16MB). Refusing to read the contents to memory!", __func__);
612 } else {
613 size_t p = 0;
614 content = (unsigned char*)malloc(size);
615 while (!feof(fd)) {
616 p += fread(content+p, 1, size-p, fd);
617 if (ferror(fd) != 0) {
618 break;
619 }
620 if (p >= size) {
621 success = 1;
622 break;
623 }
624 }
625 }
626 fclose(fd);
627 }
628
629 free(filepath);
329 630
330 /* Add it to the gnutls_datnum_t structure */ 631 /* Add it to the gnutls_datnum_t structure */
331 if (success) { 632 if (success) {
@@ -549,8 +850,8 @@ userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls
549 if (userpref_get_file_contents(LIBIMOBILEDEVICE_ROOT_CERTIF, pem_root_cert) && userpref_get_file_contents(LIBIMOBILEDEVICE_HOST_CERTIF, pem_host_cert)) 850 if (userpref_get_file_contents(LIBIMOBILEDEVICE_ROOT_CERTIF, pem_root_cert) && userpref_get_file_contents(LIBIMOBILEDEVICE_HOST_CERTIF, pem_host_cert))
550 return USERPREF_E_SUCCESS; 851 return USERPREF_E_SUCCESS;
551 else { 852 else {
552 g_free(pem_root_cert->data); 853 gnutls_free(pem_root_cert->data);
553 g_free(pem_host_cert->data); 854 gnutls_free(pem_host_cert->data);
554 } 855 }
555 return USERPREF_E_INVALID_CONF; 856 return USERPREF_E_INVALID_CONF;
556} 857}
@@ -570,7 +871,8 @@ userpref_error_t userpref_get_certs_as_pem(gnutls_datum_t *pem_root_cert, gnutls
570userpref_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) 871userpref_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)
571{ 872{
572 FILE *pFile; 873 FILE *pFile;
573 gchar *pem; 874 char *pem;
875 const char *config_path;
574 876
575 if (!root_key || !host_key || !root_cert || !host_cert) 877 if (!root_key || !host_key || !root_cert || !host_cert)
576 return USERPREF_E_INVALID_ARG; 878 return USERPREF_E_INVALID_ARG;
@@ -578,30 +880,44 @@ userpref_error_t userpref_set_keys_and_certs(gnutls_datum_t * root_key, gnutls_d
578 /* Make sure config directory exists */ 880 /* Make sure config directory exists */
579 userpref_create_config_dir(); 881 userpref_create_config_dir();
580 882
883 config_path = userpref_get_config_dir();
884
581 /* Now write keys and certificates to disk */ 885 /* Now write keys and certificates to disk */
582 pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_ROOT_PRIVKEY, NULL); 886 pem = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_ROOT_PRIVKEY)+1);
887 strcpy(pem, config_path);
888 strcat(pem, DIR_SEP_S);
889 strcat(pem, LIBIMOBILEDEVICE_ROOT_PRIVKEY);
583 pFile = fopen(pem, "wb"); 890 pFile = fopen(pem, "wb");
584 fwrite(root_key->data, 1, root_key->size, pFile); 891 fwrite(root_key->data, 1, root_key->size, pFile);
585 fclose(pFile); 892 fclose(pFile);
586 g_free(pem); 893 free(pem);
587 894
588 pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_HOST_PRIVKEY, NULL); 895 pem = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_HOST_PRIVKEY)+1);
896 strcpy(pem, config_path);
897 strcat(pem, DIR_SEP_S);
898 strcat(pem, LIBIMOBILEDEVICE_HOST_PRIVKEY);
589 pFile = fopen(pem, "wb"); 899 pFile = fopen(pem, "wb");
590 fwrite(host_key->data, 1, host_key->size, pFile); 900 fwrite(host_key->data, 1, host_key->size, pFile);
591 fclose(pFile); 901 fclose(pFile);
592 g_free(pem); 902 free(pem);
593 903
594 pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_ROOT_CERTIF, NULL); 904 pem = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_ROOT_CERTIF)+1);
905 strcpy(pem, config_path);
906 strcat(pem, DIR_SEP_S);
907 strcat(pem, LIBIMOBILEDEVICE_ROOT_CERTIF);
595 pFile = fopen(pem, "wb"); 908 pFile = fopen(pem, "wb");
596 fwrite(root_cert->data, 1, root_cert->size, pFile); 909 fwrite(root_cert->data, 1, root_cert->size, pFile);
597 fclose(pFile); 910 fclose(pFile);
598 g_free(pem); 911 free(pem);
599 912
600 pem = g_build_path(G_DIR_SEPARATOR_S, g_get_user_config_dir(), LIBIMOBILEDEVICE_CONF_DIR, LIBIMOBILEDEVICE_HOST_CERTIF, NULL); 913 pem = (char*)malloc(strlen(config_path)+1+strlen(LIBIMOBILEDEVICE_HOST_CERTIF)+1);
914 strcpy(pem, config_path);
915 strcat(pem, DIR_SEP_S);
916 strcat(pem, LIBIMOBILEDEVICE_HOST_CERTIF);
601 pFile = fopen(pem, "wb"); 917 pFile = fopen(pem, "wb");
602 fwrite(host_cert->data, 1, host_cert->size, pFile); 918 fwrite(host_cert->data, 1, host_cert->size, pFile);
603 fclose(pFile); 919 fclose(pFile);
604 g_free(pem); 920 free(pem);
605 921
606 return USERPREF_E_SUCCESS; 922 return USERPREF_E_SUCCESS;
607} 923}