Fix compile time warnings.
[pwmd.git] / src / pwmd.c
blob39f4e68acaf31507d81ba271afbafc4f399caa89
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006-2011 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
19 #ifdef HAVE_CONFIG_H
20 #include <config.h>
21 #endif
23 #include <stdio.h>
24 #include <stdlib.h>
25 #include <unistd.h>
26 #include <err.h>
27 #include <ctype.h>
28 #include <string.h>
29 #include <sys/un.h>
30 #include <signal.h>
31 #include <stdarg.h>
32 #include <string.h>
33 #include <sys/wait.h>
34 #include <fcntl.h>
35 #include <pwd.h>
36 #include <grp.h>
37 #include <glib.h>
38 #include <glib/gprintf.h>
39 #include <glib/gstdio.h>
40 #include <sys/mman.h>
41 #include <termios.h>
42 #include <assert.h>
43 #include <syslog.h>
44 #include <zlib.h>
45 #include <gcrypt.h>
46 #include <netinet/in.h>
47 #include <arpa/inet.h>
48 #include <netdb.h>
49 #include <sys/time.h>
50 #include <sys/resource.h>
52 #ifdef TM_IN_SYS_TIME
53 #include <sys/time.h>
54 #else
55 #include <time.h>
56 #endif
58 #include "mem.h"
59 #include "xml.h"
60 #include "common.h"
62 #ifdef WITH_PINENTRY
63 #include "pinentry.h"
64 #endif
66 #include "commands.h"
67 #include "pwmd_error.h"
68 #include "cache.h"
69 #include "misc.h"
70 #include "pwmd.h"
71 #include "mutex.h"
72 #include "rcfile.h"
74 GCRY_THREAD_OPTION_PTH_IMPL;
76 static void *reload_rcfile_thread(void *arg)
78 gboolean b = disable_list_and_dump;
79 gchar **users = g_key_file_get_string_list(keyfileh, "global", "allowed",
80 NULL, NULL);
81 GKeyFile *k;
82 pth_attr_t attr = pth_attr_of(pth_self());
84 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
85 pth_attr_destroy(attr);
86 MUTEX_LOCK(&rcfile_mutex);
87 log_write(_("reloading configuration file '%s'"), rcfile);
88 k = parse_rcfile(FALSE);
90 if (!k)
91 goto done;
93 g_key_file_free(keyfileh);
94 keyfileh = k;
95 parse_rcfile_keys(FALSE);
96 clear_rcfile_keys();
97 send_status_all(STATUS_CONFIG);
98 done:
99 disable_list_and_dump = !disable_list_and_dump ? b : TRUE;
100 g_key_file_set_string_list(keyfileh, "global", "allowed",
101 (const gchar **)users, g_strv_length(users));
102 g_strfreev(users);
103 MUTEX_UNLOCK(&rcfile_mutex);
104 return NULL;
107 static void reload_rcfile()
109 pth_t tid;
110 pth_attr_t attr = pth_attr_new();
111 gpg_error_t rc;
113 pth_attr_init(attr);
114 pth_attr_set(attr, PTH_ATTR_JOINABLE, 0);
115 tid = pth_spawn(attr, reload_rcfile_thread, NULL);
116 rc = gpg_error_from_syserror();
117 pth_attr_destroy(attr);
119 if (!tid)
120 log_write("%s(%i): pth_spawn(): %s", __FILE__, __LINE__,
121 pwmd_strerror(rc));
124 gpg_error_t send_error(assuan_context_t ctx, gpg_error_t e)
126 gpg_err_code_t n = gpg_err_code(e);
127 gpg_error_t code = gpg_err_make(PWMD_ERR_SOURCE, n);
128 struct client_s *client = assuan_get_pointer(ctx);
130 if (client)
131 client->last_rc = e;
133 if (!e)
134 return assuan_process_done(ctx, 0);
136 if (!ctx) {
137 log_write("%s", pwmd_strerror(e));
138 return e;
141 if (n == EPWMD_LIBXML_ERROR) {
142 xmlErrorPtr xe = client->xml_error;
144 if (!xe)
145 xe = xmlGetLastError();
147 e = assuan_process_done(ctx, assuan_set_error(ctx, code, xe->message));
148 log_write("%s", xe->message);
150 if (xe == client->xml_error)
151 xmlResetError(xe);
152 else
153 xmlResetLastError();
155 client->xml_error = NULL;
156 return e;
159 return assuan_process_done(ctx, assuan_set_error(ctx, code, pwmd_strerror(e)));
162 void log_write(const gchar *fmt, ...)
164 gchar *args, *line;
165 va_list ap;
166 struct tm *tm;
167 time_t now;
168 gchar tbuf[21];
169 gint fd = -1;
170 gchar *name;
171 gchar buf[255];
172 pth_t tid = pth_self();
173 pth_attr_t attr;
175 if ((!logfile && !isatty(STDERR_FILENO) && log_syslog == FALSE) || !fmt)
176 return;
178 if (!cmdline && logfile) {
179 if ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600)) == -1) {
180 warn("%s", logfile);
182 if (!log_syslog)
183 return;
187 va_start(ap, fmt);
189 if (g_vasprintf(&args, fmt, ap) == -1) {
190 if (logfile && fd != -1)
191 close(fd);
193 va_end(ap);
194 return;
197 va_end(ap);
199 if (cmdline) {
200 fprintf(stderr, "%s\n", args);
201 fflush(stderr);
202 g_free(args);
203 return;
206 attr = pth_attr_of(tid);
208 if (pth_attr_get(attr, PTH_ATTR_NAME, &name) == FALSE)
209 name = "unknown";
211 pth_attr_destroy(attr);
212 name = print_fmt(buf, sizeof(buf), "%s(%p): ", name, tid);
214 if (!cmdline && log_syslog == TRUE)
215 syslog(LOG_INFO, "%s%s", name, args);
217 time(&now);
218 tm = localtime(&now);
219 strftime(tbuf, sizeof(tbuf), "%b %d %Y %H:%M:%S ", tm);
220 tbuf[sizeof(tbuf) - 1] = 0;
222 if (args[strlen(args)-1] == '\n')
223 args[strlen(args)-1] = 0;
225 line = g_strdup_printf("%s %i %s%s\n", tbuf, getpid(), name, args);
226 g_free(args);
228 if (!line) {
229 if (logfile && fd != -1)
230 close(fd);
232 return;
235 if (logfile && fd != -1) {
236 pth_write(fd, line, strlen(line));
237 fsync(fd);
238 close(fd);
241 if (isatty(STDERR_FILENO)) {
242 fprintf(stdout, "%s", line);
243 fflush(stdout);
246 g_free(line);
249 static void setup_gcrypt()
251 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
253 if (!gcry_check_version("1.3.1"))
254 errx(EXIT_FAILURE, _("gcry_check_version(): Incompatible libgcrypt. Wanted %s, got %s."), GCRYPT_VERSION, gcry_check_version(NULL));
256 gcry_set_allocation_handler(g_malloc, g_malloc, NULL, g_realloc, g_free);
259 static gpg_error_t validate_peer(struct client_s *cl)
261 gchar **users;
262 gboolean allowed = FALSE;
263 pid_t pid;
264 gid_t gid;
265 uid_t uid;
266 gpg_error_t rc = assuan_get_peercred(cl->ctx, &pid, &uid, &gid);
268 if (rc)
269 return rc;
271 users = g_key_file_get_string_list(keyfileh, "global", "allowed", NULL, NULL);
273 if (users) {
274 for (gchar **p = users; *p; p++) {
275 struct passwd pw, *result;
276 struct group gr, *gresult;
277 char *buf;
279 if (*(*p) == '@') {
280 size_t len = sysconf(_SC_GETGR_R_SIZE_MAX);
282 if (len == -1)
283 len = 16384;
285 buf = g_malloc(len);
287 if (!buf) {
288 g_strfreev(users);
289 return GPG_ERR_ENOMEM;
292 if (!getgrnam_r(*(p)+1, &gr, buf, len, &gresult) && gresult) {
293 if (gresult->gr_gid == gid) {
294 g_free(buf);
295 allowed = TRUE;
296 break;
299 len = sysconf(_SC_GETPW_R_SIZE_MAX);
301 if (len == -1)
302 len = 16384;
304 gchar *tbuf = g_malloc(len);
306 for (gchar **t = gresult->gr_mem; *t; t++) {
307 if (!getpwnam_r(*t, &pw, tbuf, len, &result) && result) {
308 if (result->pw_uid == uid) {
309 g_free(buf);
310 allowed = TRUE;
311 break;
316 g_free(tbuf);
318 if (allowed)
319 break;
322 else {
323 size_t len = sysconf(_SC_GETPW_R_SIZE_MAX);
325 if (len == -1)
326 len = 16384;
328 buf = g_malloc(len);
330 if (!buf) {
331 g_strfreev(users);
332 return GPG_ERR_ENOMEM;
335 if (!getpwnam_r(*p, &pw, buf, len, &result) && result) {
336 if (result->pw_uid == uid) {
337 g_free(buf);
338 allowed = TRUE;
339 break;
344 g_free(buf);
347 g_strfreev(users);
350 log_write("peer %s: uid=%i, gid=%i, pid=%i",
351 allowed ? _("accepted") : _("rejected"), uid, gid,pid);
352 return allowed ? 0 : GPG_ERR_INV_USER_ID;
355 static gboolean new_connection(struct client_s *cl)
357 gpg_error_t rc;
358 gchar *ver;
359 gchar *str;
361 rc = assuan_init_socket_server_ext(&cl->ctx, cl->thd->fd, 2);
363 if (rc)
364 goto fail;
366 assuan_set_pointer(cl->ctx, cl);
367 ver = g_strdup_printf("%s", PACKAGE_STRING);
368 assuan_set_hello_line(cl->ctx, ver);
369 g_free(ver);
370 rc = register_commands(cl->ctx);
372 if (rc)
373 goto fail;
375 rc = assuan_accept(cl->ctx);
377 if (rc)
378 goto fail;
380 rc = validate_peer(cl);
382 /* May not be implemented on all platforms. */
383 if (rc && gpg_err_code(rc) != GPG_ERR_ASS_GENERAL)
384 goto fail;
386 str = get_key_file_string("global", "debug_file");
388 if (debugfp && str)
389 assuan_set_log_stream(cl->ctx, debugfp);
391 if (str)
392 g_free(str);
394 return TRUE;
396 fail:
397 log_write("%s", pwmd_strerror(rc));
398 return FALSE;
401 static void xml_error_cb(void *data, xmlErrorPtr e)
403 struct client_s *client = data;
406 * Keep the first reported error as the one to show in the error
407 * description. Reset in send_error().
409 if (client->xml_error)
410 return;
412 xmlCopyError(e, client->xml_error);
415 void close_file_header(file_header_internal_t *fh)
417 if (!fh)
418 return;
420 if (fh->fd != -1 || (cmdline == TRUE && fh->fd != STDOUT_FILENO))
421 close(fh->fd);
423 if (fh->doc)
424 gcry_free(fh->doc);
426 g_free(fh);
429 void cleanup_crypto(struct crypto_s **c)
431 struct crypto_s *cr = *c;
433 if (!cr)
434 return;
436 if (cr->iv) {
437 gcry_free(cr->iv);
438 cr->iv = NULL;
441 if (cr->key) {
442 gcry_free(cr->key);
443 cr->key = NULL;
446 if (cr->tkey) {
447 gcry_free(cr->tkey);
448 cr->tkey = NULL;
451 if (cr->tkey2) {
452 gcry_free(cr->tkey2);
453 cr->tkey2 = NULL;
456 if (cr->inbuf) {
457 gcry_free(cr->inbuf);
458 cr->inbuf = NULL;
461 if (cr->outbuf) {
462 gcry_free(cr->outbuf);
463 cr->outbuf = NULL;
466 close_file_header(cr->fh);
467 cr->fh = NULL;
469 if (cr->gh)
470 gcry_cipher_close(cr->gh);
472 cr->gh = NULL;
473 g_free(cr);
474 *c = NULL;
478 * This is called after a client_thread terminates. Set with
479 * pth_cleanup_push().
481 static void cleanup_cb(void *arg)
483 struct client_thread_s *cn = arg;
484 struct client_s *cl = cn->cl;
486 MUTEX_LOCK(&cn_mutex);
487 cn_thread_list = g_slist_remove(cn_thread_list, cn);
488 MUTEX_UNLOCK(&cn_mutex);
490 if (cn->msg_tid) {
491 MUTEX_LOCK(&cn->mp_mutex);
492 pth_cancel(cn->msg_tid);
493 MUTEX_UNLOCK(&cn->mp_mutex);
496 if (cn->mp) {
497 while (pth_msgport_pending(cn->mp)) {
498 pth_message_t *msg = pth_msgport_get(cn->mp);
500 g_free(msg->m_data);
501 g_free(msg);
504 pth_msgport_destroy(cn->mp);
507 if (!cl) {
508 if (cn->fd != -1)
509 close(cn->fd);
511 goto done;
514 if (!cl->freed)
515 cleanup_client(cl);
517 if (cl->ctx)
518 assuan_deinit_server(cl->ctx);
519 else if (cl->thd && cl->thd->fd != -1)
520 close(cl->thd->fd);
522 #ifdef WITH_PINENTRY
523 if (cl->pinentry)
524 cleanup_pinentry(cl->pinentry);
525 #endif
527 if (cl->crypto)
528 cleanup_crypto(&cl->crypto);
530 g_free(cl);
531 done:
532 log_write(_("exiting, fd=%i"), cn->fd);
533 g_free(cn);
534 send_status_all(STATUS_CLIENTS);
538 * Called every time a connection is made from init_new_connection(). This is
539 * the thread entry point.
541 static void *client_thread(void *data)
543 struct client_thread_s *thd = data;
544 struct client_s *cl = g_malloc0(sizeof(struct client_s));
545 gpg_error_t rc;
546 pth_attr_t attr;
549 * Prevent a race condition with init_new_connection() if this thread
550 * fails (returns) for some reason before init_new_connection() releases
551 * the cn_mutex.
553 MUTEX_LOCK(&cn_mutex);
554 MUTEX_UNLOCK(&cn_mutex);
555 pth_cleanup_push(cleanup_cb, thd);
557 if (!cl) {
558 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
559 goto fail;
562 attr = pth_attr_of(pth_self());
563 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
564 pth_attr_destroy(attr);
565 thd->cl = cl;
566 cl->thd = thd;
568 if (!new_connection(cl))
569 goto fail;
571 #ifdef WITH_PINENTRY
572 cl->pinentry = pinentry_init();
574 if (!cl->pinentry) {
575 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
576 goto fail;
578 #endif
580 thd->mp = pth_msgport_create(NULL);
581 pth_mutex_init(&thd->mp_mutex);
582 thd->msg_tid = pth_spawn(NULL, client_msg_thread, thd);
583 rc = gpg_error_from_syserror();
585 if (!thd->msg_tid) {
586 log_write("%s(%i): pth_spawn(): %s", __FILE__, __LINE__,
587 pwmd_strerror(rc));
588 goto fail;
591 pth_yield(thd->msg_tid);
592 rc = send_status(cl->ctx, STATUS_CACHE, NULL);
594 if (rc) {
595 log_write("%s", pwmd_strerror(rc));
596 goto fail;
599 send_status_all(STATUS_CLIENTS);
600 xmlSetStructuredErrorFunc(cl, xml_error_cb);
602 for (;;) {
603 #ifdef WITH_PINENTRY
604 pth_event_t pev = NULL;
605 #endif
606 pth_status_t st, wst;
607 pth_event_t wev = NULL;
608 pth_event_t rev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_READABLE,
609 cl->thd->fd);
610 pth_event_t ev = rev;
612 #ifdef WITH_PINENTRY
613 if (cl->pinentry->status == PINENTRY_RUNNING) {
614 pev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_READABLE, cl->pinentry->fd);
615 ev = pth_event_concat(ev, pev, NULL);
617 #endif
619 if (cl->inquire_status == INQUIRE_BUSY) {
620 wev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_WRITEABLE, cl->thd->fd);
621 ev = pth_event_concat(ev, wev, NULL);
624 pth_cleanup_push(cleanup_ev_cb, ev);
625 pth_wait(ev);
626 st = pth_event_status(rev);
627 wst = pth_event_status(wev);
629 if (st == PTH_STATUS_OCCURRED || wst == PTH_STATUS_OCCURRED) {
630 rc = assuan_process_next(cl->ctx);
632 if (rc) {
633 cl->inquire_status = INQUIRE_INIT;
634 pth_cleanup_pop(1);
636 if (gpg_err_code(rc) == GPG_ERR_EOF)
637 goto done;
639 log_write("assuan_process_next(): %s", pwmd_strerror(rc));
640 rc = send_error(cl->ctx, gpg_err_make(PWMD_ERR_SOURCE, rc));
642 if (rc) {
643 log_write("assuan_process_done(): %s", pwmd_strerror(rc));
644 goto done;
647 else {
648 #ifdef WITH_PINENTRY
649 if (cl->pinentry->pid && cl->pinentry->status == PINENTRY_INIT)
650 cl->pinentry->status = PINENTRY_RUNNING;
651 #endif
653 switch (cl->inquire_status) {
654 case INQUIRE_BUSY:
655 case INQUIRE_INIT:
656 break;
657 case INQUIRE_DONE:
658 cl->inquire_status = INQUIRE_INIT;
659 rc = assuan_process_done(cl->ctx, 0);
660 break;
665 #ifdef WITH_PINENTRY
666 if (pev)
667 st = pth_event_status(pev);
669 rc = pinentry_iterate(cl,
670 pev && cl->pinentry->fd != -1 && st == PTH_STATUS_OCCURRED);
671 #endif
672 pth_cleanup_pop(1);
676 * Client cleanup (including XML data) is done in cleanup_cb().
678 done:
679 fail:
680 pth_exit(PTH_CANCELED);
681 return NULL;
684 static gchar *do_read_password(const gchar *prompt)
686 gchar buf[LINE_MAX] = {0}, *p;
687 struct termios told, tnew;
688 gchar *key;
690 if (tcgetattr(STDIN_FILENO, &told) == -1) {
691 log_write("tcgetattr(): %s", pwmd_strerror(gpg_error_from_syserror()));
692 return NULL;
695 memcpy(&tnew, &told, sizeof(struct termios));
696 tnew.c_lflag &= ~(ECHO);
697 tnew.c_lflag |= ICANON|ECHONL;
699 if (tcsetattr(STDIN_FILENO, TCSANOW, &tnew) == -1) {
700 log_write("tcsetattr(): %s", pwmd_strerror(gpg_error_from_syserror()));
701 tcsetattr(STDIN_FILENO, TCSANOW, &told);
702 return NULL;
705 fprintf(stderr, "%s", prompt);
707 if ((p = fgets(buf, sizeof(buf), stdin)) == NULL) {
708 tcsetattr(STDIN_FILENO, TCSANOW, &told);
709 return NULL;
712 tcsetattr(STDIN_FILENO, TCSANOW, &told);
713 p[strlen(p) - 1] = 0;
715 if (!buf[0]) {
716 key = gcry_malloc(1);
717 key[0] = 0;
719 else {
720 key = gcry_malloc(strlen(p) + 1);
721 sprintf(key, "%s", p);
724 memset(&buf, 0, sizeof(buf));
725 return key;
728 /* Only used when "enable_pinentry" is "false" or -P. */
729 static gpg_error_t read_password(const gchar *filename,
730 struct crypto_s *crypto, guchar *key, pinentry_cmd_t which)
732 gchar *prompt;
734 if (which == PINENTRY_SAVE) {
735 prompt = g_strdup_printf(_("New passphrase for file %s: "), filename);
736 crypto->tkey = do_read_password(prompt);
737 g_free(prompt);
739 if (!crypto->tkey) {
740 log_write(_("%s: Skipping file"), filename);
741 return GPG_ERR_BAD_PASSPHRASE;
744 prompt = g_strdup_printf(_("Repeat passphrase: "));
745 crypto->tkey2 = do_read_password(prompt);
746 g_free(prompt);
748 if (!crypto->tkey2) {
749 log_write(_("%s: Skipping file"), filename);
750 return GPG_ERR_BAD_PASSPHRASE;
753 if (g_strcmp0(crypto->tkey, crypto->tkey2)) {
754 log_write(_("%s: Passphrase mismatch"), filename);
755 return GPG_ERR_INV_PASSPHRASE;
758 gcry_md_hash_buffer(GCRY_MD_SHA256, key, crypto->tkey,
759 strlen(crypto->tkey) ? strlen(crypto->tkey) : 1);
760 return 0;
763 prompt = g_strdup_printf(_("Passphrase required for %s: "), filename);
765 if ((crypto->tkey = do_read_password(prompt)) == NULL) {
766 log_write(_("%s: Skipping file"), filename);
767 g_free(prompt);
768 return GPG_ERR_BAD_PASSPHRASE;
771 gcry_md_hash_buffer(GCRY_MD_SHA256, key, crypto->tkey,
772 strlen(crypto->tkey) ? strlen(crypto->tkey) : 1);
773 g_free(prompt);
774 return 0;
778 * inbuf must have been allocated with gcry_malloc().
780 gpg_error_t export_common(const gchar *filename, struct crypto_s *crypto,
781 gpointer inbuf, gulong insize)
783 gpg_error_t rc;
784 gint level;
785 gulong outsize;
786 gpointer outbuf;
788 rc = update_save_flags(NULL, crypto);
790 if (rc)
791 return rc;
793 level = get_key_file_integer(filename, "compression_level");
795 if (level < 0)
796 level = 0;
798 rc = do_compress(NULL, level, inbuf, insize, &outbuf, &outsize);
800 if (rc)
801 return rc;
803 crypto->inbuf = outbuf;
804 crypto->insize = outsize;
805 rc = do_xml_encrypt(NULL, crypto, filename);
806 return rc;
809 static gpg_error_t get_password(const gchar *filename,
810 struct crypto_s *crypto, guchar *md5file, guchar *key,
811 pinentry_cmd_t which)
813 #ifdef WITH_PINENTRY
814 gpg_error_t rc = 0;
816 if (g_key_file_get_boolean(keyfileh, "global", "enable_pinentry", NULL)
817 == FALSE) {
818 #endif
819 return read_password(filename, crypto, key, which);
820 #ifdef WITH_PINENTRY
822 else {
823 gchar *result = NULL;
824 struct pinentry_s *pin = g_malloc0(sizeof(struct pinentry_s));
826 pth_mutex_init(&pin->status_mutex);
827 set_pinentry_defaults(pin);
828 pin->which = which;
829 pin->filename = g_strdup(filename);
830 rc = pinentry_getpin(pin, &result);
832 if (rc) {
833 xfree(result);
834 goto done;
837 gcry_md_hash_buffer(GCRY_MD_SHA256, key, result, result ? strlen(result) : 1);
838 xfree(result);
839 cleanup_pinentry(pin);
842 done:
843 return rc;
844 #endif
847 static gboolean xml_import(const gchar *filename, const gchar *outfile,
848 const gchar *keyfile, guint64 iter)
850 xmlDocPtr doc;
851 gint fd;
852 struct stat st;
853 gint len;
854 xmlChar *xmlbuf;
855 xmlChar *xml;
856 gpg_error_t rc;
857 struct crypto_s *crypto;
858 guint hashlen = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
860 if (g_stat(filename, &st) == -1) {
861 log_write("%s: %s", filename, pwmd_strerror(gpg_error_from_syserror()));
862 return FALSE;
865 crypto = init_client_crypto();
867 if (!crypto)
868 return FALSE;
870 crypto->key = gcry_malloc(hashlen);
871 memset(crypto->key, 0, hashlen);
873 if (!crypto->key) {
874 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
875 goto fail;
878 log_write(_("Importing XML from '%s'. Output will be written to '%s' ..."),
879 filename, outfile);
881 if (iter && keyfile) {
882 rc = parse_rcfile_keyfile(crypto, keyfile, TRUE);
884 if (rc)
885 goto fail;
887 gcry_md_hash_buffer(GCRY_MD_SHA256, crypto->key, crypto->tkey,
888 crypto->tkey_len);
890 else if (iter) {
891 rc = get_password(outfile, crypto, NULL, crypto->key, PINENTRY_SAVE);
893 if (rc == GPG_ERR_ASSUAN_SERVER_FAULT) {
894 log_write(_("%s. Maybe disabling pinentry (-P) will help?"),
895 pwmd_strerror(rc));
896 goto fail;
898 else if (rc) {
899 log_write("%s", pwmd_strerror(rc));
900 goto fail;
904 if ((fd = open(filename, O_RDONLY)) == -1) {
905 log_write("%s: %s", filename, pwmd_strerror(gpg_error_from_syserror()));
906 goto fail;
909 if ((xmlbuf = gcry_malloc(st.st_size+1)) == NULL) {
910 close(fd);
911 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
912 goto fail;
915 if (pth_read(fd, xmlbuf, st.st_size) == -1) {
916 rc = gpg_error_from_syserror();
917 close(fd);
918 log_write("%s: %s", filename, pwmd_strerror(rc));
919 goto fail;
922 close(fd);
923 xmlbuf[st.st_size] = 0;
926 * Make sure the document validates.
928 if ((doc = xmlReadDoc(xmlbuf, NULL, "UTF-8", XML_PARSE_NOBLANKS)) == NULL) {
929 log_write("xmlReadDoc() failed");
930 gcry_free(xmlbuf);
931 goto fail;
934 gcry_free(xmlbuf);
935 xmlNodePtr n = xmlDocGetRootElement(doc);
936 rc = validate_import(n ? n->children : n);
938 if (rc) {
939 log_write("%s", pwmd_strerror(rc));
940 xmlFreeDoc(doc);
941 goto fail;
944 xmlDocDumpMemory(doc, &xml, &len);
945 xmlFreeDoc(doc);
947 if (!iter)
948 memset(crypto->key, '!', hashlen);
950 crypto->fh = g_malloc0(sizeof(file_header_internal_t));
952 if (!crypto->fh) {
953 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
954 goto fail;
957 crypto->fh->ver.fh2.iter = iter;
958 rc = export_common(outfile, crypto, xml, len);
959 xmlFree(xml);
961 if (rc) {
962 send_error(NULL, rc);
963 goto fail;
966 cleanup_crypto(&crypto);
967 return TRUE;
969 fail:
970 cleanup_crypto(&crypto);
971 return FALSE;
974 gboolean do_cache_push(const gchar *filename, const void *password,
975 gsize len)
977 guchar md5file[16];
978 gint timeout;
979 const gchar *p = filename;
980 struct crypto_s *crypto;
981 gpg_error_t rc;
982 guint hashlen = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
984 while (isspace(*p))
985 p++;
987 if (!*p)
988 return FALSE;
990 if (valid_filename(p) == FALSE) {
991 log_write(_("%s: Invalid characters in filename"), p);
992 return FALSE;
995 gcry_md_hash_buffer(GCRY_MD_MD5, md5file, p, strlen(p));
997 if (cache_iscached(md5file)) {
998 log_write(_("%s: already cached, skipping"), p);
999 return TRUE;
1002 if (access(p, R_OK|W_OK) != 0) {
1003 log_write("%s: %s", p, pwmd_strerror(gpg_error_from_syserror()));
1004 return FALSE;
1007 crypto = init_client_crypto();
1009 if (!crypto)
1010 return FALSE;
1012 crypto->fh = read_file_header(filename, FALSE, &rc);
1014 if (!crypto->fh) {
1015 log_write("%s: %s", p, pwmd_strerror(rc));
1016 cleanup_crypto(&crypto);
1017 return FALSE;
1020 crypto->key = gcry_malloc(hashlen);
1022 if (!crypto->key) {
1023 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
1024 cleanup_crypto(&crypto);
1025 return FALSE;
1028 log_write(_("Adding '%s' to the file cache ..."), filename);
1030 if (crypto->fh->ver.fh2.iter <= 0ULL) {
1031 memset(crypto->key, '!', hashlen);
1032 goto try_decrypt;
1035 if (!password) {
1036 rc = get_password(p, crypto, md5file, crypto->key, PINENTRY_OPEN);
1038 if (rc) {
1039 send_error(NULL, rc);
1040 cleanup_crypto(&crypto);
1041 return FALSE;
1044 gcry_free(crypto->fh->doc);
1045 crypto->fh->doc = NULL;
1047 else
1048 gcry_md_hash_buffer(GCRY_MD_SHA256, crypto->key, password, len);
1050 try_decrypt:
1051 rc = init_client_crypto2(filename, crypto);
1053 if (rc) {
1054 send_error(NULL, rc);
1055 cleanup_crypto(&crypto);
1056 return FALSE;
1059 rc = try_xml_decrypt(NULL, crypto, NULL, NULL);
1061 if (rc) {
1062 log_write("%s: %s", filename, pwmd_strerror(rc));
1063 cleanup_crypto(&crypto);
1064 return FALSE;
1067 if (cache_update_key(md5file, crypto->key) == FALSE) {
1068 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
1069 cleanup_crypto(&crypto);
1070 return FALSE;
1073 timeout = get_key_file_integer(p, "cache_timeout");
1074 cache_set_timeout(md5file, timeout);
1075 log_write(_("File '%s' now cached"), filename);
1076 cleanup_crypto(&crypto);
1077 return TRUE;
1080 static void init_new_connection(gint fd)
1082 pth_attr_t attr;
1083 struct client_thread_s *new;
1084 gpg_error_t rc;
1086 new = g_malloc0(sizeof(struct client_thread_s));
1088 if (!new) {
1089 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
1090 close(fd);
1091 return;
1094 MUTEX_LOCK(&cn_mutex);
1095 new->fd = fd;
1096 attr = pth_attr_new();
1097 pth_attr_init(attr);
1098 pth_attr_set(attr, PTH_ATTR_JOINABLE, FALSE);
1099 new->tid = pth_spawn(attr, client_thread, new);
1100 rc = gpg_error_from_syserror();
1101 pth_attr_destroy(attr);
1103 if (!new->tid) {
1104 g_free(new);
1105 close(fd);
1106 log_write("%s(%i): pth_spawn(): %s", __FILE__, __LINE__,
1107 pwmd_strerror(rc));
1108 MUTEX_UNLOCK(&cn_mutex);
1109 return;
1112 cn_thread_list = g_slist_append(cn_thread_list, new);
1113 MUTEX_UNLOCK(&cn_mutex);
1114 log_write(_("new connection: tid=%p, fd=%i"), new->tid, fd);
1117 static void *accept_thread(void *arg)
1119 gint sockfd = *(gint *)arg;
1120 pth_attr_t attr = pth_attr_of(pth_self());
1122 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
1123 pth_attr_destroy(attr);
1125 for (;;) {
1126 socklen_t slen = sizeof(struct sockaddr_un);
1127 struct sockaddr_un raddr;
1128 gint fd = -1;
1130 fd = pth_accept(sockfd, (struct sockaddr *)&raddr, &slen);
1132 if (fd == -1) {
1133 if (errno != EAGAIN) {
1134 if (!quit) // probably EBADF
1135 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
1137 break;
1140 continue;
1143 init_new_connection(fd);
1146 /* Just in case accept() failed for some reason other than EBADF */
1147 quit = 1;
1148 pth_exit(PTH_CANCELED);
1149 return NULL;
1152 static void *adjust_cache_timer_thread(void *arg)
1154 pth_attr_t attr = pth_attr_of(pth_self());
1156 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
1157 pth_attr_destroy(attr);
1159 for (;;) {
1160 pth_sleep(1);
1161 CACHE_LOCK(NULL);
1162 cache_adjust_timer();
1163 CACHE_UNLOCK;
1166 return NULL;
1169 void cleanup_mutex_cb(void *arg)
1171 pth_mutex_t *m = arg;
1173 MUTEX_UNLOCK(m);
1176 void cleanup_ev_cb(void *arg)
1178 pth_event_t ev = arg;
1180 pth_event_free(ev, PTH_FREE_ALL);
1183 void cleanup_fd_cb(void *arg)
1185 gint fd = *(gint *)arg;
1187 close(fd);
1190 void cleanup_unlink_cb(void *arg)
1192 gchar *file = arg;
1194 unlink(file);
1197 void cleanup_cancel_cb(void *arg)
1199 pth_t tid = arg;
1200 pth_attr_t attr;
1201 gint join;
1203 attr = pth_attr_of(tid);
1204 pth_attr_get(attr, PTH_ATTR_JOINABLE, &join);
1205 pth_cancel(tid);
1207 if (join) {
1208 void *p;
1210 pth_join(tid, &p);
1211 g_free(p);
1215 static gboolean waiting_for_exit()
1217 guint i, t;
1218 pth_event_t evs = NULL;
1220 MUTEX_LOCK(&cn_mutex);
1222 for (t = g_slist_length(cn_thread_list), i = 0; i < t; i++) {
1223 struct client_thread_s *thd = g_slist_nth_data(cn_thread_list, i);
1224 pth_event_t ev = pth_event(PTH_EVENT_TID|PTH_UNTIL_TID_DEAD, thd->tid);
1226 if (evs)
1227 evs = pth_event_concat(evs, ev, NULL);
1228 else
1229 evs = ev;
1232 MUTEX_UNLOCK(&cn_mutex);
1234 if (!evs)
1235 return FALSE;
1237 pth_wait(evs);
1238 MUTEX_LOCK(&cn_mutex);
1239 i = g_slist_length(cn_thread_list);
1240 MUTEX_UNLOCK(&cn_mutex);
1241 pth_event_free(evs, PTH_FREE_ALL);
1242 return i ? TRUE : FALSE;
1245 static void catch_sigabrt(int sig)
1247 cache_clear(NULL, 2);
1248 #ifndef MEM_DEBUG
1249 xpanic();
1250 #endif
1253 static void server_loop(gint sockfd, gchar **socketpath)
1255 pth_t accept_tid;
1256 guint n;
1257 sigset_t sigset;
1258 pth_attr_t attr;
1259 pth_t cache_timeout_tid = NULL;
1260 gpg_error_t rc;
1262 init_commands();
1263 sigemptyset(&sigset);
1265 /* Termination */
1266 sigaddset(&sigset, SIGTERM);
1267 sigaddset(&sigset, SIGINT);
1269 /* Clears the file cache. */
1270 sigaddset(&sigset, SIGUSR1);
1272 /* Configuration file reloading. */
1273 sigaddset(&sigset, SIGHUP);
1275 /* Clears the cache and exits when something bad happens. */
1276 signal(SIGABRT, catch_sigabrt);
1277 sigaddset(&sigset, SIGABRT);
1279 /* Ignored everywhere. When a client disconnects abnormally this signal
1280 * gets raised. It isn't needed though because client_thread() will check
1281 * for rcs even after the client disconnects. */
1282 signal(SIGPIPE, SIG_IGN);
1283 sigprocmask(SIG_BLOCK, &sigset, NULL);
1285 log_write(_("%s started for user %s"), PACKAGE_STRING, g_get_user_name());
1286 log_write(_("Listening on %s"), *socketpath);
1287 #ifndef HAVE_SO_PEERCRED
1288 log_write(_("Peer credential checking is NOT supported on this OS."));
1289 #endif
1290 attr = pth_attr_new();
1291 pth_attr_init(attr);
1292 accept_tid = pth_spawn(attr, accept_thread, &sockfd);
1293 rc = gpg_error_from_syserror();
1295 if (!accept_tid) {
1296 log_write("%s(%i): pth_spawn(): %s", __FILE__, __LINE__,
1297 pwmd_strerror(rc));
1298 pth_attr_destroy(attr);
1299 goto done;
1302 pth_yield(accept_tid);
1303 pth_attr_set(attr, PTH_ATTR_JOINABLE, FALSE);
1304 cache_timeout_tid = pth_spawn(attr, adjust_cache_timer_thread, NULL);
1305 rc = gpg_error_from_syserror();
1307 if (!cache_timeout_tid) {
1308 log_write("%s(%i): pth_spawn(): %s", __FILE__, __LINE__,
1309 pwmd_strerror(rc));
1310 pth_attr_destroy(attr);
1311 goto done;
1314 pth_yield(cache_timeout_tid);
1315 pth_attr_destroy(attr);
1318 gchar *str = get_key_file_string("global", "debug_file");
1320 if (str) {
1321 gchar *f = expand_homedir(str);
1323 g_free(str);
1324 debugfp = fopen(f, "w");
1326 if (!debugfp)
1327 log_write("%s: %s", f, pwmd_strerror(gpg_error_from_syserror()));
1328 else
1329 assuan_set_assuan_log_stream(debugfp);
1331 g_free(f);
1335 do {
1336 gint sig;
1338 pth_sigwait(&sigset, &sig);
1339 log_write(_("caught signal %i (%s)"), sig, strsignal(sig));
1341 /* Caught a signal. */
1342 switch (sig) {
1343 case SIGHUP:
1344 reload_rcfile();
1345 break;
1346 case SIGABRT:
1347 // not really handled here.
1348 catch_sigabrt(SIGABRT);
1349 break;
1350 case SIGUSR1:
1351 CACHE_LOCK(NULL);
1352 log_write(_("clearing file cache"));
1353 cache_clear(NULL, 2);
1354 CACHE_UNLOCK;
1355 break;
1356 default:
1357 quit = 1;
1358 break;
1360 } while (!quit);
1362 done:
1364 * We're out of the main server loop. This happens when a signal was sent
1365 * to terminate the daemon. We'll wait for all clients to disconnect
1366 * before exiting and ignore any following signals.
1368 shutdown(sockfd, SHUT_RDWR);
1369 close(sockfd);
1370 pth_cancel(accept_tid);
1371 pth_join(accept_tid, NULL);
1372 unlink(*socketpath);
1373 g_free(*socketpath);
1374 *socketpath = NULL;
1375 MUTEX_LOCK(&cn_mutex);
1376 n = g_slist_length(cn_thread_list);
1377 MUTEX_UNLOCK(&cn_mutex);
1379 if (n) {
1380 log_write(_("waiting for all clients to disconnect"));
1382 do {
1383 MUTEX_LOCK(&cn_mutex);
1384 n = g_slist_length(cn_thread_list);
1385 MUTEX_UNLOCK(&cn_mutex);
1386 log_write(_("%i clients remain"), n);
1387 } while (waiting_for_exit());
1390 pth_cancel(cache_timeout_tid);
1391 cache_free();
1392 deinit_commands();
1396 * Only called from pinentry_fork() in the child process.
1398 void free_client_list()
1400 gint i, t = g_slist_length(cn_thread_list);
1402 for (i = 0; i < t; i++) {
1403 struct client_thread_s *cn = g_slist_nth_data(cn_thread_list, i);
1405 free_client(cn->cl);
1408 cache_free();
1411 static guint pwmd_cipher_to_gcrypt(guint64 flags)
1413 if (flags & PWMD_CIPHER_AES128)
1414 return GCRY_CIPHER_AES128;
1415 else if (flags & PWMD_CIPHER_AES192)
1416 return GCRY_CIPHER_AES192;
1417 else if (flags & PWMD_CIPHER_AES256)
1418 return GCRY_CIPHER_AES256;
1419 else if (flags & PWMD_CIPHER_SERPENT128)
1420 return GCRY_CIPHER_SERPENT128;
1421 else if (flags & PWMD_CIPHER_SERPENT192)
1422 return GCRY_CIPHER_SERPENT192;
1423 else if (flags & PWMD_CIPHER_SERPENT256)
1424 return GCRY_CIPHER_SERPENT256;
1425 else if (flags & PWMD_CIPHER_CAMELLIA128)
1426 return GCRY_CIPHER_CAMELLIA128;
1427 else if (flags & PWMD_CIPHER_CAMELLIA192)
1428 return GCRY_CIPHER_CAMELLIA192;
1429 else if (flags & PWMD_CIPHER_CAMELLIA256)
1430 return GCRY_CIPHER_CAMELLIA256;
1431 else if (flags & PWMD_CIPHER_BLOWFISH)
1432 return GCRY_CIPHER_BLOWFISH;
1433 else if (flags & PWMD_CIPHER_3DES)
1434 return GCRY_CIPHER_3DES;
1435 else if (flags & PWMD_CIPHER_CAST5)
1436 return GCRY_CIPHER_CAST5;
1437 else if (flags & PWMD_CIPHER_TWOFISH)
1438 return GCRY_CIPHER_TWOFISH;
1439 else if (flags & PWMD_CIPHER_TWOFISH128)
1440 return GCRY_CIPHER_TWOFISH128;
1442 /* For backwards compatibility (no flags). */
1443 return GCRY_CIPHER_AES256;
1446 guint pwmd_cipher_str_to_cipher(const gchar *str)
1448 guint64 flags = 0;
1450 if (!g_strcasecmp(str, "aes128"))
1451 flags = PWMD_CIPHER_AES128;
1452 else if (!g_strcasecmp(str, "aes192"))
1453 flags = PWMD_CIPHER_AES192;
1454 else if (!g_strcasecmp(str, "aes256"))
1455 flags = PWMD_CIPHER_AES256;
1456 if (!g_strcasecmp(str, "serpent128"))
1457 flags = PWMD_CIPHER_SERPENT128;
1458 else if (!g_strcasecmp(str, "serpent192"))
1459 flags = PWMD_CIPHER_SERPENT192;
1460 else if (!g_strcasecmp(str, "serpent256"))
1461 flags = PWMD_CIPHER_SERPENT256;
1462 if (!g_strcasecmp(str, "camellia128"))
1463 flags = PWMD_CIPHER_CAMELLIA128;
1464 else if (!g_strcasecmp(str, "camellia192"))
1465 flags = PWMD_CIPHER_CAMELLIA192;
1466 else if (!g_strcasecmp(str, "camellia256"))
1467 flags = PWMD_CIPHER_CAMELLIA256;
1468 else if (!g_strcasecmp(str, "blowfish"))
1469 flags = PWMD_CIPHER_BLOWFISH;
1470 else if (!g_strcasecmp(str, "cast5"))
1471 flags = PWMD_CIPHER_CAST5;
1472 else if (!g_strcasecmp(str, "3des"))
1473 flags = PWMD_CIPHER_3DES;
1474 else if (!g_strcasecmp(str, "twofish256"))
1475 flags = PWMD_CIPHER_TWOFISH;
1476 else if (!g_strcasecmp(str, "twofish128"))
1477 flags = PWMD_CIPHER_TWOFISH128;
1479 return flags;
1482 const gchar *pwmd_cipher_to_str(guint64 flags)
1484 if (flags & PWMD_CIPHER_AES128)
1485 return "aes128";
1486 else if (flags & PWMD_CIPHER_AES192)
1487 return "aes192";
1488 else if (flags & PWMD_CIPHER_AES256)
1489 return "aes256";
1490 else if (flags & PWMD_CIPHER_SERPENT128)
1491 return "serpent128";
1492 else if (flags & PWMD_CIPHER_SERPENT192)
1493 return "serpent192";
1494 else if (flags & PWMD_CIPHER_SERPENT256)
1495 return "serpent256";
1496 else if (flags & PWMD_CIPHER_CAMELLIA128)
1497 return "camellia128";
1498 else if (flags & PWMD_CIPHER_CAMELLIA192)
1499 return "camellia192";
1500 else if (flags & PWMD_CIPHER_CAMELLIA256)
1501 return "camellia256";
1502 else if (flags & PWMD_CIPHER_BLOWFISH)
1503 return "blowfish";
1504 else if (flags & PWMD_CIPHER_CAST5)
1505 return "cast5";
1506 else if (flags & PWMD_CIPHER_3DES)
1507 return "3des";
1508 else if (flags & PWMD_CIPHER_TWOFISH)
1509 return "twofish256";
1510 else if (flags & PWMD_CIPHER_TWOFISH128)
1511 return "twofish128";
1513 return NULL;
1516 /* To be called after read_file_header(). This sets the wanted algorithm from
1517 * .flags */
1518 gpg_error_t init_client_crypto2(const char *filename,
1519 struct crypto_s *crypto)
1521 gpg_error_t rc;
1522 guint algo;
1524 /* New file or conversion. */
1525 if (crypto->fh->v1)
1526 algo = pwmd_cipher_to_gcrypt(PWMD_CIPHER_AES256);
1527 else if (!crypto->fh->ver.fh2.flags) {
1528 gchar *tmp = get_key_file_string(filename ? filename : "global", "cipher");
1529 guint64 flags;
1531 flags = pwmd_cipher_str_to_cipher(tmp);
1532 g_free(tmp);
1533 algo = pwmd_cipher_to_gcrypt(flags);
1534 crypto->fh->ver.fh2.flags = flags;
1536 else
1537 algo = pwmd_cipher_to_gcrypt(crypto->fh->ver.fh2.flags);
1539 rc = gcry_cipher_algo_info(algo, GCRYCTL_TEST_ALGO, NULL, NULL);
1541 if (rc)
1542 return rc;
1544 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_KEYLEN, NULL,
1545 &crypto->keysize);
1547 if (rc)
1548 return rc;
1550 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_BLKLEN, NULL,
1551 &crypto->blocksize);
1553 if (rc)
1554 return rc;
1556 if (crypto->gh)
1557 gcry_cipher_close(crypto->gh);
1559 return gcry_cipher_open(&crypto->gh, algo, GCRY_CIPHER_MODE_CBC, 0);
1562 struct crypto_s *init_client_crypto()
1564 struct crypto_s *new = g_malloc0(sizeof(struct crypto_s));
1566 if (!new) {
1567 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
1568 return NULL;
1571 return new;
1574 static gpg_error_t convert_file(const gchar *filename, const gchar *keyfile,
1575 const gchar *outfile)
1577 gpg_error_t rc;
1578 guchar md5file[gcry_md_get_algo_dlen(GCRY_MD_MD5)];
1579 guint64 iter;
1580 struct crypto_s *crypto = init_client_crypto();
1581 guint hashlen = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
1583 if (!crypto)
1584 return GPG_ERR_ENOMEM;
1586 crypto->key = gcry_malloc(hashlen);
1588 if (!crypto->key) {
1589 cleanup_crypto(&crypto);
1590 return GPG_ERR_ENOMEM;
1593 log_write(_("Converting version 1 data file '%s' to version 2 ..."),
1594 filename);
1595 crypto->fh = read_file_header(filename, TRUE, &rc);
1597 if (!crypto->fh)
1598 goto done;
1600 gcry_md_hash_buffer(GCRY_MD_MD5, md5file, filename, strlen(filename));
1602 /* The header in version 1 had a bug where the iterations were off-by-one.
1603 * So 0 iterations was really -1 in the header. This is fixed in v2 of the
1604 * header.
1606 if (crypto->fh->ver.fh1.iter != -1) {
1607 if (keyfile) {
1608 rc = parse_rcfile_keyfile(crypto, keyfile, TRUE);
1610 if (rc)
1611 goto done;
1613 gcry_md_hash_buffer(GCRY_MD_SHA256, crypto->key, crypto->tkey,
1614 crypto->tkey_len);
1615 gcry_free(crypto->tkey);
1616 crypto->tkey = NULL;
1618 else {
1619 rc = get_password(filename, crypto, md5file, crypto->key,
1620 PINENTRY_OPEN);
1622 if (rc)
1623 goto done;
1627 rc = init_client_crypto2(NULL, crypto);
1629 if (rc)
1630 goto done;
1632 rc = try_xml_decrypt(NULL, crypto, &crypto->fh->doc, &crypto->fh->len);
1634 if (rc)
1635 goto done;
1637 rc = convert_xml((gchar **)&crypto->fh->doc, &crypto->fh->len);
1639 if (rc) {
1640 log_write("%s: %s", filename, pwmd_strerror(rc));
1641 goto done;
1644 crypto->fh->v1 = FALSE;
1646 iter = crypto->fh->ver.fh1.iter+1;
1647 memset(&crypto->fh->ver.fh2, 0, sizeof(crypto->fh->ver.fh2));
1648 /* Keep the iterations and key from the original file. */
1649 crypto->fh->ver.fh2.iter = iter;
1650 rc = export_common(outfile, crypto, crypto->fh->doc, crypto->fh->len);
1652 done:
1653 if (rc)
1654 send_error(NULL, rc);
1656 /* fh->doc is freed from do_xml_decrypt() via the inbuf pointer. */
1657 cleanup_crypto(&crypto);
1658 return rc;
1661 static void startup_failure()
1663 log_write(_("Failed to add a file to the cache. Use --ignore to force startup. Exiting."));
1664 cache_clear(NULL, 2);
1667 int main(int argc, char *argv[])
1669 struct sockaddr_un addr;
1670 gchar buf[PATH_MAX];
1671 gchar *socketpath = NULL, *socketdir, *socketname = NULL;
1672 gchar *socketarg = NULL;
1673 gchar *datadir = NULL;
1674 gint n;
1675 gchar *p;
1676 gchar **cache_push = NULL;
1677 gchar *import = NULL, *keyfile = NULL;
1678 gint64 cmd_iterations = -1;
1679 gboolean rcfile_spec = FALSE;
1680 gint estatus = EXIT_FAILURE;
1681 gint sockfd;
1682 gchar *outfile = NULL;
1683 GMemVTable mtable = { xmalloc, xrealloc, xfree, xcalloc, NULL, NULL };
1684 gint do_unlink = 0;
1685 gboolean secure = FALSE;
1686 gboolean nofork = FALSE;
1687 gchar *convert = NULL;
1688 gint show_version = 0;
1689 gboolean force = FALSE;
1690 #ifdef WITH_PINENTRY
1691 gboolean disable_pinentry = FALSE;
1692 #endif
1693 GError *error = NULL;
1694 GOptionContext *context;
1695 GOptionEntry options[] =
1697 #ifdef WITH_PINENTRY
1698 { "no-pinentry", 'P', 0, G_OPTION_ARG_NONE, &disable_pinentry,
1699 "disable pinentry", NULL },
1700 #endif
1701 { "version", 0, 0, G_OPTION_ARG_NONE, &show_version,
1702 "version information", NULL },
1703 { "no-fork", 'n', 0, G_OPTION_ARG_NONE, &nofork,
1704 "run as a foreground process", NULL },
1705 { "disable-dump", 'D', 0, G_OPTION_ARG_NONE, &secure,
1706 "disable the LIST, XPATH and DUMP commands", NULL },
1707 { "rcfile", 'f', 0, G_OPTION_ARG_FILENAME, &rcfile,
1708 "load the specified rcfile (~/.pwmd/config)", "filename" },
1709 { "ignore", 0, 0, G_OPTION_ARG_NONE, &force,
1710 "ignore cache failures on startup", NULL },
1711 { "outfile", 'o', 0, G_OPTION_ARG_FILENAME, &outfile,
1712 "output file when importing (- for stdout)", "filename" },
1713 { "convert", 'C', 0, G_OPTION_ARG_FILENAME, &convert,
1714 "convert a version 1 data file to version 2", "filename" },
1715 { "key-file", 'k', 0, G_OPTION_ARG_FILENAME, &keyfile,
1716 "for decryption when converting", "filename" },
1717 { "import", 'I', 0, G_OPTION_ARG_FILENAME, &import,
1718 "import an XML file", "filename" },
1719 { "iterations", 'i', 0, G_OPTION_ARG_INT64, &cmd_iterations,
1720 "when importing or converting", "N" },
1721 { NULL }
1723 #ifndef DEBUG
1724 #ifdef HAVE_SETRLIMIT
1725 struct rlimit rl;
1727 rl.rlim_cur = rl.rlim_max = 0;
1729 if (setrlimit(RLIMIT_CORE, &rl) != 0)
1730 err(EXIT_FAILURE, "setrlimit()");
1731 #endif
1732 #endif
1734 #ifdef ENABLE_NLS
1735 setlocale(LC_ALL, "");
1736 bindtextdomain("pwmd", LOCALEDIR);
1737 textdomain("pwmd");
1738 #endif
1740 pth_init();
1741 #ifndef MEM_DEBUG
1742 xmem_init();
1743 #endif
1744 setup_gcrypt();
1745 gpg_err_init();
1746 assuan_set_assuan_err_source(GPG_ERR_SOURCE_DEFAULT);
1747 g_mem_set_vtable(&mtable);
1748 assuan_set_malloc_hooks(g_malloc, g_realloc, g_free);
1749 xmlMemSetup(g_free, g_malloc, g_realloc, g_strdup);
1750 xmlInitMemory();
1751 xmlInitGlobals();
1752 xmlInitParser();
1753 xmlXPathInit();
1754 g_snprintf(buf, sizeof(buf), "%s/.pwmd", g_get_home_dir());
1756 if (mkdir(buf, 0700) == -1 && errno != EEXIST)
1757 err(EXIT_FAILURE, "%s", buf);
1759 g_snprintf(buf, sizeof(buf), "%s/.pwmd/data", g_get_home_dir());
1761 if (mkdir(buf, 0700) == -1 && errno != EEXIST)
1762 err(EXIT_FAILURE, "%s", buf);
1764 cmdline = TRUE;
1765 context = g_option_context_new("- Password Manager Daemon");
1766 g_option_context_add_main_entries(context, options, NULL);
1767 if (!g_option_context_parse(context, &argc, &argv, &error))
1769 g_print("Option parsing failed: %s\n", error->message);
1770 exit(EXIT_FAILURE);
1773 if (show_version) {
1774 printf(_("%s\nCopyright (C) 2006-2011 %s\nReleased under the terms of the GPL v2. Use at your own risk.\n\nCompile time features:\n%s"), PACKAGE_STRING,
1775 PACKAGE_BUGREPORT,
1776 #ifdef WITH_PINENTRY
1777 "+WITH_PINENTRY\n"
1778 #else
1779 "-WITH_PINENTRY\n"
1780 #endif
1781 #ifdef WITH_QUALITY
1782 "+WITH_QUALITY\n"
1783 #else
1784 "-WITH_QUALITY\n"
1785 #endif
1786 #ifdef WITH_LIBACL
1787 "+WITH_LIBACL\n"
1788 #else
1789 "-WITH_LIBACL\n"
1790 #endif
1791 #ifdef DEBUG
1792 "+DEBUG\n"
1793 #else
1794 "-DEBUG\n"
1795 #endif
1796 #ifdef MEM_DEBUG
1797 "+MEM_DEBUG\n"
1798 #else
1799 "-MEM_DEBUG\n"
1800 #endif
1801 #ifdef MUTEX_DEBUG
1802 "+MUTEX_DEBUG\n"
1803 #else
1804 "-MUTEX_DEBUG\n"
1805 #endif
1807 exit(EXIT_SUCCESS);
1810 pth_mutex_init(&cn_mutex);
1811 pth_mutex_init(&cache_mutex);
1812 pth_mutex_init(&rcfile_mutex);
1813 #ifdef WITH_PINENTRY
1814 pth_mutex_init(&pin_mutex);
1815 #endif
1817 if (!rcfile)
1818 rcfile = g_strdup_printf("%s/.pwmd/config", g_get_home_dir());
1820 if ((keyfileh = parse_rcfile(rcfile_spec)) == NULL)
1821 exit(EXIT_FAILURE);
1823 #ifdef WITH_PINENTRY
1824 if (disable_pinentry == TRUE)
1825 g_key_file_set_boolean(keyfileh, "global", "enable_pinentry", FALSE);
1826 #endif
1828 if (g_key_file_has_key(keyfileh, "global", "syslog", NULL) == TRUE)
1829 log_syslog = g_key_file_get_boolean(keyfileh, "global", "syslog", NULL);
1831 if (log_syslog == TRUE)
1832 openlog("pwmd", LOG_NDELAY|LOG_PID, LOG_DAEMON);
1834 if (g_key_file_has_key(keyfileh, "global", "priority", NULL)) {
1835 n = g_key_file_get_integer(keyfileh, "global", "priority", NULL);
1836 errno = 0;
1838 if (setpriority(PRIO_PROCESS, 0, n) == -1) {
1839 log_write("setpriority(): %s", pwmd_strerror(gpg_error_from_syserror()));
1840 goto do_exit;
1844 #ifdef HAVE_MLOCKALL
1845 if (disable_mlock == FALSE && mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
1846 log_write("mlockall(): %s", pwmd_strerror(gpg_error_from_syserror()));
1847 goto do_exit;
1849 #endif
1851 if (convert) {
1852 if (!outfile) {
1853 gchar *tmp = g_option_context_get_help(context, TRUE, NULL);
1855 fprintf(stderr, "%s", tmp);
1856 g_free(tmp);
1857 exit(EXIT_FAILURE);
1860 n = convert_file(convert, keyfile, outfile);
1861 g_key_file_free(keyfileh);
1862 g_free(rcfile);
1863 exit(n ? EXIT_FAILURE : EXIT_SUCCESS);
1866 if (import) {
1867 if (!outfile) {
1868 gchar *tmp = g_option_context_get_help(context, TRUE, NULL);
1870 fprintf(stderr, "%s", tmp);
1871 g_free(tmp);
1872 exit(EXIT_FAILURE);
1875 if (cmd_iterations == -1)
1876 cmd_iterations = get_key_file_uint64("global", "iterations");
1878 gboolean b = xml_import(import, outfile, keyfile, cmd_iterations);
1879 g_key_file_free(keyfileh);
1880 g_free(rcfile);
1881 exit(!b ? EXIT_FAILURE : EXIT_SUCCESS);
1884 g_option_context_free(context);
1886 if ((p = g_key_file_get_string(keyfileh, "global", "socket_path", NULL)) == NULL)
1887 errx(EXIT_FAILURE, _("%s: socket_path not defined"), rcfile);
1889 socketarg = expand_homedir(p);
1890 g_free(p);
1892 if ((p = g_key_file_get_string(keyfileh, "global", "data_directory", NULL)) == NULL)
1893 errx(EXIT_FAILURE, _("%s: data_directory not defined"), rcfile);
1895 datadir = expand_homedir(p);
1896 g_free(p);
1898 if (secure == FALSE && g_key_file_has_key(keyfileh, "global", "disable_list_and_dump", NULL) == TRUE) {
1899 n = g_key_file_get_boolean(keyfileh, "global", "disable_list_and_dump", NULL);
1900 disable_list_and_dump = n;
1902 else
1903 disable_list_and_dump = secure;
1905 setup_logging(keyfileh);
1907 if (g_key_file_has_key(keyfileh, "global", "cache_push", NULL) == TRUE)
1908 cache_push = g_key_file_get_string_list(keyfileh, "global", "cache_push", NULL, NULL);
1910 for (n = 1; n < argc; n++) {
1911 if (strv_printf(&cache_push, "%s", argv[n]) == FALSE)
1912 errx(EXIT_FAILURE, "%s", pwmd_strerror(GPG_ERR_ENOMEM));
1915 if (strchr(socketarg, '/') == NULL) {
1916 socketdir = g_get_current_dir();
1917 socketname = g_strdup(socketarg);
1918 socketpath = g_strdup_printf("%s/%s", socketdir, socketname);
1920 else {
1921 socketname = g_strdup(strrchr(socketarg, '/'));
1922 socketname++;
1923 socketarg[strlen(socketarg) - strlen(socketname) -1] = 0;
1924 socketdir = g_strdup(socketarg);
1925 socketpath = g_strdup_printf("%s/%s", socketdir, socketname);
1928 if (chdir(datadir)) {
1929 log_write("%s: %s", datadir, pwmd_strerror(gpg_error_from_syserror()));
1930 unlink(socketpath);
1931 goto do_exit;
1934 if (parse_rcfile_keys(!force) == FALSE) {
1935 startup_failure();
1936 estatus = EXIT_FAILURE;
1937 goto do_exit;
1940 clear_rcfile_keys();
1943 * Set the cache entry for a file. Prompts for the password.
1945 if (cache_push) {
1946 for (n = 0; cache_push[n]; n++) {
1947 if (!do_cache_push(cache_push[n], NULL, 0) && !force) {
1948 g_strfreev(cache_push);
1949 startup_failure();
1950 estatus = EXIT_FAILURE;
1951 goto do_exit;
1955 g_strfreev(cache_push);
1956 log_write(!nofork ? _("Done. Daemonizing...") : _("Done. Waiting for connections..."));
1960 * bind() doesn't like the full pathname of the socket or any non alphanum
1961 * characters so change to the directory where the socket is wanted then
1962 * create it then change to datadir.
1964 if (chdir(socketdir)) {
1965 log_write("%s: %s", socketdir, pwmd_strerror(gpg_error_from_syserror()));
1966 goto do_exit;
1969 g_free(socketdir);
1971 if ((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
1972 log_write("socket(): %s", pwmd_strerror(gpg_error_from_syserror()));
1973 goto do_exit;
1976 addr.sun_family = AF_UNIX;
1977 g_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socketname);
1979 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
1980 log_write("bind(): %s", pwmd_strerror(gpg_error_from_syserror()));
1982 if (errno == EADDRINUSE)
1983 log_write(_("Either there is another pwmd running or '%s' is a \n"
1984 "stale socket. Please remove it manually."), socketpath);
1986 goto do_exit;
1989 do_unlink = 1;
1990 if (g_key_file_has_key(keyfileh, "global", "socket_perms", NULL) == TRUE) {
1991 gchar *t = g_key_file_get_string(keyfileh, "global", "socket_perms", NULL);
1992 mode_t mode = strtol(t, NULL, 8);
1993 mode_t mask = umask(0);
1995 g_free(t);
1997 if (chmod(socketname, mode) == -1) {
1998 log_write("%s: %s", socketname, pwmd_strerror(gpg_error_from_syserror()));
1999 close(sockfd);
2000 unlink(socketpath);
2001 umask(mask);
2002 goto do_exit;
2005 umask(mask);
2008 g_free(--socketname);
2010 if (chdir(datadir)) {
2011 log_write("%s: %s", datadir, pwmd_strerror(gpg_error_from_syserror()));
2012 close(sockfd);
2013 unlink(socketpath);
2014 goto do_exit;
2017 g_free(datadir);
2019 if (listen(sockfd, 0) == -1) {
2020 log_write("listen(): %s", pwmd_strerror(gpg_error_from_syserror()));
2021 goto do_exit;
2024 cmdline = FALSE;
2025 unsetenv("DISPLAY");
2026 unsetenv("TERM");
2028 if (!nofork) {
2029 switch (fork()) {
2030 case -1:
2031 log_write("fork(): %s", pwmd_strerror(gpg_error_from_syserror()));
2032 goto do_exit;
2033 case 0:
2034 close(0);
2035 close(1);
2036 close(2);
2037 setsid();
2038 break;
2039 default:
2040 _exit(EXIT_SUCCESS);
2044 server_loop(sockfd, &socketpath);
2045 estatus = EXIT_SUCCESS;
2047 do_exit:
2048 if (socketpath && do_unlink) {
2049 unlink(socketpath);
2050 g_free(socketpath);
2053 g_free(socketarg);
2054 g_key_file_free(keyfileh);
2055 g_free(rcfile);
2056 xmlCleanupParser();
2057 xmlCleanupGlobals();
2059 if (estatus == EXIT_SUCCESS)
2060 log_write(_("pwmd exiting normally"));
2062 #if defined(DEBUG) && !defined(MEM_DEBUG)
2063 xdump();
2064 #endif
2065 exit(estatus);