1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2006-2010 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA
23 #include <sys/types.h>
26 #include <gpg-error.h>
29 #include "pwmd_error.h"
34 gboolean
do_cache_push(const gchar
*filename
, const void *password
, gsize
);
36 void clear_rcfile_keys()
42 groups
= g_key_file_get_groups(keyfileh
, &n
);
44 for (p
= groups
; *p
; p
++) {
47 if (g_key_file_has_key(keyfileh
, *p
, "key", &rc
) == TRUE
)
48 g_key_file_set_string(keyfileh
, *p
, "key", "");
54 static gpg_error_t
_getline(struct crypto_s
*crypto
, const gchar
*file
)
60 if (stat(file
, &st
) == -1)
61 return gpg_error_from_errno(errno
);
63 crypto
->tkey_len
= st
.st_size
;
64 crypto
->tkey
= gcry_malloc(crypto
->tkey_len
);
67 return GPG_ERR_ENOMEM
;
69 fd
= open(file
, O_RDONLY
);
72 return gpg_error_from_errno(errno
);
74 gsize len
= read(fd
, crypto
->tkey
, crypto
->tkey_len
);
76 if (len
!= crypto
->tkey_len
)
77 rc
= GPG_ERR_INCOMPLETE_LINE
;
83 gpg_error_t
parse_rcfile_keyfile(struct crypto_s
*crypto
, const gchar
*filename
,
87 gchar
*t
, *file
= NULL
;
90 // parse_rcfile_keys()
91 if (import
== FALSE
) {
92 if (g_key_file_has_key(keyfileh
, filename
, "key_file", &rv
) == TRUE
) {
93 file
= g_key_file_get_string(keyfileh
, filename
, "key_file", &rv
);
97 log_write("%s: key_file: %s", rcfile
, rv
->message
);
101 return GPG_ERR_ENFILE
;
104 t
= expand_homedir(file
);
108 log_write("%s(%i): %s", __FILE__
, __LINE__
, strerror(ENOMEM
));
109 return GPG_ERR_ENOMEM
;
117 log_write("%s: key_file: %s", rcfile
, rv
->message
);
123 return GPG_ERR_UNKNOWN_ERRNO
;
127 /* -I or -C. The filename is a key file. */
128 file
= g_strdup(filename
);
131 log_write("%s(%i): %s", __FILE__
, __LINE__
, strerror(ENOMEM
));
132 return GPG_ERR_ENOMEM
;
137 return GPG_ERR_ENFILE
;
139 rc
= _getline(crypto
, file
);
142 log_write("%s: %s: %s", filename
, file
, pwmd_strerror(rc
));
148 gchar
*get_key_file_string(const gchar
*section
, const gchar
*what
)
153 MUTEX_LOCK(&rcfile_mutex
);
155 if (g_key_file_has_key(keyfileh
, section
, what
, NULL
) == TRUE
) {
156 val
= g_key_file_get_string(keyfileh
, section
, what
, &grc
);
159 log_write("%s(%i): %s", __FILE__
, __LINE__
, grc
->message
);
164 if (g_key_file_has_key(keyfileh
, "global", what
, NULL
) == TRUE
) {
165 val
= g_key_file_get_string(keyfileh
, "global", what
, &grc
);
168 log_write("%s(%i): %s", __FILE__
, __LINE__
, grc
->message
);
174 MUTEX_UNLOCK(&rcfile_mutex
);
178 gint
get_key_file_integer(const gchar
*section
, const gchar
*what
)
183 MUTEX_LOCK(&rcfile_mutex
);
185 if (g_key_file_has_key(keyfileh
, section
? section
: "global", what
, NULL
) == TRUE
) {
186 val
= g_key_file_get_integer(keyfileh
, section
? section
: "global", what
, &grc
);
189 log_write("%s(%i): %s", __FILE__
, __LINE__
, grc
->message
);
194 if (g_key_file_has_key(keyfileh
, "global", what
, NULL
) == TRUE
) {
195 val
= g_key_file_get_integer(keyfileh
, "global", what
, &grc
);
198 log_write("%s(%i): %s", __FILE__
, __LINE__
, grc
->message
);
204 MUTEX_UNLOCK(&rcfile_mutex
);
208 gdouble
get_key_file_double(const gchar
*section
, const gchar
*what
)
213 MUTEX_LOCK(&rcfile_mutex
);
215 if (g_key_file_has_key(keyfileh
, section
? section
: "global", what
, NULL
) == TRUE
) {
216 val
= g_key_file_get_double(keyfileh
, section
? section
: "global", what
, &grc
);
219 log_write("%s(%i): %s", __FILE__
, __LINE__
, grc
->message
);
224 if (g_key_file_has_key(keyfileh
, "global", what
, NULL
) == TRUE
) {
225 val
= g_key_file_get_double(keyfileh
, "global", what
, &grc
);
228 log_write("%s(%i): %s", __FILE__
, __LINE__
, grc
->message
);
234 MUTEX_UNLOCK(&rcfile_mutex
);
238 gboolean
get_key_file_boolean(const gchar
*section
, const gchar
*what
)
240 gboolean val
= FALSE
;
243 MUTEX_LOCK(&rcfile_mutex
);
245 if (g_key_file_has_key(keyfileh
, section
? section
: "global", what
, NULL
)
247 val
= g_key_file_get_boolean(keyfileh
, section
? section
: "global",
251 log_write("%s(%i): %s", __FILE__
, __LINE__
, grc
->message
);
256 if (g_key_file_has_key(keyfileh
, "global", what
, NULL
) == TRUE
) {
257 val
= g_key_file_get_boolean(keyfileh
, "global", what
, &grc
);
260 log_write("%s(%i): %s", __FILE__
, __LINE__
, grc
->message
);
266 MUTEX_UNLOCK(&rcfile_mutex
);
270 gboolean
parse_rcfile_keys()
277 groups
= g_key_file_get_groups(keyfileh
, &n
);
279 for (p
= groups
; *p
; p
++) {
282 if (g_key_file_has_key(keyfileh
, *p
, "key", &rv
) == TRUE
) {
283 str
= g_key_file_get_string(keyfileh
, *p
, "key", &rv
);
287 log_write("%s: key: %s", rcfile
, rv
->message
);
294 do_cache_push(*p
, str
, strlen(str
));
300 log_write("%s: key: %s", rcfile
, rv
->message
);
305 struct crypto_s
*crypto
= g_malloc0(sizeof(struct crypto_s
));
306 gpg_error_t rc
= parse_rcfile_keyfile(crypto
, *p
, FALSE
);
309 cleanup_crypto(&crypto
);
313 do_cache_push(*p
, crypto
->tkey
, crypto
->tkey_len
);
314 cleanup_crypto(&crypto
);
321 GKeyFile
*parse_rcfile(gboolean specified
)
323 GKeyFile
*kf
= g_key_file_new();
326 g_key_file_set_list_separator(kf
, ',');
328 if (g_key_file_load_from_file(kf
, rcfile
, G_KEY_FILE_NONE
, &rc
) == FALSE
) {
329 log_write("%s: %s", rcfile
, rc
->message
);
331 if (cmdline
&& specified
) {
336 if (rc
->code
&& rc
->code
!= G_FILE_ERROR_NOENT
) {
342 set_rcfile_defaults(kf
);
346 void setup_logging(GKeyFile
*kf
)
348 gboolean n
= g_key_file_get_boolean(kf
, "global", "enable_logging", NULL
);
351 gchar
*p
= g_key_file_get_string(kf
, "global", "log_path", NULL
);
357 g_snprintf(buf
, sizeof(buf
), "%s%s", g_get_home_dir(), p
--);
363 logfile
= g_strdup(buf
);
373 log_syslog
= g_key_file_get_boolean(kf
, "global", "syslog", NULL
);
377 * Make sure all settings are set to either the specified setting or a
380 void set_rcfile_defaults(GKeyFile
*kf
)
384 if (g_key_file_has_key(kf
, "global", "socket_path", NULL
) == FALSE
) {
385 g_snprintf(buf
, sizeof(buf
), "~/.pwmd/socket");
386 g_key_file_set_string(kf
, "global", "socket_path", buf
);
389 if (g_key_file_has_key(kf
, "global", "data_directory", NULL
) == FALSE
) {
390 g_snprintf(buf
, sizeof(buf
), "~/.pwmd/data");
391 g_key_file_set_string(kf
, "global", "data_directory", buf
);
394 if (g_key_file_has_key(kf
, "global", "backup", NULL
) == FALSE
)
395 g_key_file_set_boolean(kf
, "global", "backup", TRUE
);
397 if (g_key_file_has_key(kf
, "global", "log_path", NULL
) == FALSE
) {
398 g_snprintf(buf
, sizeof(buf
), "~/.pwmd/log");
399 g_key_file_set_string(kf
, "global", "log_path", buf
);
402 if (g_key_file_has_key(kf
, "global", "enable_logging", NULL
) == FALSE
)
403 g_key_file_set_boolean(kf
, "global", "enable_logging", FALSE
);
406 if (g_key_file_has_key(kf
, "global", "disable_mlockall", NULL
) == FALSE
)
407 g_key_file_set_boolean(kf
, "global", "disable_mlockall", TRUE
);
410 if (g_key_file_has_key(kf
, "global", "cache_timeout", NULL
) == FALSE
)
411 g_key_file_set_integer(kf
, "global", "cache_timeout", -1);
413 if (g_key_file_has_key(kf
, "global", "iterations", NULL
) == FALSE
||
414 g_key_file_get_double(kf
, "global", "iterations", 0) < 0L)
415 g_key_file_set_double(kf
, "global", "iterations", 1UL);
417 if (g_key_file_has_key(kf
, "global", "disable_list_and_dump", NULL
) == FALSE
)
418 g_key_file_set_boolean(kf
, "global", "disable_list_and_dump", FALSE
);
420 if (g_key_file_has_key(kf
, "global", "iteration_progress", NULL
) == FALSE
)
421 g_key_file_set_double(kf
, "global", "iteration_progress", 1000ULL);
423 if (g_key_file_has_key(kf
, "global", "compression_level", NULL
) == FALSE
)
424 g_key_file_set_integer(kf
, "global", "compression_level", 6);
426 if (g_key_file_has_key(kf
, "global", "recursion_depth", NULL
) == FALSE
)
427 g_key_file_set_integer(kf
, "global", "recursion_depth", DEFAULT_RECURSION_DEPTH
);
429 if (g_key_file_has_key(kf
, "global", "zlib_bufsize", NULL
) == FALSE
)
430 g_key_file_set_integer(kf
, "global", "zlib_bufsize", DEFAULT_ZLIB_BUFSIZE
);
432 zlib_bufsize
= (guint
)g_key_file_get_integer(kf
, "global", "zlib_bufsize", NULL
);
434 max_recursion_depth
= g_key_file_get_integer(kf
, "global", "recursion_depth", NULL
);
435 disable_list_and_dump
= g_key_file_get_boolean(kf
, "global", "disable_list_and_dump", NULL
);
438 disable_mlock
= g_key_file_get_boolean(kf
, "global", "disable_mlockall", NULL
);
441 if (g_key_file_has_key(kf
, "global", "syslog", NULL
) == FALSE
)
442 g_key_file_set_boolean(kf
, "global", "syslog", FALSE
);
444 if (g_key_file_has_key(kf
, "global", "keepalive", NULL
) == FALSE
)
445 g_key_file_set_integer(kf
, "global", "keepalive", DEFAULT_KEEPALIVE_TO
);
448 if (g_key_file_has_key(kf
, "global", "enable_pinentry", NULL
) == FALSE
)
449 g_key_file_set_boolean(kf
, "global", "enable_pinentry", TRUE
);
451 if (g_key_file_has_key(kf
, "global", "pinentry_timeout", NULL
) == FALSE
)
452 g_key_file_set_integer(kf
, "global", "pinentry_timeout",
453 DEFAULT_PIN_TIMEOUT
);
455 if (g_key_file_has_key(kf
, "global", "pinentry_path", NULL
) == FALSE
)
456 g_key_file_set_string(kf
, "global", "pinentry_path", PINENTRY_PATH
);
459 if (g_key_file_has_key(kf
, "global", "xfer_progress", NULL
) == FALSE
)
460 g_key_file_set_integer(kf
, "global", "xfer_progress", 8196);
462 if (g_key_file_has_key(kf
, "global", "cipher", NULL
) == FALSE
)
463 g_key_file_set_string(kf
, "global", "cipher", "AES256");
465 if (g_key_file_has_key(kf
, "global", "log_level", NULL
) == FALSE
)
466 g_key_file_set_integer(kf
, "global", "log_level", 0);
468 if (!g_key_file_has_key(kf
, "global", "allowed", NULL
)) {
469 const gchar
*users
[] = { g_get_user_name(), NULL
};
471 g_key_file_set_string_list(kf
, "global", "allowed", users
, 1);