Handle SIGABRT properly.
[pwmd.git] / src / pwmd.c
blobeb24c1d048a9417e740f8a22b380e79ab43829a9
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
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
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 <errno.h>
28 #include <ctype.h>
29 #include <string.h>
30 #include <sys/un.h>
31 #include <signal.h>
32 #include <stdarg.h>
33 #include <string.h>
34 #include <sys/wait.h>
35 #include <fcntl.h>
36 #include <pwd.h>
37 #include <grp.h>
38 #include <glib.h>
39 #include <glib/gprintf.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 HAVE_GETOPT_LONG
53 #ifdef HAVE_GETOPT_H
54 #include <getopt.h>
55 #endif
56 #else
57 #include "getopt_long.h"
58 #endif
60 #ifdef TM_IN_SYS_TIME
61 #include <sys/time.h>
62 #else
63 #include <time.h>
64 #endif
66 #include "mem.h"
67 #include "xml.h"
68 #include "common.h"
70 #ifdef WITH_PINENTRY
71 #include "pinentry.h"
72 #endif
74 #include "commands.h"
75 #include "pwmd_error.h"
76 #include "cache.h"
77 #include "misc.h"
78 #include "pwmd.h"
79 #include "lock.h"
80 #include "rcfile.h"
82 GCRY_THREAD_OPTION_PTH_IMPL;
83 ASSUAN_SYSTEM_PTH_IMPL;
85 static void *reload_rcfile_thread(void *arg)
87 gboolean b = disable_list_and_dump;
88 gchar **users = g_key_file_get_string_list(keyfileh, "global", "allowed",
89 NULL, NULL);
90 GKeyFile *k;
91 pth_attr_t attr = pth_attr_of(pth_self());
93 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
94 pth_attr_destroy(attr);
95 MUTEX_LOCK(&rcfile_mutex);
96 log_write(N_("reloading configuration file '%s'"), rcfile);
97 k = parse_rcfile(FALSE);
99 if (!k)
100 goto done;
102 g_key_file_free(keyfileh);
103 keyfileh = k;
104 parse_rcfile_keys();
105 clear_rcfile_keys();
106 startStopKeepAlive(FALSE);
107 send_status_all(STATUS_CONFIG);
108 done:
109 disable_list_and_dump = !disable_list_and_dump ? b : TRUE;
110 g_key_file_set_string_list(keyfileh, "global", "allowed",
111 (const gchar **)users, g_strv_length(users));
112 g_strfreev(users);
113 MUTEX_UNLOCK(&rcfile_mutex);
114 return NULL;
117 static void reload_rcfile()
119 pth_t tid;
120 pth_attr_t attr = pth_attr_new();
121 gint n;
123 pth_attr_init(attr);
124 pth_attr_set(attr, PTH_ATTR_JOINABLE, 0);
125 tid = pth_spawn(attr, reload_rcfile_thread, NULL);
126 n = errno;
127 pth_attr_destroy(attr);
129 if (!tid)
130 log_write("%s(%i): pth_spawn(): %s", __FILE__, __LINE__,
131 _gpg_strerror(gpg_error_from_errno(n)));
134 gpg_error_t send_syserror(assuan_context_t ctx, gint e)
136 gpg_error_t n = gpg_error_from_errno(e);
137 struct client_s *client = assuan_get_pointer(ctx);
139 client->last_rc = e;
140 return assuan_process_done(ctx, assuan_set_error(ctx, n, _gpg_strerror(n)));
143 gpg_error_t send_error(assuan_context_t ctx, gpg_error_t e)
145 gpg_err_code_t n = gpg_err_code(e);
146 gpg_error_t code = gpg_err_make(PWMD_ERR_SOURCE, n);
147 struct client_s *client = assuan_get_pointer(ctx);
149 if (client)
150 client->last_rc = e;
152 if (!e)
153 return assuan_process_done(ctx, 0);
155 if (!ctx) {
156 log_write("%s", pwmd_strerror(e));
157 return e;
160 if (n == EPWMD_LIBXML_ERROR) {
161 xmlErrorPtr xe = client->xml_error;
163 if (!xe)
164 xe = xmlGetLastError();
166 e = assuan_process_done(ctx, assuan_set_error(ctx, code, xe->message));
167 log_write("%s", xe->message);
169 if (xe == client->xml_error)
170 xmlResetError(xe);
171 else
172 xmlResetLastError();
174 client->xml_error = NULL;
175 return e;
178 return assuan_process_done(ctx, assuan_set_error(ctx, code, pwmd_strerror(e)));
181 void log_write(const gchar *fmt, ...)
183 gchar *args, *line;
184 va_list ap;
185 struct tm *tm;
186 time_t now;
187 gchar tbuf[21];
188 gint fd = -1;
189 gchar *name;
190 gchar buf[255];
191 pth_t tid = pth_self();
192 pth_attr_t attr;
194 if ((!logfile && !isatty(STDERR_FILENO) && log_syslog == FALSE) || !fmt)
195 return;
197 if (!cmdline && logfile) {
198 if ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600)) == -1) {
199 warn("%s", logfile);
200 return;
204 va_start(ap, fmt);
206 if (g_vasprintf(&args, fmt, ap) == -1) {
207 if (logfile)
208 close(fd);
210 va_end(ap);
211 return;
214 va_end(ap);
216 if (cmdline) {
217 fprintf(stderr, "%s\n", args);
218 fflush(stderr);
219 g_free(args);
220 return;
223 attr = pth_attr_of(tid);
225 if (pth_attr_get(attr, PTH_ATTR_NAME, &name) == FALSE)
226 name = "unknown";
228 pth_attr_destroy(attr);
229 name = print_fmt(buf, sizeof(buf), "%s(%p): ", name, tid);
231 if (!cmdline && log_syslog == TRUE)
232 syslog(LOG_INFO, "%s%s", name, args);
234 time(&now);
235 tm = localtime(&now);
236 strftime(tbuf, sizeof(tbuf), "%b %d %Y %H:%M:%S ", tm);
237 tbuf[sizeof(tbuf) - 1] = 0;
239 if (args[strlen(args)-1] == '\n')
240 args[strlen(args)-1] = 0;
242 line = g_strdup_printf("%s %i %s%s\n", tbuf, getpid(), name, args);
243 g_free(args);
245 if (!line) {
246 if (logfile)
247 close(fd);
249 return;
252 if (logfile) {
253 pth_write(fd, line, strlen(line));
254 fsync(fd);
255 close(fd);
258 if (isatty(STDERR_FILENO)) {
259 fprintf(stderr, "%s", line);
260 fflush(stderr);
263 g_free(line);
266 static void usage(gchar *pn, gint rc)
268 g_fprintf(rc == EXIT_FAILURE ? stderr : stdout, N_(
269 "Usage: %s [options] [file1] [...]\n"
270 " --no-fork/-n\n"
271 " run as a foreground process\n"
272 " --rcfile/-f <filename>\n"
273 " load the specified rcfile (~/.pwmd/config)\n"
274 " --convert/-C <filename>\n"
275 " convert a version 1 data file to version 2\n"
276 " --import/-I <filename>\n"
277 " import an XML file\n"
278 " --iterations/-i\n"
279 " encrypt with the specified number of iterations when importing\n"
280 " (default is in the rcfile \"global\" section)\n"
281 " --key-file/-k <filename>\n"
282 " obtain the key from the specified file when importing or converting\n"
283 " --outfile/-o <filename>\n"
284 " output file to use when importing or converting (- for stdout)\n"
285 " --disable-dump/-D\n"
286 " disable use of the LIST, XPATH and DUMP commands\n"
287 " --no-pinentry/-P\n"
288 " disable use of pinentry\n"
289 " --version\n"
290 " --help\n"
291 ), pn);
292 exit(rc);
295 static void setup_gcrypt()
297 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pth);
299 if (!gcry_check_version(GCRYPT_VERSION))
300 errx(EXIT_FAILURE, N_("gcry_check_version(): Incompatible libgcrypt. Wanted %s, got %s."), GCRYPT_VERSION, gcry_check_version(NULL));
302 gcry_set_allocation_handler(xmalloc, xmalloc, NULL, xrealloc, xfree);
305 static gpg_error_t validate_peer(struct client_s *cl)
307 assuan_peercred_t peer;
308 gpg_error_t rc = assuan_get_peercred(cl->ctx, &peer);
309 gchar **users;
310 gboolean allowed = FALSE;
312 if (rc)
313 return rc;
315 users = g_key_file_get_string_list(keyfileh, "global", "allowed", NULL, NULL);
317 if (users) {
318 for (gchar **p = users; *p; p++) {
319 struct passwd pw, *result;
320 struct group gr, *gresult;
321 char *buf;
323 if (*(*p) == '@') {
324 size_t len = sysconf(_SC_GETGR_R_SIZE_MAX);
326 if (len == -1)
327 len = 16384;
329 buf = g_malloc(len);
331 if (!buf) {
332 g_strfreev(users);
333 return gpg_error_from_errno(ENOMEM);
336 if (!getgrnam_r(*(p)+1, &gr, buf, len, &gresult) && gresult) {
337 if (gresult->gr_gid == peer->gid) {
338 g_free(buf);
339 allowed = TRUE;
340 break;
343 len = sysconf(_SC_GETPW_R_SIZE_MAX);
345 if (len == -1)
346 len = 16384;
348 gchar *tbuf = g_malloc(len);
350 for (gchar **t = gresult->gr_mem; *t; t++) {
351 if (!getpwnam_r(*t, &pw, tbuf, len, &result) && result) {
352 if (result->pw_uid == peer->uid) {
353 g_free(buf);
354 allowed = TRUE;
355 break;
360 g_free(tbuf);
362 if (allowed)
363 break;
366 else {
367 size_t len = sysconf(_SC_GETPW_R_SIZE_MAX);
369 if (len == -1)
370 len = 16384;
372 buf = g_malloc(len);
374 if (!buf) {
375 g_strfreev(users);
376 return gpg_error_from_errno(ENOMEM);
379 if (!getpwnam_r(*p, &pw, buf, len, &result) && result) {
380 if (result->pw_uid == peer->uid) {
381 g_free(buf);
382 allowed = TRUE;
383 break;
388 g_free(buf);
391 g_strfreev(users);
394 log_write("peer %s: uid=%i, gid=%i, pid=%i",
395 allowed ? N_("accepted") : N_("rejected"), peer->uid, peer->gid,
396 peer->pid);
397 return allowed ? 0 : GPG_ERR_INV_USER_ID;
400 static gboolean new_connection(struct client_s *cl)
402 gpg_error_t rc;
403 gchar *ver;
404 gchar *str;
406 rc = assuan_new(&cl->ctx);
408 if (rc)
409 goto fail;
411 rc = assuan_init_socket_server(cl->ctx, cl->thd->fd,
412 ASSUAN_SOCKET_SERVER_ACCEPTED);
414 if (rc)
415 goto fail;
417 assuan_set_pointer(cl->ctx, cl);
418 ver = g_strdup_printf("%s", PACKAGE_STRING);
419 assuan_set_hello_line(cl->ctx, ver);
420 g_free(ver);
421 rc = register_commands(cl->ctx);
423 if (rc)
424 goto fail;
426 rc = assuan_accept(cl->ctx);
428 if (rc)
429 goto fail;
431 rc = validate_peer(cl);
433 if (rc)
434 goto fail;
436 str = get_key_file_string("global", "debug_file");
438 if (debugfp && str)
439 assuan_set_log_stream(cl->ctx, debugfp);
441 if (str)
442 g_free(str);
444 return TRUE;
446 fail:
447 log_write("%s", _gpg_strerror(rc));
448 return FALSE;
451 static void xml_error_cb(void *data, xmlErrorPtr e)
453 struct client_s *client = data;
456 * Keep the first reported error as the one to show in the error
457 * description. Reset in send_error().
459 if (client->xml_error)
460 return;
462 xmlCopyError(e, client->xml_error);
465 void close_file_header(file_header_internal_t *fh)
467 if (!fh)
468 return;
470 if (fh->fd != -1 || (cmdline == TRUE && fh->fd != STDOUT_FILENO))
471 close(fh->fd);
473 if (fh->doc)
474 gcry_free(fh->doc);
476 g_free(fh);
479 void cleanup_crypto(struct client_crypto_s **c)
481 struct client_crypto_s *cr = *c;
483 if (!cr)
484 return;
486 if (cr->iv) {
487 gcry_free(cr->iv);
488 cr->iv = NULL;
491 if (cr->key) {
492 gcry_free(cr->key);
493 cr->key = NULL;
496 if (cr->tkey) {
497 gcry_free(cr->tkey);
498 cr->tkey = NULL;
501 if (cr->tkey2) {
502 gcry_free(cr->tkey2);
503 cr->tkey2 = NULL;
506 if (cr->inbuf) {
507 gcry_free(cr->inbuf);
508 cr->inbuf = NULL;
511 if (cr->outbuf) {
512 gcry_free(cr->outbuf);
513 cr->outbuf = NULL;
516 close_file_header(cr->fh);
517 cr->fh = NULL;
519 if (cr->gh)
520 gcry_cipher_close(cr->gh);
522 cr->gh = NULL;
523 g_free(cr);
524 *c = NULL;
528 * This is called after a child_thread terminates. Set with
529 * pth_cleanup_push().
531 static void cleanup_cb(void *arg)
533 struct client_thread_s *cn = arg;
534 struct client_s *cl = cn->cl;
536 MUTEX_LOCK(&cn_mutex);
537 cn_thread_list = g_slist_remove(cn_thread_list, cn);
538 MUTEX_UNLOCK(&cn_mutex);
540 if (cn->msg_tid) {
541 MUTEX_LOCK(&cn->mp_mutex);
542 pth_cancel(cn->msg_tid);
543 MUTEX_UNLOCK(&cn->mp_mutex);
546 if (cn->mp) {
547 while (pth_msgport_pending(cn->mp)) {
548 pth_message_t *msg = pth_msgport_get(cn->mp);
550 g_free(msg->m_data);
551 g_free(msg);
554 pth_msgport_destroy(cn->mp);
557 if (!cl) {
558 if (cn->fd != -1)
559 close(cn->fd);
561 goto done;
564 if (!cl->freed)
565 cleanup_client(cl);
567 if (cl->ctx)
568 assuan_release(cl->ctx);
569 else if (cl->thd && cl->thd->fd != -1)
570 close(cl->thd->fd);
572 #ifdef WITH_PINENTRY
573 if (cl->pinentry)
574 cleanup_pinentry(cl->pinentry);
575 #endif
577 if (cl->crypto)
578 cleanup_crypto(&cl->crypto);
580 g_free(cl);
581 done:
582 log_write(N_("exiting, fd=%i"), cn->fd);
583 g_free(cn);
584 send_status_all(STATUS_CLIENTS);
588 * Called every time a connection is made from init_new_connection(). This is
589 * the thread entry point.
591 static void *client_thread(void *data)
593 struct client_thread_s *thd = data;
594 struct client_s *cl = g_malloc0(sizeof(struct client_s));
595 gpg_error_t rc;
596 pth_attr_t attr;
597 gint n;
600 * Prevent a race condition with init_new_connection() if this thread
601 * fails (returns) for some reason before init_new_connection() releases
602 * the cn_mutex.
604 MUTEX_LOCK(&cn_mutex);
605 MUTEX_UNLOCK(&cn_mutex);
606 pth_cleanup_push(cleanup_cb, thd);
608 if (!cl) {
609 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
610 goto fail;
613 attr = pth_attr_of(pth_self());
614 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
615 pth_attr_destroy(attr);
616 thd->cl = cl;
617 cl->thd = thd;
619 if (!new_connection(cl))
620 goto fail;
622 #ifdef WITH_PINENTRY
623 cl->pinentry = pinentry_init();
625 if (!cl->pinentry) {
626 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
627 goto fail;
629 #endif
631 #ifdef HAVE_MLOCKALL
632 if (disable_mlock == FALSE && mlockall(MCL_FUTURE) == -1) {
633 log_write("mlockall(): %s", strerror(errno));
634 goto fail;
636 #endif
638 thd->mp = pth_msgport_create(NULL);
639 pth_mutex_init(&thd->mp_mutex);
640 thd->msg_tid = pth_spawn(NULL, client_msg_thread, thd);
641 n = errno;
643 if (!thd->msg_tid) {
644 log_write("%s(%i): pth_spawn(): %s", __FILE__, __LINE__,
645 _gpg_strerror(gpg_error_from_errno(n)));
646 goto fail;
649 pth_yield(thd->msg_tid);
650 rc = send_status(cl->ctx, STATUS_CACHE, NULL);
652 if (rc) {
653 log_write("%s", _gpg_strerror(rc));
654 goto fail;
657 send_status_all(STATUS_CLIENTS);
658 xmlSetStructuredErrorFunc(cl, xml_error_cb);
660 for (;;) {
661 #ifdef WITH_PINENTRY
662 pth_event_t pev = NULL;
663 #endif
664 pth_status_t st, wst;
665 pth_event_t wev = NULL;
666 pth_event_t rev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_READABLE,
667 cl->thd->fd);
668 pth_event_t ev = rev;
670 #ifdef WITH_PINENTRY
671 if (cl->pinentry->status == PINENTRY_RUNNING) {
672 pev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_READABLE, cl->pinentry->fd);
673 ev = pth_event_concat(ev, pev, NULL);
675 #endif
677 if (cl->inquire_status == INQUIRE_BUSY) {
678 wev = pth_event(PTH_EVENT_FD|PTH_UNTIL_FD_WRITEABLE, cl->thd->fd);
679 ev = pth_event_concat(ev, wev, NULL);
682 pth_cleanup_push(cleanup_ev_cb, ev);
683 pth_wait(ev);
684 st = pth_event_status(rev);
685 wst = pth_event_status(wev);
687 if (st == PTH_STATUS_OCCURRED || wst == PTH_STATUS_OCCURRED) {
688 int ended;
690 rc = assuan_process_next(cl->ctx, &ended);
692 if (ended)
693 goto done;
695 if (rc) {
696 cl->inquire_status = INQUIRE_INIT;
697 pth_cleanup_pop(1);
699 if (gpg_err_code(rc) == GPG_ERR_EOF)
700 goto done;
702 log_write("assuan_process_next(): %s", _gpg_strerror(rc));
703 rc = send_error(cl->ctx, gpg_err_make(PWMD_ERR_SOURCE, rc));
705 if (rc) {
706 log_write("assuan_process_done(): %s", _gpg_strerror(rc));
707 goto done;
710 else {
711 #ifdef WITH_PINENTRY
712 if (cl->pinentry->pid && cl->pinentry->status == PINENTRY_INIT)
713 cl->pinentry->status = PINENTRY_RUNNING;
714 #endif
716 switch (cl->inquire_status) {
717 case INQUIRE_BUSY:
718 case INQUIRE_INIT:
719 break;
720 case INQUIRE_DONE:
721 cl->inquire_status = INQUIRE_INIT;
722 rc = assuan_process_done(cl->ctx, 0);
723 break;
728 #ifdef WITH_PINENTRY
729 if (pev)
730 st = pth_event_status(pev);
732 rc = pinentry_iterate(cl,
733 pev && cl->pinentry->fd != -1 && st == PTH_STATUS_OCCURRED);
734 #endif
735 pth_cleanup_pop(1);
739 * Client cleanup (including XML data) is done in cleanup_cb().
741 done:
742 fail:
743 pth_exit(PTH_CANCELED);
744 return NULL;
747 static gchar *do_read_password(const gchar *prompt)
749 gchar buf[LINE_MAX] = {0}, *p;
750 struct termios told, tnew;
751 gchar *key;
753 if (tcgetattr(STDIN_FILENO, &told) == -1) {
754 log_write("tcgetattr(): %s", strerror(errno));
755 return NULL;
758 memcpy(&tnew, &told, sizeof(struct termios));
759 tnew.c_lflag &= ~(ECHO);
760 tnew.c_lflag |= ICANON|ECHONL;
762 if (tcsetattr(STDIN_FILENO, TCSANOW, &tnew) == -1) {
763 log_write("tcsetattr(): %s", strerror(errno));
764 tcsetattr(STDIN_FILENO, TCSANOW, &told);
765 return NULL;
768 fprintf(stderr, "%s", prompt);
770 if ((p = fgets(buf, sizeof(buf), stdin)) == NULL) {
771 tcsetattr(STDIN_FILENO, TCSANOW, &told);
772 return NULL;
775 tcsetattr(STDIN_FILENO, TCSANOW, &told);
776 p[strlen(p) - 1] = 0;
778 if (!buf[0]) {
779 key = gcry_malloc(1);
780 key[0] = 0;
782 else {
783 key = gcry_malloc(strlen(p) + 1);
784 sprintf(key, "%s", p);
787 memset(&buf, 0, sizeof(buf));
788 return key;
791 /* Only used when "enable_pinentry" is "false" or -P. */
792 static gpg_error_t read_password(const gchar *filename,
793 struct client_crypto_s *crypto, guchar *key, pinentry_cmd_t which)
795 gchar *prompt;
797 if (which == PINENTRY_SAVE) {
798 prompt = g_strdup_printf(N_("New passphrase for file %s: "), filename);
799 crypto->tkey = do_read_password(prompt);
800 g_free(prompt);
802 if (!crypto->tkey) {
803 log_write(N_("%s: Skipping file"), filename);
804 return GPG_ERR_BAD_PASSPHRASE;
807 prompt = g_strdup_printf(N_("Repeat passphrase: "));
808 crypto->tkey2 = do_read_password(prompt);
809 g_free(prompt);
811 if (!crypto->tkey2) {
812 log_write(N_("%s: Skipping file"), filename);
813 return GPG_ERR_BAD_PASSPHRASE;
816 if (strcmp(crypto->tkey, crypto->tkey2)) {
817 log_write(N_("%s: Passphrase mismatch"), filename);
818 return EPWMD_BADKEY;
821 gcry_md_hash_buffer(GCRY_MD_SHA256, key, crypto->tkey,
822 strlen(crypto->tkey) ? strlen(crypto->tkey) : 1);
823 return 0;
826 prompt = g_strdup_printf(N_("Passphrase required for %s: "), filename);
828 if ((crypto->tkey = do_read_password(prompt)) == NULL) {
829 log_write(N_("%s: Skipping file"), filename);
830 g_free(prompt);
831 return GPG_ERR_BAD_PASSPHRASE;
834 gcry_md_hash_buffer(GCRY_MD_SHA256, key, crypto->tkey,
835 strlen(crypto->tkey) ? strlen(crypto->tkey) : 1);
836 g_free(prompt);
837 return 0;
841 * inbuf must have been allocated with gcry_malloc().
843 gpg_error_t export_common(const gchar *filename, struct client_crypto_s *crypto,
844 gpointer inbuf, gulong insize)
846 gpg_error_t rc;
847 gint level, zrc;
848 gulong outsize;
849 gpointer outbuf;
851 rc = update_save_flags(NULL, crypto);
853 if (rc)
854 return rc;
856 level = get_key_file_integer(filename, "compression_level");
858 if (level < 0)
859 level = 0;
861 if (do_compress(NULL, level, inbuf, insize, &outbuf, &outsize, &zrc)
862 == FALSE) {
863 return zrc == Z_MEM_ERROR ? GPG_ERR_ENOMEM : GPG_ERR_COMPR_ALGO;
866 crypto->inbuf = outbuf;
867 crypto->insize = outsize;
868 rc = do_xml_encrypt(NULL, crypto, filename);
869 return rc;
872 static gpg_error_t get_password(const gchar *filename,
873 struct client_crypto_s *crypto, guchar *md5file, guchar *key,
874 pinentry_cmd_t which)
876 #ifdef WITH_PINENTRY
877 gpg_error_t rc = 0;
879 if (g_key_file_get_boolean(keyfileh, "global", "enable_pinentry", NULL)
880 == FALSE) {
881 #endif
882 return read_password(filename, crypto, key, which);
883 #ifdef WITH_PINENTRY
885 else {
886 gchar *result = NULL;
887 struct pinentry_s *pin = g_malloc0(sizeof(struct pinentry_s));
889 pth_mutex_init(&pin->status_mutex);
890 set_pinentry_defaults(pin);
891 pin->which = which;
892 pin->filename = g_strdup(filename);
893 rc = pinentry_getpin(pin, &result);
895 if (rc) {
896 xfree(result);
897 goto done;
900 gcry_md_hash_buffer(GCRY_MD_SHA256, key, result, result ? strlen(result) : 1);
901 xfree(result);
902 cleanup_pinentry(pin);
905 done:
906 return rc;
907 #endif
910 static gboolean xml_import(const gchar *filename, const gchar *outfile,
911 const gchar *keyfile, guint64 iter)
913 xmlDocPtr doc;
914 gint fd;
915 struct stat st;
916 gint len;
917 xmlChar *xmlbuf;
918 xmlChar *xml;
919 gpg_error_t rc;
920 struct client_crypto_s *crypto;
921 guint hashlen = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
923 if (stat(filename, &st) == -1) {
924 log_write("%s: %s", filename, strerror(errno));
925 return FALSE;
928 crypto = init_client_crypto();
930 if (!crypto)
931 return FALSE;
933 crypto->key = gcry_malloc(hashlen);
934 memset(crypto->key, 0, hashlen);
936 if (!crypto->key) {
937 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
938 goto fail;
941 log_write(N_("Importing XML from '%s'. Output will be written to '%s' ..."),
942 filename, outfile);
944 if (iter && keyfile) {
945 crypto->tkey = parse_rcfile_keyfile(keyfile, TRUE, &rc);
947 if (!crypto->tkey)
948 goto fail;
950 gcry_md_hash_buffer(GCRY_MD_SHA256, crypto->key, crypto->tkey,
951 strlen(crypto->tkey) ? strlen(crypto->tkey) : 1);
953 else if (iter) {
954 rc = get_password(outfile, crypto, NULL, crypto->key, PINENTRY_SAVE);
956 if (rc == GPG_ERR_ASSUAN_SERVER_FAULT) {
957 log_write(N_("%s. Maybe disabling pinentry (-P) will help?"),
958 pwmd_strerror(rc));
959 goto fail;
961 else if (rc) {
962 log_write("%s", pwmd_strerror(rc));
963 goto fail;
967 if ((fd = open(filename, O_RDONLY)) == -1) {
968 log_write("%s: %s", filename, strerror(errno));
969 goto fail;
972 if ((xmlbuf = gcry_malloc(st.st_size+1)) == NULL) {
973 close(fd);
974 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
975 goto fail;
978 if (pth_read(fd, xmlbuf, st.st_size) == -1) {
979 rc = errno;
980 close(fd);
981 errno = rc;
982 log_write("%s: %s", filename, strerror(errno));
983 goto fail;
986 close(fd);
987 xmlbuf[st.st_size] = 0;
990 * Make sure the document validates.
992 if ((doc = xmlReadDoc(xmlbuf, NULL, "UTF-8", XML_PARSE_NOBLANKS)) == NULL) {
993 log_write("xmlReadDoc() failed");
994 gcry_free(xmlbuf);
995 goto fail;
998 gcry_free(xmlbuf);
999 xmlDocDumpMemory(doc, &xml, &len);
1000 xmlFreeDoc(doc);
1002 if (!iter)
1003 memset(crypto->key, '!', hashlen);
1005 crypto->fh = g_malloc0(sizeof(file_header_internal_t));
1007 if (!crypto->fh) {
1008 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
1009 goto fail;
1012 crypto->fh->ver.fh2.iter = iter;
1013 rc = export_common(outfile, crypto, xml, len);
1014 xmlFree(xml);
1016 if (rc) {
1017 send_error(NULL, rc);
1018 goto fail;
1021 cleanup_crypto(&crypto);
1022 return TRUE;
1024 fail:
1025 cleanup_crypto(&crypto);
1026 return FALSE;
1029 gboolean do_cache_push(const gchar *filename, const gchar *password)
1031 guchar md5file[16];
1032 gint timeout;
1033 const gchar *p = filename;
1034 struct client_crypto_s *crypto;
1035 gpg_error_t rc;
1036 guint hashlen = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
1038 while (isspace(*p))
1039 p++;
1041 if (!*p)
1042 return FALSE;
1044 if (valid_filename(p) == FALSE) {
1045 log_write(N_("%s: Invalid characters in filename"), p);
1046 return FALSE;
1049 gcry_md_hash_buffer(GCRY_MD_MD5, md5file, p, strlen(p));
1051 if (access(p, R_OK|W_OK) != 0) {
1052 log_write("%s: %s", p, strerror(errno));
1053 return FALSE;
1056 crypto = init_client_crypto();
1058 if (!crypto)
1059 return FALSE;
1061 crypto->fh = read_file_header(filename, FALSE, &rc);
1063 if (!crypto->fh) {
1064 log_write("%s: %s", p, pwmd_strerror(rc));
1065 cleanup_crypto(&crypto);
1066 return FALSE;
1069 crypto->key = gcry_malloc(hashlen);
1071 if (!crypto->key) {
1072 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
1073 cleanup_crypto(&crypto);
1074 return FALSE;
1077 log_write(N_("Adding '%s' to the file cache ..."), filename);
1079 if (crypto->fh->ver.fh2.iter <= 0ULL) {
1080 memset(crypto->key, '!', hashlen);
1081 goto try_decrypt;
1084 if (!password) {
1085 rc = get_password(p, crypto, md5file, crypto->key, PINENTRY_OPEN);
1087 if (rc) {
1088 send_error(NULL, rc);
1089 cleanup_crypto(&crypto);
1090 return FALSE;
1093 gcry_free(crypto->fh->doc);
1094 crypto->fh->doc = NULL;
1096 else
1097 gcry_md_hash_buffer(GCRY_MD_SHA256, crypto->key, password,
1098 strlen(password) ? strlen(password) : 1);
1100 try_decrypt:
1101 rc = init_client_crypto2(filename, crypto);
1103 if (rc) {
1104 send_error(NULL, rc);
1105 cleanup_crypto(&crypto);
1106 return FALSE;
1109 rc = try_xml_decrypt(NULL, crypto->key, crypto, NULL, NULL);
1111 if (rc) {
1112 log_write("%s: %s", filename, pwmd_strerror(rc));
1113 cleanup_crypto(&crypto);
1114 return FALSE;
1117 if (cache_update_key(md5file, crypto->key) == FALSE) {
1118 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
1119 cleanup_crypto(&crypto);
1120 return FALSE;
1123 timeout = get_key_file_integer(p, "cache_timeout");
1124 cache_set_timeout(md5file, timeout);
1125 log_write(N_("File '%s' now cached"), filename);
1126 cleanup_crypto(&crypto);
1127 return TRUE;
1130 static void init_new_connection(gint fd)
1132 pth_attr_t attr;
1133 struct client_thread_s *new;
1134 gint n;
1136 new = g_malloc0(sizeof(struct client_thread_s));
1138 if (!new) {
1139 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
1140 close(fd);
1141 return;
1144 MUTEX_LOCK(&cn_mutex);
1145 new->fd = fd;
1146 attr = pth_attr_new();
1147 pth_attr_init(attr);
1148 pth_attr_set(attr, PTH_ATTR_JOINABLE, FALSE);
1149 new->tid = pth_spawn(attr, client_thread, new);
1150 n = errno;
1151 pth_attr_destroy(attr);
1153 if (!new->tid) {
1154 g_free(new);
1155 close(fd);
1156 log_write("%s(%i): pth_spawn(): %s", __FILE__, __LINE__,
1157 _gpg_strerror(gpg_error_from_errno(n)));
1158 MUTEX_UNLOCK(&cn_mutex);
1159 return;
1162 cn_thread_list = g_slist_append(cn_thread_list, new);
1163 MUTEX_UNLOCK(&cn_mutex);
1164 log_write(N_("new connection: tid=%p, fd=%i"), new->tid, fd);
1167 static void *accept_thread(void *arg)
1169 gint sockfd = *(gint *)arg;
1170 pth_attr_t attr = pth_attr_of(pth_self());
1172 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
1173 pth_attr_destroy(attr);
1175 for (;;) {
1176 socklen_t slen = sizeof(struct sockaddr_un);
1177 struct sockaddr_un raddr;
1178 gint fd = -1;
1180 fd = pth_accept(sockfd, (struct sockaddr *)&raddr, &slen);
1182 if (fd == -1) {
1183 if (errno != EAGAIN) {
1184 if (!quit) // probably EBADF
1185 log_write("accept(): %s", strerror(errno));
1187 break;
1190 continue;
1193 init_new_connection(fd);
1196 /* Just in case accept() failed for some reason other than EBADF */
1197 quit = 1;
1198 pth_exit(PTH_CANCELED);
1199 return NULL;
1202 static void *adjust_cache_timer_thread(void *arg)
1204 pth_attr_t attr = pth_attr_of(pth_self());
1206 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
1207 pth_attr_destroy(attr);
1209 for (;;) {
1210 pth_sleep(1);
1211 CACHE_LOCK(NULL);
1212 cache_adjust_timer();
1213 CACHE_UNLOCK;
1216 return NULL;
1219 void cleanup_mutex_cb(void *arg)
1221 pth_mutex_t *m = arg;
1223 MUTEX_UNLOCK(m);
1226 void cleanup_ev_cb(void *arg)
1228 pth_event_t ev = arg;
1230 pth_event_free(ev, PTH_FREE_ALL);
1233 void cleanup_fd_cb(void *arg)
1235 gint fd = *(gint *)arg;
1237 close(fd);
1240 void cleanup_unlink_cb(void *arg)
1242 gchar *file = arg;
1244 unlink(file);
1247 void cleanup_cancel_cb(void *arg)
1249 pth_t tid = arg;
1250 pth_attr_t attr;
1251 gint join;
1253 attr = pth_attr_of(tid);
1254 pth_attr_get(attr, PTH_ATTR_JOINABLE, &join);
1255 pth_cancel(tid);
1257 if (join) {
1258 gpg_error_t rc;
1259 pth_join(tid, (void **)&rc);
1263 static void *keepalive_thread(void *arg)
1265 gint to = *(gint *)arg;
1266 pth_attr_t attr = pth_attr_of(pth_self());
1268 pth_attr_set(attr, PTH_ATTR_NAME, __FUNCTION__);
1269 pth_attr_destroy(attr);
1271 for (;;) {
1272 pth_event_t ev = pth_event(PTH_EVENT_TIME, pth_timeout(to, 0));
1274 pth_cleanup_push(cleanup_ev_cb, ev);
1275 pth_wait(ev);
1276 send_status_all(STATUS_KEEPALIVE);
1277 pth_cleanup_pop(1);
1280 return NULL;
1283 static void startStopKeepAlive(gboolean term)
1285 gint n = get_key_file_integer("global", "keepalive");
1287 if (keepalive_tid)
1288 pth_cancel(keepalive_tid);
1290 keepalive_tid = NULL;
1292 if (term)
1293 return;
1295 if (n > 0) {
1296 gint e;
1297 pth_attr_t attr = pth_attr_new();
1299 pth_attr_init(attr);
1300 pth_attr_set(attr, PTH_ATTR_JOINABLE, FALSE);
1301 keepalive_tid = pth_spawn(attr, keepalive_thread, &n);
1302 e = errno;
1303 pth_attr_destroy(attr);
1305 if (!keepalive_tid) {
1306 log_write("%s(%i): pth_spawn(): %s", __FILE__, __LINE__,
1307 _gpg_strerror(gpg_error_from_errno(e)));
1308 return;
1311 pth_yield(keepalive_tid);
1315 static gboolean waiting_for_exit()
1317 guint i, t;
1318 pth_event_t evs = NULL;
1320 MUTEX_LOCK(&cn_mutex);
1322 for (t = g_slist_length(cn_thread_list), i = 0; i < t; i++) {
1323 struct client_thread_s *thd = g_slist_nth_data(cn_thread_list, i);
1324 pth_event_t ev = pth_event(PTH_EVENT_TID|PTH_UNTIL_TID_DEAD, thd->tid);
1326 if (evs)
1327 evs = pth_event_concat(evs, ev, NULL);
1328 else
1329 evs = ev;
1332 MUTEX_UNLOCK(&cn_mutex);
1334 if (!evs)
1335 return FALSE;
1337 pth_wait(evs);
1338 MUTEX_LOCK(&cn_mutex);
1339 i = g_slist_length(cn_thread_list);
1340 MUTEX_UNLOCK(&cn_mutex);
1341 pth_event_free(evs, PTH_FREE_ALL);
1342 return i ? TRUE : FALSE;
1345 static void catch_sigabrt(int sig)
1347 cache_clear(NULL, 2);
1348 #ifndef MEM_DEBUG
1349 xpanic();
1350 #endif
1353 static void server_loop(gint sockfd, gchar **socketpath)
1355 pth_t accept_tid;
1356 guint n;
1357 sigset_t sigset;
1358 pth_attr_t attr;
1359 pth_t cache_timeout_tid;
1361 sigemptyset(&sigset);
1363 /* Termination */
1364 sigaddset(&sigset, SIGTERM);
1365 sigaddset(&sigset, SIGINT);
1367 /* Clears the file cache. */
1368 sigaddset(&sigset, SIGUSR1);
1370 /* Configuration file reloading. */
1371 sigaddset(&sigset, SIGHUP);
1373 /* Clears the cache and exits when something bad happens. */
1374 signal(SIGABRT, catch_sigabrt);
1375 sigaddset(&sigset, SIGABRT);
1377 /* Ignored everywhere. When a client disconnects abnormally this signal
1378 * gets raised. It isn't needed though because client_thread() will check
1379 * for rcs even after the client disconnects. */
1380 signal(SIGPIPE, SIG_IGN);
1381 sigprocmask(SIG_BLOCK, &sigset, NULL);
1383 log_write(N_("%s started for user %s"), PACKAGE_STRING, g_get_user_name());
1384 log_write(N_("Listening on %s"), *socketpath);
1385 attr = pth_attr_new();
1386 pth_attr_init(attr);
1387 accept_tid = pth_spawn(attr, accept_thread, &sockfd);
1389 if (!accept_tid) {
1390 log_write("%s(%i): pth_spawn(): %s", __FILE__, __LINE__,
1391 _gpg_strerror(gpg_error_from_errno(errno)));
1392 pth_attr_destroy(attr);
1393 goto done;
1396 pth_yield(accept_tid);
1397 startStopKeepAlive(FALSE);
1398 pth_attr_set(attr, PTH_ATTR_JOINABLE, FALSE);
1399 cache_timeout_tid = pth_spawn(attr, adjust_cache_timer_thread, NULL);
1401 if (!cache_timeout_tid) {
1402 log_write("%s(%i): pth_spawn(): %s", __FILE__, __LINE__,
1403 _gpg_strerror(gpg_error_from_errno(errno)));
1404 pth_attr_destroy(attr);
1405 goto done;
1408 pth_yield(cache_timeout_tid);
1409 pth_attr_destroy(attr);
1412 gchar *str = get_key_file_string("global", "debug_file");
1414 if (str) {
1415 gchar *f = expand_homedir(str);
1417 g_free(str);
1418 debugfp = fopen(f, "w");
1420 if (!debugfp)
1421 log_write("%s: %s", f, pwmd_strerror(gpg_error_from_errno(errno)));
1422 else
1423 assuan_set_assuan_log_stream(debugfp);
1425 g_free(f);
1429 do {
1430 gint sig;
1432 pth_sigwait(&sigset, &sig);
1433 log_write(N_("caught signal %i (%s)"), sig, strsignal(sig));
1435 /* Caught a signal. */
1436 switch (sig) {
1437 case SIGHUP:
1438 reload_rcfile();
1439 break;
1440 case SIGABRT:
1441 // not really handled here.
1442 catch_sigabrt(SIGABRT);
1443 break;
1444 case SIGUSR1:
1445 CACHE_LOCK(NULL);
1446 log_write(N_("clearing file cache"));
1447 cache_clear(NULL, 2);
1448 CACHE_UNLOCK;
1449 break;
1450 default:
1451 quit = 1;
1452 break;
1454 } while (!quit);
1456 done:
1458 * We're out of the main server loop. This happens when a signal was sent
1459 * to terminate the daemon. We'll wait for all clients to disconnect
1460 * before exiting and ignore any following signals.
1462 shutdown(sockfd, SHUT_RDWR);
1463 close(sockfd);
1464 pth_cancel(accept_tid);
1465 pth_join(accept_tid, NULL);
1466 unlink(*socketpath);
1467 g_free(*socketpath);
1468 *socketpath = NULL;
1469 MUTEX_LOCK(&cn_mutex);
1470 n = g_slist_length(cn_thread_list);
1471 MUTEX_UNLOCK(&cn_mutex);
1473 if (n) {
1474 log_write(N_("waiting for all clients to disconnect"));
1476 do {
1477 MUTEX_LOCK(&cn_mutex);
1478 n = g_slist_length(cn_thread_list);
1479 MUTEX_UNLOCK(&cn_mutex);
1480 log_write(N_("%i clients remain"), n);
1481 } while (waiting_for_exit());
1484 startStopKeepAlive(TRUE);
1485 pth_cancel(cache_timeout_tid);
1486 cache_free();
1490 * Only called from pinentry_fork() in the child process.
1492 void free_client_list()
1494 gint i, t = g_slist_length(cn_thread_list);
1496 for (i = 0; i < t; i++) {
1497 struct client_thread_s *cn = g_slist_nth_data(cn_thread_list, i);
1499 free_client(cn->cl);
1502 cache_free();
1505 static guint pwmd_cipher_to_gcrypt(guint64 flags)
1507 if (flags & PWMD_CIPHER_AES128)
1508 return GCRY_CIPHER_AES128;
1509 else if (flags & PWMD_CIPHER_AES192)
1510 return GCRY_CIPHER_AES192;
1511 else if (flags & PWMD_CIPHER_AES256)
1512 return GCRY_CIPHER_AES256;
1513 else if (flags & PWMD_CIPHER_SERPENT128)
1514 return GCRY_CIPHER_SERPENT128;
1515 else if (flags & PWMD_CIPHER_SERPENT192)
1516 return GCRY_CIPHER_SERPENT192;
1517 else if (flags & PWMD_CIPHER_SERPENT256)
1518 return GCRY_CIPHER_SERPENT256;
1519 else if (flags & PWMD_CIPHER_CAMELLIA128)
1520 return GCRY_CIPHER_CAMELLIA128;
1521 else if (flags & PWMD_CIPHER_CAMELLIA192)
1522 return GCRY_CIPHER_CAMELLIA192;
1523 else if (flags & PWMD_CIPHER_CAMELLIA256)
1524 return GCRY_CIPHER_CAMELLIA256;
1525 else if (flags & PWMD_CIPHER_BLOWFISH)
1526 return GCRY_CIPHER_BLOWFISH;
1527 else if (flags & PWMD_CIPHER_3DES)
1528 return GCRY_CIPHER_3DES;
1529 else if (flags & PWMD_CIPHER_CAST5)
1530 return GCRY_CIPHER_CAST5;
1531 else if (flags & PWMD_CIPHER_TWOFISH)
1532 return GCRY_CIPHER_TWOFISH;
1533 else if (flags & PWMD_CIPHER_TWOFISH128)
1534 return GCRY_CIPHER_TWOFISH128;
1536 /* For backwards compatibility (no flags). */
1537 return GCRY_CIPHER_AES256;
1540 guint pwmd_cipher_str_to_cipher(const gchar *str)
1542 guint64 flags = 0;
1544 if (!g_strcasecmp(str, "aes128"))
1545 flags = PWMD_CIPHER_AES128;
1546 else if (!g_strcasecmp(str, "aes192"))
1547 flags = PWMD_CIPHER_AES192;
1548 else if (!g_strcasecmp(str, "aes256"))
1549 flags = PWMD_CIPHER_AES256;
1550 if (!g_strcasecmp(str, "serpent128"))
1551 flags = PWMD_CIPHER_SERPENT128;
1552 else if (!g_strcasecmp(str, "serpent192"))
1553 flags = PWMD_CIPHER_SERPENT192;
1554 else if (!g_strcasecmp(str, "serpent256"))
1555 flags = PWMD_CIPHER_SERPENT256;
1556 if (!g_strcasecmp(str, "camellia128"))
1557 flags = PWMD_CIPHER_CAMELLIA128;
1558 else if (!g_strcasecmp(str, "camellia192"))
1559 flags = PWMD_CIPHER_CAMELLIA192;
1560 else if (!g_strcasecmp(str, "camellia256"))
1561 flags = PWMD_CIPHER_CAMELLIA256;
1562 else if (!g_strcasecmp(str, "blowfish"))
1563 flags = PWMD_CIPHER_BLOWFISH;
1564 else if (!g_strcasecmp(str, "cast5"))
1565 flags = PWMD_CIPHER_CAST5;
1566 else if (!g_strcasecmp(str, "3des"))
1567 flags = PWMD_CIPHER_3DES;
1568 else if (!g_strcasecmp(str, "twofish256"))
1569 flags = PWMD_CIPHER_TWOFISH;
1570 else if (!g_strcasecmp(str, "twofish128"))
1571 flags = PWMD_CIPHER_TWOFISH128;
1573 return flags;
1576 /* To be called after read_file_header(). This sets the wanted algorithm from
1577 * .flags */
1578 gpg_error_t init_client_crypto2(const char *filename,
1579 struct client_crypto_s *crypto)
1581 gpg_error_t rc;
1582 guint algo;
1584 /* New file or conversion. */
1585 if (crypto->fh->v1)
1586 algo = pwmd_cipher_to_gcrypt(PWMD_CIPHER_AES256);
1587 else if (!crypto->fh->ver.fh2.flags) {
1588 gchar *tmp = get_key_file_string(filename ? filename : "global", "cipher");
1589 guint64 flags;
1591 flags = pwmd_cipher_str_to_cipher(tmp);
1592 g_free(tmp);
1593 algo = pwmd_cipher_to_gcrypt(flags);
1594 crypto->fh->ver.fh2.flags = flags;
1596 else
1597 algo = pwmd_cipher_to_gcrypt(crypto->fh->ver.fh2.flags);
1599 rc = gcry_cipher_algo_info(algo, GCRYCTL_TEST_ALGO, NULL, NULL);
1601 if (rc)
1602 return rc;
1604 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_KEYLEN, NULL,
1605 &crypto->keysize);
1607 if (rc)
1608 return rc;
1610 rc = gcry_cipher_algo_info(algo, GCRYCTL_GET_BLKLEN, NULL,
1611 &crypto->blocksize);
1613 if (rc)
1614 return rc;
1616 if (crypto->gh)
1617 gcry_cipher_close(crypto->gh);
1619 return gcry_cipher_open(&crypto->gh, algo, GCRY_CIPHER_MODE_CBC, 0);
1622 struct client_crypto_s *init_client_crypto()
1624 struct client_crypto_s *new = g_malloc0(sizeof(struct client_crypto_s));
1626 if (!new) {
1627 log_write("%s(%i): %s", __FILE__, __LINE__, strerror(ENOMEM));
1628 return NULL;
1631 return new;
1634 static gpg_error_t convert_file(const gchar *filename, const gchar *keyfile,
1635 const gchar *outfile)
1637 gpg_error_t rc;
1638 guchar md5file[gcry_md_get_algo_dlen(GCRY_MD_MD5)];
1639 guint64 iter;
1640 struct client_crypto_s *crypto = init_client_crypto();
1641 guint hashlen = gcry_md_get_algo_dlen(GCRY_MD_SHA256);
1643 if (!crypto)
1644 return GPG_ERR_ENOMEM;
1646 crypto->key = gcry_malloc(hashlen);
1648 if (!crypto->key) {
1649 cleanup_crypto(&crypto);
1650 return GPG_ERR_ENOMEM;
1653 log_write(N_("Converting version 1 data file '%s' to version 2 ..."),
1654 filename);
1655 crypto->fh = read_file_header(filename, TRUE, &rc);
1657 if (!crypto->fh)
1658 goto done;
1660 gcry_md_hash_buffer(GCRY_MD_MD5, md5file, filename, strlen(filename));
1662 /* The header in version 1 had a bug where the iterations were off-by-one.
1663 * So 0 iterations was really -1 in the header. This is fixed in v2 of the
1664 * header.
1666 if (crypto->fh->ver.fh1.iter != -1) {
1667 if (keyfile) {
1668 crypto->tkey = parse_rcfile_keyfile(keyfile, TRUE, &rc);
1670 if (!crypto->tkey)
1671 goto done;
1673 gcry_md_hash_buffer(GCRY_MD_SHA256, crypto->key, crypto->tkey,
1674 strlen(crypto->tkey) ? strlen(crypto->tkey) : 1);
1676 else {
1677 rc = get_password(filename, crypto, md5file, crypto->key,
1678 PINENTRY_OPEN);
1680 if (rc)
1681 goto done;
1685 rc = init_client_crypto2(NULL, crypto);
1687 if (rc)
1688 goto done;
1690 rc = try_xml_decrypt(NULL, crypto->key, crypto, &crypto->fh->doc,
1691 &crypto->fh->len);
1693 if (rc)
1694 goto done;
1696 rc = convert_xml((gchar **)&crypto->fh->doc, &crypto->fh->len);
1698 if (rc) {
1699 log_write("%s: %s", filename, pwmd_strerror(rc));
1700 goto done;
1703 crypto->fh->v1 = FALSE;
1705 iter = crypto->fh->ver.fh1.iter+1;
1706 memset(&crypto->fh->ver.fh2, 0, sizeof(crypto->fh->ver.fh2));
1707 /* Keep the iterations and key from the original file. */
1708 crypto->fh->ver.fh2.iter = iter;
1709 rc = export_common(outfile, crypto, crypto->fh->doc, crypto->fh->len);
1711 done:
1712 if (rc)
1713 send_error(NULL, rc);
1715 /* fh->doc is freed from do_xml_decrypt() via the inbuf pointer. */
1716 cleanup_crypto(&crypto);
1717 return rc;
1720 int main(int argc, char *argv[])
1722 gint opt;
1723 struct sockaddr_un addr;
1724 gchar buf[PATH_MAX];
1725 gchar *socketpath = NULL, *socketdir, *socketname = NULL;
1726 gchar *socketarg = NULL;
1727 gchar *datadir = NULL;
1728 gboolean n;
1729 gint x;
1730 gchar *p;
1731 gchar **cache_push = NULL;
1732 gchar *import = NULL, *keyfile = NULL;
1733 guint64 cmd_iterations = 0UL;
1734 gboolean iterations_arg = FALSE;
1735 gint default_timeout;
1736 gboolean rcfile_spec = FALSE;
1737 gint estatus = EXIT_FAILURE;
1738 gint sockfd;
1739 gchar *outfile = NULL;
1740 GMemVTable mtable = { xmalloc, xrealloc, xfree, xcalloc, NULL, NULL };
1741 gint do_unlink = 1;
1742 gboolean secure = FALSE;
1743 gint background = 1;
1744 gchar *convert = NULL;
1745 gint show_version = 0;
1746 gint show_help = 0;
1747 #ifdef WITH_PINENTRY
1748 gboolean disable_pinentry = FALSE;
1749 #endif
1750 gint opt_index;
1751 const struct option long_opts[] = {
1752 #ifdef WITH_PINENTRY
1753 { "no-pinentry", 0, 0, 'P' },
1754 #endif
1755 { "outfile", 1, 0, 'o' },
1756 { "convert", 1, 0, 'C' },
1757 { "no-fork", 0, 0, 'n' },
1758 { "disable-dump", 0, 0, 'D' },
1759 { "import", 1, 0, 'I' },
1760 { "iterations", 1, 0, 'i' },
1761 { "key-file", 1, 0, 'k' },
1762 { "rcfile", 1, 0, 'f' },
1763 { "version", 0, &show_version, 1 },
1764 { "help", 0, &show_help, 1 },
1765 { 0, 0, 0, 0}
1767 #ifdef WITH_PINENTRY
1768 const gchar *optstring = "Po:C:nDI:i:k:f:";
1769 #else
1770 const gchar *optstring = "o:C:nDI:i:k:f:";
1771 #endif
1772 #ifndef DEBUG
1773 #ifdef HAVE_SETRLIMIT
1774 struct rlimit rl;
1776 rl.rlim_cur = rl.rlim_max = 0;
1778 if (setrlimit(RLIMIT_CORE, &rl) != 0)
1779 err(EXIT_FAILURE, "setrlimit()");
1780 #endif
1781 #endif
1783 #ifdef ENABLE_NLS
1784 setlocale(LC_ALL, "");
1785 bindtextdomain("pwmd", LOCALEDIR);
1786 textdomain("pwmd");
1787 #endif
1789 #ifndef MEM_DEBUG
1790 xmem_init();
1791 #endif
1792 setup_gcrypt();
1793 gpg_err_init();
1794 assuan_set_gpg_err_source(GPG_ERR_SOURCE_DEFAULT);
1795 g_mem_set_vtable(&mtable);
1796 struct assuan_malloc_hooks mhooks = {
1797 xmalloc, xrealloc, xfree
1799 assuan_set_system_hooks(ASSUAN_SYSTEM_PTH);
1800 assuan_set_malloc_hooks(&mhooks);
1801 xmlMemSetup(xfree, xmalloc, xrealloc, xstrdup);
1802 xmlInitMemory();
1803 xmlInitGlobals();
1804 xmlInitParser();
1805 xmlXPathInit();
1806 g_snprintf(buf, sizeof(buf), "%s/.pwmd", g_get_home_dir());
1808 if (mkdir(buf, 0700) == -1 && errno != EEXIST)
1809 err(EXIT_FAILURE, "%s", buf);
1811 g_snprintf(buf, sizeof(buf), "%s/.pwmd/data", g_get_home_dir());
1813 if (mkdir(buf, 0700) == -1 && errno != EEXIST)
1814 err(EXIT_FAILURE, "%s", buf);
1816 cmdline = TRUE;
1818 while ((opt = getopt_long(argc, argv, optstring, long_opts, &opt_index)) != -1) {
1819 switch (opt) {
1820 case 0:
1821 if (show_help)
1822 usage(argv[0], EXIT_SUCCESS);
1824 if (show_version) {
1825 printf(N_("%s\nCopyright (C) 2010 %s\nReleased under the terms of the GPL v2. Use at your own risk.\n\nCompile time features:\n%s"), PACKAGE_STRING,
1826 PACKAGE_BUGREPORT,
1827 #ifdef WITH_PINENTRY
1828 "+WITH_PINENTRY\n"
1829 #else
1830 "-WITH_PINENTRY\n"
1831 #endif
1832 #ifdef WITH_QUALITY
1833 "+WITH_QUALITY\n"
1834 #else
1835 "-WITH_QUALITY\n"
1836 #endif
1837 #ifdef WITH_LIBACL
1838 "+WITH_LIBACL\n"
1839 #else
1840 "-WITH_LIBACL\n"
1841 #endif
1842 #ifdef DEBUG
1843 "+DEBUG\n"
1844 #else
1845 "-DEBUG\n"
1846 #endif
1847 #ifdef MEM_DEBUG
1848 "+MEM_DEBUG\n"
1849 #else
1850 "-MEM_DEBUG\n"
1851 #endif
1853 exit(EXIT_SUCCESS);
1855 break;
1856 #ifdef WITH_PINENTRY
1857 case 'P':
1858 disable_pinentry = TRUE;
1859 break;
1860 #endif
1861 case 'o':
1862 outfile = optarg;
1863 break;
1864 case 'C':
1865 convert = optarg;
1866 break;
1867 case 'n':
1868 background = 0;
1869 break;
1870 case 'D':
1871 secure = TRUE;
1872 break;
1873 case 'I':
1874 import = optarg;
1875 break;
1876 case 'i':
1877 cmd_iterations = strtoul(optarg, NULL, 10);
1879 if (cmd_iterations == G_MAXULONG) {
1880 log_write("%s", N_("invalid iteration count"));
1881 usage(argv[0], EXIT_FAILURE);
1884 iterations_arg = TRUE;
1885 break;
1886 case 'k':
1887 keyfile = optarg;
1888 break;
1889 case 'f':
1890 rcfile = g_strdup(optarg);
1891 rcfile_spec = TRUE;
1892 break;
1893 default:
1894 usage(argv[0], EXIT_FAILURE);
1898 pth_mutex_init(&cn_mutex);
1899 pth_mutex_init(&cache_mutex);
1900 pth_mutex_init(&rcfile_mutex);
1901 #ifdef WITH_PINENTRY
1902 pth_mutex_init(&pin_mutex);
1903 #endif
1905 if (!rcfile)
1906 rcfile = g_strdup_printf("%s/.pwmd/config", g_get_home_dir());
1908 if ((keyfileh = parse_rcfile(rcfile_spec)) == NULL)
1909 exit(EXIT_FAILURE);
1911 #ifdef WITH_PINENTRY
1912 if (disable_pinentry == TRUE)
1913 g_key_file_set_boolean(keyfileh, "global", "enable_pinentry", FALSE);
1914 #endif
1916 if (g_key_file_has_key(keyfileh, "global", "syslog", NULL) == TRUE)
1917 log_syslog = g_key_file_get_boolean(keyfileh, "global", "syslog", NULL);
1919 if (log_syslog == TRUE)
1920 openlog("pwmd", LOG_NDELAY|LOG_PID, LOG_DAEMON);
1922 if (g_key_file_has_key(keyfileh, "global", "priority", NULL)) {
1923 x = g_key_file_get_integer(keyfileh, "global", "priority", NULL);
1924 errno = 0;
1926 if (setpriority(PRIO_PROCESS, 0, x) == -1) {
1927 log_write("setpriority(): %s", strerror(errno));
1928 goto do_exit;
1932 #ifdef HAVE_MLOCKALL
1933 if (disable_mlock == FALSE && mlockall(MCL_FUTURE) == -1) {
1934 log_write("mlockall(): %s", strerror(errno));
1935 goto do_exit;
1937 #endif
1939 if (convert) {
1940 if (!outfile)
1941 usage(argv[0], EXIT_FAILURE);
1943 opt = convert_file(convert, keyfile, outfile);
1944 g_key_file_free(keyfileh);
1945 g_free(rcfile);
1946 exit(opt ? EXIT_FAILURE : EXIT_SUCCESS);
1949 if (import) {
1950 if (!outfile)
1951 usage(argv[0], EXIT_FAILURE);
1953 if (!iterations_arg)
1954 cmd_iterations = (guint64)get_key_file_double("global", "iterations");
1956 opt = xml_import(import, outfile, keyfile, cmd_iterations);
1957 g_key_file_free(keyfileh);
1958 g_free(rcfile);
1959 exit(opt == FALSE ? EXIT_FAILURE : EXIT_SUCCESS);
1962 if ((p = g_key_file_get_string(keyfileh, "global", "socket_path", NULL)) == NULL)
1963 errx(EXIT_FAILURE, N_("%s: socket_path not defined"), rcfile);
1965 socketarg = expand_homedir(p);
1966 g_free(p);
1968 if ((p = g_key_file_get_string(keyfileh, "global", "data_directory", NULL)) == NULL)
1969 errx(EXIT_FAILURE, N_("%s: data_directory not defined"), rcfile);
1971 datadir = expand_homedir(p);
1972 g_free(p);
1974 if (secure == FALSE && g_key_file_has_key(keyfileh, "global", "disable_list_and_dump", NULL) == TRUE) {
1975 n = g_key_file_get_boolean(keyfileh, "global", "disable_list_and_dump", NULL);
1976 disable_list_and_dump = n;
1978 else
1979 disable_list_and_dump = secure;
1981 if (g_key_file_has_key(keyfileh, "global", "cache_timeout", NULL) == TRUE)
1982 default_timeout = g_key_file_get_integer(keyfileh, "global", "cache_timeout", NULL);
1983 else
1984 default_timeout = -1;
1986 setup_logging(keyfileh);
1988 if (g_key_file_has_key(keyfileh, "global", "cache_push", NULL) == TRUE)
1989 cache_push = g_key_file_get_string_list(keyfileh, "global", "cache_push", NULL, NULL);
1991 if (argc != optind) {
1992 for (; optind < argc; optind++) {
1993 if (strv_printf(&cache_push, "%s", argv[optind]) == FALSE)
1994 errx(EXIT_FAILURE, "%s", strerror(ENOMEM));
1998 if (strchr(socketarg, '/') == NULL) {
1999 socketdir = g_get_current_dir();
2000 socketname = g_strdup(socketarg);
2001 socketpath = g_strdup_printf("%s/%s", socketdir, socketname);
2003 else {
2004 socketname = g_strdup(strrchr(socketarg, '/'));
2005 socketname++;
2006 socketarg[strlen(socketarg) - strlen(socketname) -1] = 0;
2007 socketdir = g_strdup(socketarg);
2008 socketpath = g_strdup_printf("%s/%s", socketdir, socketname);
2011 if (chdir(datadir)) {
2012 log_write("%s: %s", datadir, strerror(errno));
2013 unlink(socketpath);
2014 goto do_exit;
2017 if (parse_rcfile_keys() == FALSE)
2018 goto do_exit;
2020 clear_rcfile_keys();
2023 * Set the cache entry for a file. Prompts for the password.
2025 if (cache_push) {
2026 for (opt = 0; cache_push[opt]; opt++)
2027 do_cache_push(cache_push[opt], NULL);
2029 g_strfreev(cache_push);
2030 log_write(background ? N_("Done. Daemonizing...") : N_("Done. Waiting for connections..."));
2034 * bind() doesn't like the full pathname of the socket or any non alphanum
2035 * characters so change to the directory where the socket is wanted then
2036 * create it then change to datadir.
2038 if (chdir(socketdir)) {
2039 log_write("%s: %s", socketdir, strerror(errno));
2040 goto do_exit;
2043 g_free(socketdir);
2045 if ((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
2046 log_write("socket(): %s", strerror(errno));
2047 goto do_exit;
2050 addr.sun_family = AF_UNIX;
2051 g_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socketname);
2053 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
2054 log_write("bind(): %s", strerror(errno));
2056 if (errno == EADDRINUSE)
2057 log_write(N_("Either there is another pwmd running or '%s' is a \n"
2058 "stale socket. Please remove it manually."), socketpath);
2060 do_unlink = 0;
2061 goto do_exit;
2064 if (g_key_file_has_key(keyfileh, "global", "socket_perms", NULL) == TRUE) {
2065 gchar *t = g_key_file_get_string(keyfileh, "global", "socket_perms", NULL);
2066 mode_t mode = strtol(t, NULL, 8);
2067 mode_t mask = umask(0);
2069 g_free(t);
2071 if (chmod(socketname, mode) == -1) {
2072 log_write("%s: %s", socketname, strerror(errno));
2073 close(sockfd);
2074 unlink(socketpath);
2075 umask(mask);
2076 goto do_exit;
2079 umask(mask);
2082 g_free(--socketname);
2084 if (chdir(datadir)) {
2085 log_write("%s: %s", datadir, strerror(errno));
2086 close(sockfd);
2087 unlink(socketpath);
2088 goto do_exit;
2091 g_free(datadir);
2093 if (listen(sockfd, 0) == -1) {
2094 log_write("listen(): %s", strerror(errno));
2095 goto do_exit;
2098 cmdline = FALSE;
2099 unsetenv("DISPLAY");
2100 unsetenv("TERM");
2102 if (background) {
2103 switch (fork()) {
2104 case -1:
2105 log_write("fork(): %s", strerror(errno));
2106 goto do_exit;
2107 case 0:
2108 close(0);
2109 close(1);
2110 close(2);
2111 setsid();
2112 break;
2113 default:
2114 exit(EXIT_SUCCESS);
2118 server_loop(sockfd, &socketpath);
2119 estatus = EXIT_SUCCESS;
2121 do_exit:
2122 if (socketpath && do_unlink) {
2123 unlink(socketpath);
2124 g_free(socketpath);
2127 g_key_file_free(keyfileh);
2128 g_free(rcfile);
2129 xmlCleanupParser();
2130 xmlCleanupGlobals();
2132 if (estatus == EXIT_SUCCESS)
2133 log_write(N_("pwmd exiting normally"));
2135 #if defined(DEBUG) && !defined(MEM_DEBUG)
2136 xdump();
2137 #endif
2138 exit(estatus);