Consider INQUIRE_MAXLEN when exporting and cache pushing.
[pwmd.git] / src / pwmd.c
blob52b7144827a40bc6084dc94cb1ded3f2f3fc0c92
1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
2 /*
3 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
4 Ben Kibbey <bjk@luxsci.net>
6 This file is part of pwmd.
8 Pwmd is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
13 Pwmd is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
21 #ifdef HAVE_CONFIG_H
22 #include <config.h>
23 #endif
25 #include <stdio.h>
26 #include <stdlib.h>
27 #include <unistd.h>
28 #include <err.h>
29 #include <ctype.h>
30 #include <string.h>
31 #include <sys/un.h>
32 #include <signal.h>
33 #include <stdarg.h>
34 #include <string.h>
35 #include <sys/wait.h>
36 #include <fcntl.h>
37 #include <pwd.h>
38 #include <grp.h>
39 #include <pthread.h>
40 #include <glib.h>
41 #include <glib/gprintf.h>
42 #include <sys/mman.h>
43 #include <termios.h>
44 #include <assert.h>
45 #include <syslog.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>
51 #include <setjmp.h>
53 #ifdef TM_IN_SYS_TIME
54 #include <sys/time.h>
55 #else
56 #include <time.h>
57 #endif
59 #ifdef HAVE_PR_SET_NAME
60 #include <sys/prctl.h>
61 #endif
63 #include "pwmd-error.h"
64 #include <gcrypt.h>
66 #include "mem.h"
67 #include "xml.h"
68 #include "common.h"
69 #include "commands.h"
70 #include "cache.h"
71 #include "misc.h"
72 #include "mutex.h"
73 #include "rcfile.h"
74 #include "agent.h"
75 #include "convert.h"
77 static gboolean quit;
78 static jmp_buf jmp;
79 static gboolean nofork;
80 static pthread_cond_t quit_cond;
81 static pthread_mutex_t quit_mutex;
82 static gboolean no_passphrase_file = FALSE;
84 gboolean do_cache_push(const gchar *filename, struct crypto_s *crypto);
85 static gboolean signal_loop(sigset_t sigset);
87 GCRY_THREAD_OPTION_PTHREAD_IMPL;
89 static void cache_push_from_rcfile()
91 struct crypto_s *crypto;
92 gpg_error_t rc = init_client_crypto(&crypto);
94 if (rc) {
95 log_write("%s: %s", __FUNCTION__, pwmd_strerror(rc));
96 return;
99 rc = set_agent_option(crypto->agent, "pinentry-mode", "error");
100 if (rc) {
101 log_write("%s: %s", __FUNCTION__, pwmd_strerror(rc));
102 return;
105 if (g_key_file_has_key(keyfileh, "global", "cache_push", NULL)) {
106 gchar **cache_push = g_key_file_get_string_list(keyfileh, "global",
107 "cache_push", NULL, NULL);
108 gchar **p;
110 for (p = cache_push; *p; p++) {
111 (void)do_cache_push(*p, crypto);
112 cleanup_crypto_stage1(crypto);
115 g_strfreev(cache_push);
118 (void)kill_scd(crypto->agent);
119 cleanup_crypto(&crypto);
122 static void *reload_rcfile_thread(void *arg)
124 #ifdef HAVE_PR_SET_NAME
125 prctl(PR_SET_NAME, "reload rcfile");
126 #endif
127 pthread_setspecific(thread_name_key, g_strdup(__FUNCTION__));
128 MUTEX_LOCK(&rcfile_mutex);
129 pthread_cleanup_push(cleanup_mutex_cb, &rcfile_mutex);
131 for (;;) {
132 gboolean b = disable_list_and_dump;
133 gchar **users;
134 GKeyFile *k;
136 pthread_cond_wait(&rcfile_cond, &rcfile_mutex);
137 users = g_key_file_get_string_list(keyfileh, "global", "allowed", NULL, NULL);
138 log_write(_("reloading configuration file '%s'"), rcfile);
139 k = parse_rcfile(FALSE, cmdline);
140 if (k) {
141 g_key_file_free(keyfileh);
142 keyfileh = k;
143 cache_push_from_rcfile();
144 clear_rcfile_keys();
147 disable_list_and_dump = !disable_list_and_dump ? b : TRUE;
148 g_key_file_set_string_list(keyfileh, "global", "allowed",
149 (const gchar **)users, g_strv_length(users));
150 g_strfreev(users);
153 pthread_cleanup_pop(1);
154 return NULL;
157 gpg_error_t send_error(assuan_context_t ctx, gpg_error_t e)
159 struct client_s *client = assuan_get_pointer(ctx);
161 if (gpg_err_source(e) == GPG_ERR_SOURCE_UNKNOWN)
162 e = gpg_error(e);
164 if (client)
165 client->last_rc = e;
167 if (!e)
168 return assuan_process_done(ctx, 0);
170 if (!ctx) {
171 log_write("%s", pwmd_strerror(e));
172 return e;
175 if (gpg_err_code(e) == GPG_ERR_BAD_DATA) {
176 xmlErrorPtr xe = client->xml_error;
178 if (!xe)
179 xe = xmlGetLastError();
180 if (xe) {
181 log_write("%s", xe->message);
182 if (client->last_error)
183 g_free(client->last_error);
185 client->last_error = g_strdup(xe->message);
188 e = assuan_process_done(ctx, assuan_set_error(ctx, e,
189 xe ? xe->message : NULL));
191 if (xe == client->xml_error)
192 xmlResetError(xe);
193 else
194 xmlResetLastError();
196 client->xml_error = NULL;
197 return e;
200 return assuan_process_done(ctx, assuan_set_error(ctx, e, pwmd_strerror(e)));
203 int assuan_log_cb(assuan_context_t ctx, void *data, unsigned cat,
204 const char *msg)
206 static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
207 int i, t;
208 gboolean match = FALSE;
210 pthread_mutex_lock(&m);
211 pthread_cleanup_push((void (*)(void *))pthread_mutex_unlock, &m);
212 t = g_strv_length(debug_level);
214 for (i = 0; i < t; i++) {
215 if (!g_ascii_strcasecmp(debug_level[i], (gchar *)"init")
216 && cat == ASSUAN_LOG_INIT) {
217 match = TRUE;
218 break;
221 if (!g_ascii_strcasecmp(debug_level[i], (gchar *)"ctx")
222 && cat == ASSUAN_LOG_CTX) {
223 match = TRUE;
224 break;
227 if (!g_ascii_strcasecmp(debug_level[i], (gchar *)"engine")
228 && cat == ASSUAN_LOG_ENGINE) {
229 match = TRUE;
230 break;
233 if (!g_ascii_strcasecmp(debug_level[i], (gchar *)"data")
234 && cat == ASSUAN_LOG_DATA) {
235 match = TRUE;
236 break;
239 if (!g_ascii_strcasecmp(debug_level[i], (gchar *)"sysio")
240 && cat == ASSUAN_LOG_SYSIO) {
241 match = TRUE;
242 break;
245 if (!g_ascii_strcasecmp(debug_level[i], (gchar *)"control")
246 && cat == ASSUAN_LOG_CONTROL) {
247 match = TRUE;
248 break;
252 if (match && msg) {
253 if (logfile) {
254 int fd;
256 if ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600)) == -1)
257 warn("%s", logfile);
258 else {
259 pthread_cleanup_push(cleanup_fd_cb, &fd);
260 write(fd, msg, strlen(msg));
261 pthread_cleanup_pop(1);
265 if (nofork) {
266 fprintf(stderr, "%s%s", data ? (gchar *)data : "", msg);
267 fflush(stderr);
271 pthread_cleanup_pop(1);
272 return match;
275 void log_write(const gchar *fmt, ...)
277 gchar *args, *line;
278 va_list ap;
279 struct tm *tm;
280 time_t now;
281 gchar tbuf[21];
282 gint fd = -1;
283 gchar *name = NULL;
284 gchar buf[255];
285 pthread_t tid = pthread_self();
286 static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
288 if ((!logfile && !isatty(STDERR_FILENO) && !log_syslog) || !fmt)
289 return;
291 pthread_mutex_lock(&m);
292 pthread_cleanup_push((void (*)(void *))pthread_mutex_unlock, &m);
293 pthread_cleanup_push(cleanup_fd_cb, &fd);
295 if (!cmdline && logfile) {
296 if ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600)) == -1)
297 warn("%s", logfile);
300 va_start(ap, fmt);
302 if (g_vasprintf(&args, fmt, ap) != -1) {
303 if (cmdline) {
304 pthread_cleanup_push(g_free, args);
305 fprintf(stderr, "%s\n", args);
306 fflush(stderr);
307 pthread_cleanup_pop(1);
309 else {
310 pthread_cleanup_push(g_free, args);
311 name = pthread_getspecific(thread_name_key);
312 name = print_fmt(buf, sizeof(buf), "%s(%p): ",
313 name ? name : _("unknown"), (pthread_t *)tid);
315 if (!cmdline && log_syslog && !nofork)
316 syslog(LOG_INFO, "%s%s", name, args);
318 time(&now);
319 tm = localtime(&now);
320 strftime(tbuf, sizeof(tbuf), "%b %d %Y %H:%M:%S ", tm);
321 tbuf[sizeof(tbuf) - 1] = 0;
323 if (args[strlen(args)-1] == '\n')
324 args[strlen(args)-1] = 0;
326 line = g_strdup_printf("%s %i %s%s\n", tbuf, getpid(), name,
327 args);
328 pthread_cleanup_pop(1);
329 if (line) {
330 pthread_cleanup_push(g_free, line);
331 if (logfile && fd != -1) {
332 write(fd, line, strlen(line));
333 fsync(fd);
336 if (nofork) {
337 fprintf(stdout, "%s", line);
338 fflush(stdout);
341 pthread_cleanup_pop(1);
346 va_end(ap);
347 pthread_cleanup_pop(1);
348 pthread_cleanup_pop(0);
349 pthread_mutex_unlock(&m);
352 static gpg_error_t setup_crypto()
354 gpg_error_t rc;
356 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
358 if (!gcry_check_version(NULL))
359 errx(EXIT_FAILURE, _("gcry_check_version(): Incompatible libgcrypt. Wanted %s, got %s."), GCRYPT_VERSION, gcry_check_version(NULL));
361 gcry_set_allocation_handler(g_malloc, g_malloc, NULL, g_realloc, g_free);
362 return rc;
365 static gpg_error_t validate_peer(struct client_s *cl)
367 gchar **users;
368 gboolean allowed = FALSE;
369 assuan_peercred_t peercred;
370 gpg_error_t rc = assuan_get_peercred(cl->ctx, &peercred);
372 if (rc)
373 return rc;
375 users = g_key_file_get_string_list(keyfileh, "global", "allowed", NULL, NULL);
377 if (users) {
378 for (gchar **p = users; *p; p++) {
379 struct passwd pw, *result;
380 struct group gr, *gresult;
381 char *buf;
383 if (*(*p) == '@') {
384 size_t len = sysconf(_SC_GETGR_R_SIZE_MAX);
386 if (len == -1)
387 len = 16384;
389 buf = g_malloc(len);
391 if (!buf) {
392 g_strfreev(users);
393 return GPG_ERR_ENOMEM;
396 if (!getgrnam_r(*(p)+1, &gr, buf, len, &gresult) && gresult) {
397 if (gresult->gr_gid == peercred->gid) {
398 g_free(buf);
399 allowed = TRUE;
400 break;
403 len = sysconf(_SC_GETPW_R_SIZE_MAX);
405 if (len == -1)
406 len = 16384;
408 gchar *tbuf = g_malloc(len);
410 for (gchar **t = gresult->gr_mem; *t; t++) {
411 if (!getpwnam_r(*t, &pw, tbuf, len, &result) && result) {
412 if (result->pw_uid == peercred->uid) {
413 g_free(buf);
414 allowed = TRUE;
415 break;
420 g_free(tbuf);
422 if (allowed)
423 break;
426 else {
427 size_t len = sysconf(_SC_GETPW_R_SIZE_MAX);
429 if (len == -1)
430 len = 16384;
432 buf = g_malloc(len);
434 if (!buf) {
435 g_strfreev(users);
436 return GPG_ERR_ENOMEM;
439 if (!getpwnam_r(*p, &pw, buf, len, &result) && result) {
440 if (result->pw_uid == peercred->uid) {
441 g_free(buf);
442 allowed = TRUE;
443 break;
448 g_free(buf);
451 g_strfreev(users);
454 log_write("peer %s: uid=%i, gid=%i, pid=%i",
455 allowed ? _("accepted") : _("rejected"), peercred->uid,
456 peercred->gid, peercred->pid);
457 return allowed ? 0 : GPG_ERR_INV_USER_ID;
460 static void xml_error_cb(void *data, xmlErrorPtr e)
462 struct client_s *client = data;
465 * Keep the first reported error as the one to show in the error
466 * description. Reset in send_error().
468 if (client->xml_error)
469 return;
471 xmlCopyError(e, client->xml_error);
474 static gboolean new_connection(struct client_s *cl)
476 gpg_error_t rc;
477 static struct assuan_malloc_hooks mhooks = { g_malloc, g_realloc, g_free };
479 cl->thd->status_msg_pipe[0] = -1;
480 cl->thd->status_msg_pipe[1] = -1;
481 rc = assuan_new_ext(&cl->ctx, GPG_ERR_SOURCE_DEFAULT, &mhooks,
482 debug_level ? assuan_log_cb : NULL, NULL);
483 if (rc)
484 goto fail;
486 rc = assuan_init_socket_server(cl->ctx, cl->thd->fd, 2);
487 if (rc)
488 goto fail;
490 assuan_set_pointer(cl->ctx, cl);
491 assuan_set_hello_line(cl->ctx, PACKAGE_STRING);
492 rc = register_commands(cl->ctx);
493 if (rc)
494 goto fail;
496 rc = assuan_accept(cl->ctx);
497 if (rc)
498 goto fail;
500 rc = validate_peer(cl);
501 /* May not be implemented on all platforms. */
502 if (rc && gpg_err_code(rc) != GPG_ERR_ASS_GENERAL)
503 goto fail;
505 rc = init_client_crypto(&cl->crypto);
506 if (rc)
507 goto fail;
509 if (pipe(cl->thd->status_msg_pipe) == -1) {
510 cl->thd->status_msg_pipe[0] = -1;
511 cl->thd->status_msg_pipe[1] = -1;
512 rc = gpg_error_from_syserror();
513 goto fail;
516 cl->crypto->agent->client_ctx = cl->ctx;
517 fcntl(cl->thd->status_msg_pipe[0], F_SETFL, O_NONBLOCK);
518 fcntl(cl->thd->status_msg_pipe[1], F_SETFL, O_NONBLOCK);
519 pthread_mutex_init(&cl->thd->status_mutex, NULL);
520 cl->crypto->client_ctx = cl->ctx;
521 xmlSetStructuredErrorFunc(cl, xml_error_cb);
522 return TRUE;
524 fail:
525 log_write("%s", pwmd_strerror(rc));
526 return FALSE;
530 * This is called after a client_thread() terminates. Set with
531 * pthread_cleanup_push().
533 static void cleanup_cb(void *arg)
535 struct client_thread_s *cn = arg;
536 struct client_s *cl = cn->cl;
537 struct status_msg_s *msg;
539 MUTEX_LOCK(&cn_mutex);
540 cn_thread_list = g_slist_remove(cn_thread_list, cn);
541 MUTEX_UNLOCK(&cn_mutex);
543 if (cl) {
544 cleanup_client(cl);
546 if (cl->ctx)
547 assuan_release(cl->ctx);
548 else if (cl->thd && cl->thd->fd != -1)
549 close(cl->thd->fd);
551 if (cl->crypto)
552 cleanup_crypto(&cl->crypto);
554 g_free(cl);
556 else {
557 if (cn->fd != -1)
558 close(cn->fd);
561 for (msg = cn->msg_queue; msg; msg = msg->next) {
562 g_free(msg->line);
563 g_free(msg);
566 if (cn->status_msg_pipe[0] != -1)
567 close(cn->status_msg_pipe[0]);
569 if (cn->status_msg_pipe[1] != -1)
570 close(cn->status_msg_pipe[1]);
572 pthread_mutex_destroy(&cn->status_mutex);
573 log_write(_("exiting, fd=%i"), cn->fd);
574 g_free(cn);
575 send_status_all(STATUS_CLIENTS, NULL);
576 pthread_cond_signal(&quit_cond);
579 gpg_error_t send_msg_queue(struct client_thread_s *thd)
581 MUTEX_LOCK(&thd->status_mutex);
582 gpg_error_t rc = 0;
583 gchar c;
585 read(thd->status_msg_pipe[0], &c, 1);
587 while (thd->msg_queue) {
588 struct status_msg_s *msg = thd->msg_queue;
590 MUTEX_UNLOCK(&thd->status_mutex);
591 rc = send_status(thd->cl->ctx, msg->s, msg->line);
592 MUTEX_LOCK(&thd->status_mutex);
593 g_free(msg->line);
594 thd->msg_queue = thd->msg_queue->next;
595 g_free(msg);
597 if (rc)
598 break;
601 MUTEX_UNLOCK(&thd->status_mutex);
602 return rc;
605 static void *client_thread(void *data)
607 struct client_thread_s *thd = data;
608 struct client_s *cl = g_malloc0(sizeof(struct client_s));
610 #ifdef HAVE_PR_SET_NAME
611 prctl(PR_SET_NAME, "client");
612 #endif
613 pthread_setspecific(thread_name_key, g_strdup(__FUNCTION__));
615 if (!cl) {
616 log_write("%s(%i): %s", __FILE__, __LINE__,
617 pwmd_strerror(GPG_ERR_ENOMEM));
618 return NULL;
621 pthread_cleanup_push(cleanup_cb, thd);
622 thd->cl = cl;
623 cl->thd = thd;
625 if (new_connection(cl)) {
626 gboolean finished = FALSE;
627 gpg_error_t rc;
629 send_status_all(STATUS_CLIENTS, NULL);
630 rc = send_status(cl->ctx, STATUS_CACHE, NULL);
631 if (rc) {
632 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(rc));
633 finished = TRUE;
636 while (!finished) {
637 fd_set rfds;
638 gint n;
639 gint eof;
641 FD_ZERO(&rfds);
642 FD_SET(thd->fd, &rfds);
643 FD_SET(thd->status_msg_pipe[0], &rfds);
644 n = thd->fd > thd->status_msg_pipe[0] ? thd->fd : thd->status_msg_pipe[0];
646 n = select(n+1, &rfds, NULL, NULL, NULL);
647 if (n == -1) {
648 log_write("%s", strerror(errno));
649 break;
652 if (FD_ISSET(thd->status_msg_pipe[0], &rfds)) {
653 rc = send_msg_queue(thd);
654 if (rc && gpg_err_code(rc) != GPG_ERR_EPIPE) {
655 log_write("%s(%i): %s", __FUNCTION__, __LINE__,
656 pwmd_strerror(rc));
657 break;
661 if (!FD_ISSET(thd->fd, &rfds))
662 continue;
664 rc = assuan_process_next(cl->ctx, &eof);
665 if (rc || eof) {
666 if (gpg_err_code(rc) == GPG_ERR_EOF || eof)
667 break;
669 log_write("assuan_process_next(): %s", pwmd_strerror(rc));
670 rc = send_error(cl->ctx, rc);
672 if (rc) {
673 log_write("assuan_process_done(): %s", pwmd_strerror(rc));
674 break;
678 /* Since the msg queue pipe fd's are non-blocking, check for
679 * pending status msgs here. GPG_ERR_EPIPE can be seen when the
680 * client has already disconnected and will be converted to
681 * GPG_ERR_EOF during assuan_process_next().
683 rc = send_msg_queue(thd);
684 if (rc && gpg_err_code(rc) != GPG_ERR_EPIPE) {
685 log_write("%s(%i): %s", __FUNCTION__, __LINE__,
686 pwmd_strerror(rc));
687 break;
692 pthread_cleanup_pop(1);
693 return NULL;
696 static gboolean xml_import(const gchar *filename, const gchar *outfile,
697 const gchar *keygrip, const char *sign_keygrip, const gchar *keyfile,
698 gboolean no_passphrase, const gchar *cipher, const gchar *params,
699 gulong s2k_count)
701 xmlDocPtr doc;
702 gint fd;
703 struct stat st;
704 gint len;
705 xmlChar *xmlbuf;
706 xmlChar *xml;
707 gpg_error_t rc;
708 struct crypto_s *crypto;
709 gint algo = cipher ? cipher_string_to_gcrypt((gchar *)cipher) :
710 GCRY_CIPHER_AES256;
712 if (algo == -1) {
713 log_write("%s", pwmd_strerror(GPG_ERR_CIPHER_ALGO));
714 return FALSE;
717 if (stat(filename, &st) == -1) {
718 log_write("%s: %s", filename, pwmd_strerror(gpg_error_from_syserror()));
719 return FALSE;
722 rc = init_client_crypto(&crypto);
723 if (rc)
724 return FALSE;
726 memcpy(&crypto->save.hdr, &crypto->hdr, sizeof(file_header_t));
727 crypto->save.hdr.flags = set_cipher_flag(crypto->save.hdr.flags, algo);
728 log_write(_("Importing XML from '%s'. Output will be written to '%s' ..."),
729 filename, outfile);
731 if ((fd = open(filename, O_RDONLY)) == -1) {
732 log_write("%s: %s", filename, pwmd_strerror(gpg_error_from_syserror()));
733 goto fail;
736 if ((xmlbuf = xmalloc(st.st_size+1)) == NULL) {
737 close(fd);
738 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
739 goto fail;
742 if (read(fd, xmlbuf, st.st_size) == -1) {
743 rc = gpg_error_from_syserror();
744 close(fd);
745 log_write("%s: %s", filename, pwmd_strerror(rc));
746 goto fail;
749 close(fd);
750 xmlbuf[st.st_size] = 0;
752 * Make sure the document validates.
754 if ((doc = xmlReadDoc(xmlbuf, NULL, "UTF-8", XML_PARSE_NOBLANKS)) == NULL) {
755 log_write("xmlReadDoc() failed");
756 xfree(xmlbuf);
757 goto fail;
760 xfree(xmlbuf);
761 xmlNodePtr n = xmlDocGetRootElement(doc);
762 if (strcmp((gchar *)n->name, (gchar *)"pwmd")) {
763 log_write(_("Could not find root \"pwmd\" element."));
764 rc = GPG_ERR_BAD_DATA;
767 if (!rc)
768 rc = validate_import(n ? n->children : n);
770 if (rc) {
771 log_write("%s", pwmd_strerror(rc));
772 xmlFreeDoc(doc);
773 goto fail;
776 xmlDocDumpMemory(doc, &xml, &len);
777 xmlFreeDoc(doc);
778 crypto->save.s2k_count = (gulong)s2k_count;
779 rc = set_pinentry_options(crypto->agent);
780 if (!rc)
781 rc = export_common(crypto, keygrip, sign_keygrip, no_passphrase, xml,
782 len, outfile, params, keyfile);
784 xmlFree(xml);
785 if (rc) {
786 send_error(NULL, rc);
787 goto fail;
790 cleanup_crypto(&crypto);
791 return TRUE;
793 fail:
794 cleanup_crypto(&crypto);
795 return FALSE;
798 gboolean do_cache_push(const gchar *filename, struct crypto_s *crypto)
800 guchar md5file[16];
801 gpg_error_t rc;
802 gchar *key = NULL;
803 gsize keylen;
804 xmlDocPtr doc;
805 struct cache_data_s *cdata;
807 log_write(_("Trying to add datafile '%s' to the file cache ..."),
808 filename);
810 if (valid_filename(filename) == FALSE) {
811 log_write(_("%s: Invalid characters in filename"), filename);
812 return FALSE;
815 rc = read_data_file(filename, crypto);
816 if (rc) {
817 log_write("%s", pwmd_strerror(rc));
818 return FALSE;
821 if ((key = get_key_file_string(filename, "passphrase"))) {
822 log_write(_("Trying the passphrase specified in config ..."));
823 keylen = strlen(key);
825 else if ((key = get_key_file_string(filename, "passphrase_file"))) {
826 gint fd = open((gchar *)key, O_RDONLY);
827 struct stat st;
829 log_write(_("Trying the passphrase using file '%s' ..."), key);
830 if (fd == -1) {
831 log_write("%s: %s", key, pwmd_strerror(gpg_error_from_syserror()));
832 g_free(key);
833 return FALSE;
836 stat((gchar *)key, &st);
837 g_free(key);
838 key = g_malloc(st.st_size);
839 if (read(fd, key, st.st_size) != st.st_size) {
840 log_write("short read() count");
841 g_free(key);
842 close(fd);
843 return FALSE;
846 keylen = st.st_size;
849 if (key) {
850 rc = set_agent_passphrase(crypto, key, keylen);
851 g_free(key);
852 if (rc) {
853 log_write("%s", pwmd_strerror(rc));
854 return FALSE;
858 crypto->filename = g_strdup(filename);
859 rc = decrypt_data(crypto);
860 if (rc) {
861 log_write("%s", pwmd_strerror(rc));
862 return FALSE;
865 doc = parse_doc((gchar *)crypto->plaintext, crypto->plaintext_len);
866 if (!doc) {
867 log_write("%s", pwmd_strerror(GPG_ERR_ENOMEM));
868 return FALSE;
871 gcry_md_hash_buffer(GCRY_MD_MD5, md5file, filename, strlen(filename));
872 cdata = g_malloc0(sizeof(struct cache_data_s));
873 if (!cdata) {
874 xmlFreeDoc(doc);
875 log_write("%s", pwmd_strerror(GPG_ERR_ENOMEM));
876 return FALSE;
879 cdata->doc = doc;
880 gcry_sexp_build((gcry_sexp_t *)&cdata->pubkey, NULL, "%S", crypto->pkey_sexp);
881 gcry_sexp_build((gcry_sexp_t *)&cdata->sigkey, NULL, "%S", crypto->sigpkey_sexp);
882 cdata->ctime = crypto->st.st_ctime;
883 gint timeout = get_key_file_integer(filename, "cache_timeout");
884 cache_add_file(md5file, crypto->grip, cdata, timeout);
885 log_write(_("Successfully added '%s' to the cache."), filename);
886 return TRUE;
889 static void *accept_thread(void *arg)
891 gint sockfd = *(gint *)arg;
893 #ifdef HAVE_PR_SET_NAME
894 prctl(PR_SET_NAME, "accept");
895 #endif
896 pthread_setspecific(thread_name_key, g_strdup(__FUNCTION__));
898 for (;;) {
899 socklen_t slen = sizeof(struct sockaddr_un);
900 struct sockaddr_un raddr;
901 gint fd;
902 struct client_thread_s *new;
903 gpg_error_t rc;
905 fd = accept(sockfd, (struct sockaddr *)&raddr, &slen);
906 if (fd == -1) {
907 if (errno != EAGAIN) {
908 if (!quit) // probably EBADF
909 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
911 break;
913 continue;
916 new = g_malloc0(sizeof(struct client_thread_s));
917 if (!new) {
918 log_write("%s(%i): %s", __FILE__, __LINE__,
919 pwmd_strerror(GPG_ERR_ENOMEM));
920 close(fd);
921 continue;
924 MUTEX_LOCK(&cn_mutex);
925 pthread_cleanup_push(cleanup_mutex_cb, &cn_mutex);
926 new->fd = fd;
927 rc = create_thread(client_thread, new, &new->tid, TRUE);
928 if (!rc) {
929 cn_thread_list = g_slist_append(cn_thread_list, new);
930 log_write(_("new connection: tid=%p, fd=%i"), (pthread_t *)new->tid, fd);
933 pthread_cleanup_pop(1);
934 if (rc) {
935 g_free(new);
936 close(fd);
937 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
938 pwmd_strerror(rc));
942 /* Just in case accept() failed for some reason other than EBADF */
943 quit = TRUE;
944 return NULL;
947 static void *cache_timer_thread(void *arg)
949 #ifdef HAVE_PR_SET_NAME
950 prctl(PR_SET_NAME, "cache timer");
951 #endif
952 pthread_setspecific(thread_name_key, g_strdup(__FUNCTION__));
954 for (;;) {
955 sleep(1);
956 cache_adjust_timeout();
959 return NULL;
962 static void catch_sigabrt(int sig)
964 cache_clear(NULL);
965 #ifndef MEM_DEBUG
966 xpanic();
967 #endif
970 static gboolean signal_loop(sigset_t sigset)
972 gboolean done = FALSE;
973 gboolean sigint = FALSE;
975 do {
976 gint sig = sigwaitinfo(&sigset, NULL);
978 if (sig == -1) {
979 if (errno != EAGAIN)
980 log_write("sigwaitinfo(): %s", strerror(errno));
981 continue;
984 if (sig != SIGUSR2)
985 log_write(_("caught signal %i (%s)"), sig, strsignal(sig));
987 switch (sig) {
988 case SIGHUP:
989 pthread_cond_signal(&rcfile_cond);
990 break;
991 case SIGABRT:
992 // not really handled here.
993 catch_sigabrt(SIGABRT);
994 break;
995 case SIGUSR1:
996 log_write(_("clearing file cache"));
997 cache_clear(NULL);
998 send_status_all(STATUS_CACHE, NULL);
999 break;
1000 case SIGUSR2:
1001 done = TRUE;
1002 break;
1003 default:
1004 sigint = TRUE;
1005 done = TRUE;
1006 break;
1008 } while (!done);
1010 return sigint;
1013 static void catchsig(int sig)
1015 log_write("Caught SIGSEGV. Exiting.");
1016 #ifdef HAVE_BACKTRACE
1017 BACKTRACE(__FUNCTION__);
1018 #endif
1019 longjmp(jmp, 1);
1022 static void *waiting_for_exit(void *arg)
1024 #ifdef HAVE_PR_SET_NAME
1025 prctl(PR_SET_NAME, "exiting");
1026 #endif
1027 pthread_setspecific(thread_name_key, g_strdup(__FUNCTION__));
1028 log_write(_("waiting for all clients to disconnect"));
1029 MUTEX_LOCK(&quit_mutex);
1030 pthread_cleanup_push(cleanup_mutex_cb, &quit_mutex);
1032 for (;;) {
1033 MUTEX_LOCK(&cn_mutex);
1034 gint n = g_slist_length(cn_thread_list);
1035 MUTEX_UNLOCK(&cn_mutex);
1036 if (!n)
1037 break;
1039 log_write(_("%i clients remain"), n);
1040 pthread_cond_wait(&quit_cond, &quit_mutex);
1043 pthread_cleanup_pop(1);
1044 kill(getpid(), SIGUSR2);
1045 return NULL;
1048 static gboolean server_loop(gint sockfd, gchar **socketpath)
1050 pthread_t accept_tid;
1051 pthread_t cache_timeout_tid;
1052 gint n;
1053 sigset_t sigset;
1054 gboolean segv = FALSE;
1055 gpg_error_t rc;
1057 init_commands();
1058 sigemptyset(&sigset);
1060 /* Termination */
1061 sigaddset(&sigset, SIGTERM);
1062 sigaddset(&sigset, SIGINT);
1064 /* Clears the file cache. */
1065 sigaddset(&sigset, SIGUSR1);
1067 /* Configuration file reloading. */
1068 sigaddset(&sigset, SIGHUP);
1070 /* For exiting cleanly. */
1071 sigaddset(&sigset, SIGUSR2);
1073 /* Clears the cache and exits when something bad happens. */
1074 signal(SIGABRT, catch_sigabrt);
1075 sigaddset(&sigset, SIGABRT);
1076 sigprocmask(SIG_BLOCK, &sigset, NULL);
1078 /* Ignored everywhere. When a client disconnects abnormally this signal
1079 * gets raised. It isn't needed though because client_thread() will check
1080 * for rcs even after the client disconnects. */
1081 signal(SIGPIPE, SIG_IGN);
1083 /* Can show a backtrace of the stack in the log. */
1084 signal(SIGSEGV, catchsig);
1086 pthread_mutex_init(&quit_mutex, NULL);
1087 pthread_cond_init(&quit_cond, NULL);
1088 log_write(_("%s started for user %s"), PACKAGE_STRING, g_get_user_name());
1089 log_write(_("Listening on %s"), *socketpath);
1090 #ifndef HAVE_SO_PEERCRED
1091 log_write(_("Peer credential checking is NOT supported on this OS."));
1092 #endif
1094 rc = create_thread(reload_rcfile_thread, NULL, &rcfile_tid, TRUE);
1095 if (rc) {
1096 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1097 pwmd_strerror(rc));
1098 goto done;
1101 rc = create_thread(cache_timer_thread, NULL, &cache_timeout_tid, TRUE);
1102 if (rc) {
1103 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1104 pwmd_strerror(rc));
1105 goto done;
1108 rc = create_thread(accept_thread, &sockfd, &accept_tid, TRUE);
1109 if (rc) {
1110 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1111 pwmd_strerror(rc));
1112 goto done;
1115 sigdelset(&sigset, SIGUSR2);
1116 if (!setjmp(jmp))
1117 signal_loop(sigset);
1118 else
1119 segv = TRUE;
1121 done:
1123 * We're out of the main server loop. This happens when a signal was sent
1124 * to terminate the daemon. We'll wait for all clients to disconnect
1125 * before exiting but exit immediately if another termination signal is
1126 * sent.
1128 pthread_cancel(accept_tid);
1129 shutdown(sockfd, SHUT_RDWR);
1130 close(sockfd);
1131 unlink(*socketpath);
1132 g_free(*socketpath);
1133 *socketpath = NULL;
1134 MUTEX_LOCK(&cn_mutex);
1135 n = g_slist_length(cn_thread_list);
1136 MUTEX_UNLOCK(&cn_mutex);
1138 if (n && !segv) {
1139 pthread_t tid;
1141 rc = create_thread(waiting_for_exit, NULL, &tid, TRUE);
1142 if (!rc) {
1143 sigaddset(&sigset, SIGUSR2);
1144 if (signal_loop(sigset)) {
1145 log_write(_("Received second termination request. Exiting."));
1146 pthread_cancel(tid);
1149 else
1150 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1151 pwmd_strerror(rc));
1154 pthread_cancel(cache_timeout_tid);
1155 cache_deinit();
1156 deinit_commands();
1157 pthread_cancel(rcfile_tid);
1158 pthread_cond_destroy(&rcfile_cond);
1159 pthread_mutex_destroy(&rcfile_mutex);
1160 pthread_cond_destroy(&quit_cond);
1161 pthread_mutex_destroy(&quit_mutex);
1162 return segv ? EXIT_FAILURE : EXIT_SUCCESS;;
1165 static void startup_failure()
1167 log_write(_("Failed to add a file to the cache. Use --ignore to force startup. Exiting."));
1168 cache_clear(NULL);
1171 /* This is called from cache.c:clear_once(). See
1172 * command.c:clearcache_command() for details about lock checking.
1174 static gpg_error_t free_cache_data(file_cache_t *cache)
1176 gpg_error_t rc = GPG_ERR_NO_DATA;
1177 gint i, t;
1178 struct client_thread_s *found = NULL;
1179 gboolean self = FALSE;
1181 if (!cache->data)
1182 return 0;
1184 MUTEX_LOCK(&cn_mutex);
1185 pthread_cleanup_push(cleanup_mutex_cb, &cn_mutex);
1186 t = g_slist_length(cn_thread_list);
1188 for (i = 0; i < t; i++) {
1189 struct client_thread_s *thd = g_slist_nth_data(cn_thread_list, i);
1191 if (!memcmp(thd->cl->md5file, cache->filename,
1192 sizeof(cache->filename))) {
1193 if (pthread_equal(pthread_self(), thd->tid)) {
1194 found = thd;
1195 self = TRUE;
1196 continue;
1199 /* Continue trying to find a client who has the same file open and
1200 * also has a lock. */
1201 rc = cache_lock_mutex(thd->cl->ctx, thd->cl->md5file, TRUE,
1202 FALSE, -1);
1203 if (!rc) {
1204 self = FALSE;
1205 found = thd;
1206 break;
1211 if (!rc && self)
1212 rc = cache_lock_mutex(found->cl->ctx, found->cl->md5file, TRUE,
1213 FALSE, -1);
1215 if (!rc || rc == GPG_ERR_NO_DATA) {
1216 if (cache->data) {
1217 if (cache->data->doc)
1218 xmlFreeDoc(cache->data->doc);
1219 if (cache->data->pubkey)
1220 gcry_sexp_release(cache->data->pubkey);
1221 g_free(cache->data);
1222 cache->data = NULL;
1225 if (found)
1226 cache_unlock_mutex(found->cl->md5file, FALSE);
1228 rc = 0;
1231 pthread_cleanup_pop(1);
1232 return rc;
1235 static gboolean convert_v2_datafile(const gchar *filename, const gchar *cipher,
1236 const gchar *keyfile, const gchar *keygrip, const gchar *sign_keygrip,
1237 gboolean nopass, const gchar *outfile, const gchar *keyparam,
1238 gulong s2k_count)
1240 gpg_error_t rc;
1241 gpointer data = NULL;
1242 gsize datalen;
1243 struct crypto_s *crypto = NULL;
1244 guint16 ver;
1245 gint algo;
1247 if (outfile[0] == '-' && outfile[1] == 0)
1248 outfile = NULL;
1250 log_write(_("Converting version 2 data file \"%s\" ..."), filename);
1251 if (access(filename, R_OK) == -1) {
1252 log_write("%s: %s", filename, pwmd_strerror(gpg_error_from_syserror()));
1253 return FALSE;
1256 if (keyfile) {
1257 log_write(_("Using passphrase file \"%s\" for decryption ..."),
1258 keyfile);
1259 if (access(keyfile, R_OK) == -1) {
1260 log_write("%s: %s", keyfile,
1261 pwmd_strerror(gpg_error_from_syserror()));
1262 return FALSE;
1266 rc = read_v2_datafile(filename, keyfile, &data, &datalen, &ver, &algo);
1267 if (rc) {
1268 log_write("%s", pwmd_strerror(rc));
1269 return FALSE;
1272 if (cipher) {
1273 algo = cipher_string_to_gcrypt(cipher);
1274 if (algo == -1) {
1275 rc = GPG_ERR_CIPHER_ALGO;
1276 goto fail;
1280 if (ver < 0x212) {
1281 xmlDocPtr doc = parse_doc(data, datalen);
1283 if (!doc) {
1284 rc = GPG_ERR_BAD_DATA;
1285 goto fail;
1288 rc = convert_pre_212_elements(doc);
1289 gcry_free(data);
1290 data = NULL;
1291 if (!rc) {
1292 xmlDocDumpFormatMemory(doc, (xmlChar **)&data, (gint *)&datalen, 0);
1293 if (!data)
1294 rc = GPG_ERR_ENOMEM;
1297 xmlFreeDoc(doc);
1298 if (rc)
1299 goto fail;
1302 rc = init_client_crypto(&crypto);
1303 if (!rc) {
1304 rc = set_pinentry_options(crypto->agent);
1305 if (!rc) {
1306 memcpy(&crypto->save.hdr, &crypto->hdr,
1307 sizeof(file_header_t));
1308 crypto->save.hdr.flags = set_cipher_flag(crypto->save.hdr.flags, algo);
1309 crypto->save.s2k_count = (gulong)s2k_count;
1310 rc = export_common(crypto, keygrip, sign_keygrip, nopass, data,
1311 datalen, outfile, keyparam,
1312 no_passphrase_file ? NULL : keyfile);
1313 if (!rc)
1314 log_write(_("Output written to \"%s\"."), outfile);
1318 fail:
1319 if (ver < 0x212)
1320 xmlFree(data);
1321 else
1322 gcry_free(data);
1323 cleanup_crypto(&crypto);
1325 if (rc)
1326 log_write("%s", pwmd_strerror(rc));
1327 return rc ? FALSE : TRUE;
1330 int main(int argc, char *argv[])
1332 gint opt;
1333 struct sockaddr_un addr;
1334 gchar buf[PATH_MAX];
1335 gchar *socketpath = NULL, *socketdir, *socketname = NULL;
1336 gchar *socketarg = NULL;
1337 gchar *datadir = NULL;
1338 gboolean n;
1339 gint x;
1340 gchar *p;
1341 gchar **cache_push = NULL;
1342 gchar *import = NULL, *keygrip = NULL, *sign_keygrip = NULL;
1343 gchar *keyparam = NULL;
1344 gboolean rcfile_spec = FALSE;
1345 gint estatus = EXIT_FAILURE;
1346 gint sockfd;
1347 gchar *outfile = NULL;
1348 GMemVTable mtable = { xmalloc, xrealloc, xfree, xcalloc, NULL, NULL };
1349 gint do_unlink = 0;
1350 gboolean secure = FALSE;
1351 gint show_version = 0;
1352 gboolean force = FALSE;
1353 gboolean no_passphrase = FALSE;
1354 gpg_error_t rc;
1355 gchar *convertfile = NULL;
1356 gchar *cipher = NULL;
1357 gchar *keyfile = NULL;
1358 glong s2k_count = -1;
1359 GError *error = NULL;
1360 gchar *debug_level_opt = NULL;
1361 GOptionContext *context;
1362 GOptionEntry options[] =
1364 { "version", 0, 0, G_OPTION_ARG_NONE, &show_version,
1365 "version information", NULL },
1366 { "no-fork", 'n', 0, G_OPTION_ARG_NONE, &nofork,
1367 "run as a foreground process", NULL },
1368 { "disable-dump", 'D', 0, G_OPTION_ARG_NONE, &secure,
1369 "disable the LIST, XPATH and DUMP commands", NULL },
1370 { "rcfile", 'f', 0, G_OPTION_ARG_FILENAME, &rcfile,
1371 "load the specified rcfile (~/.pwmd/config)", "filename" },
1372 { "ignore", 0, 0, G_OPTION_ARG_NONE, &force,
1373 "ignore cache failures on startup", NULL },
1374 { "outfile", 'o', 0, G_OPTION_ARG_FILENAME, &outfile,
1375 "output file when importing (- for stdout)", "filename" },
1376 { "convert", 'C', 0, G_OPTION_ARG_FILENAME, &convertfile,
1377 "convert a version 2 data file to version 3", "filename" },
1378 { "passphrase-file", 'k', 0, G_OPTION_ARG_FILENAME, &keyfile,
1379 "for decryption when converting", "filename" },
1380 { "no-passphrase-file", 0, 0, G_OPTION_ARG_NONE, &no_passphrase_file,
1381 "no --passphrase-file after conversion", NULL },
1382 { "import", 'I', 0, G_OPTION_ARG_FILENAME, &import,
1383 "import an XML file", "filename" },
1384 { "keygrip", 0, 0, G_OPTION_ARG_STRING, &keygrip,
1385 "the public keygrip to use for encryption", "hexstring"},
1386 { "sign-keygrip", 0, 0, G_OPTION_ARG_STRING, &sign_keygrip,
1387 "the keygrip to use for signing of the data", "hexstring"},
1388 { "keyparam", 0, 0, G_OPTION_ARG_STRING, &keyparam,
1389 "alternate key parameters to use (RSA-2048)", "s-exp"},
1390 { "no-passphrase", 0, 0, G_OPTION_ARG_NONE, &no_passphrase,
1391 "for the imported/converted keypair", NULL },
1392 { "cipher", 0, 0, G_OPTION_ARG_STRING, &cipher,
1393 "encryption cipher, see man page (AES-256)", "string" },
1394 { "s2k-count", 0, 0, G_OPTION_ARG_INT64, &s2k_count,
1395 "hash iteration count >65536 (calibrated)", "iterations" },
1396 { "debug-level", 0, 0, G_OPTION_ARG_STRING, &debug_level_opt,
1397 "protocol output, see man page", "keywords"},
1398 { NULL }
1401 #ifndef DEBUG
1402 #ifdef HAVE_SETRLIMIT
1403 struct rlimit rl;
1405 rl.rlim_cur = rl.rlim_max = 0;
1407 if (setrlimit(RLIMIT_CORE, &rl) != 0)
1408 err(EXIT_FAILURE, "setrlimit()");
1409 #endif
1410 #endif
1412 #ifdef ENABLE_NLS
1413 setlocale(LC_ALL, "");
1414 bindtextdomain("pwmd", LOCALEDIR);
1415 textdomain("pwmd");
1416 #endif
1418 #ifndef MEM_DEBUG
1419 xmem_init();
1420 #endif
1421 g_mem_set_vtable(&mtable);
1422 g_thread_init(NULL);
1423 gpg_err_init();
1424 setup_crypto();
1425 xmlMemSetup(g_free, g_malloc, g_realloc, g_strdup);
1426 xmlInitMemory();
1427 xmlInitGlobals();
1428 xmlInitParser();
1429 xmlXPathInit();
1430 g_snprintf(buf, sizeof(buf), "%s/.pwmd", g_get_home_dir());
1431 if (mkdir(buf, 0700) == -1 && errno != EEXIST)
1432 err(EXIT_FAILURE, "%s", buf);
1434 g_snprintf(buf, sizeof(buf), "%s/.pwmd/data", g_get_home_dir());
1435 if (mkdir(buf, 0700) == -1 && errno != EEXIST)
1436 err(EXIT_FAILURE, "%s", buf);
1438 cmdline = TRUE;
1439 context = g_option_context_new("- Password Manager Daemon");
1440 g_option_context_add_main_entries(context, options, NULL);
1441 if (!g_option_context_parse(context, &argc, &argv, &error))
1443 g_print("Option parsing failed: %s\n", error->message);
1444 exit(EXIT_FAILURE);
1447 if (show_version) {
1448 printf(_("%s\n\n"
1449 "Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011\n"
1450 "%s\n"
1451 "Released under the terms of the GPL v2. Use at your own risk.\n\n"
1452 "Compile time features:\n%s"), PACKAGE_STRING, PACKAGE_BUGREPORT,
1453 #ifdef WITH_LIBACL
1454 "+WITH_LIBACL\n"
1455 #else
1456 "-WITH_LIBACL\n"
1457 #endif
1458 #ifdef DEBUG
1459 "+DEBUG\n"
1460 #else
1461 "-DEBUG\n"
1462 #endif
1463 #ifdef MEM_DEBUG
1464 "+MEM_DEBUG\n"
1465 #else
1466 "-MEM_DEBUG\n"
1467 #endif
1468 #ifdef MUTEX_DEBUG
1469 "+MUTEX_DEBUG\n"
1470 #else
1471 "-MUTEX_DEBUG\n"
1472 #endif
1474 exit(EXIT_SUCCESS);
1477 pthread_mutexattr_t attr;
1478 pthread_mutexattr_init(&attr);
1479 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
1480 pthread_mutex_init(&rcfile_mutex, &attr);
1481 pthread_mutex_init(&cn_mutex, &attr);
1482 pthread_mutexattr_destroy(&attr);
1484 if (!rcfile)
1485 rcfile = g_strdup_printf("%s/.pwmd/config", g_get_home_dir());
1486 else
1487 rcfile_spec = TRUE;
1489 if ((keyfileh = parse_rcfile(rcfile_spec, cmdline)) == NULL)
1490 exit(EXIT_FAILURE);
1492 if (debug_level_opt)
1493 debug_level = g_strsplit(debug_level_opt, ",", 0);
1495 if (g_key_file_has_key(keyfileh, "global", "syslog", NULL) == TRUE)
1496 log_syslog = g_key_file_get_boolean(keyfileh, "global", "syslog", NULL);
1498 if (log_syslog == TRUE)
1499 openlog("pwmd", LOG_NDELAY|LOG_PID, LOG_DAEMON);
1501 if (g_key_file_has_key(keyfileh, "global", "priority", NULL)) {
1502 x = g_key_file_get_integer(keyfileh, "global", "priority", NULL);
1503 errno = 0;
1505 if (setpriority(PRIO_PROCESS, 0, x) == -1) {
1506 log_write("setpriority(): %s", pwmd_strerror(gpg_error_from_syserror()));
1507 goto do_exit;
1511 #ifdef HAVE_MLOCKALL
1512 if (disable_mlock == FALSE && mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
1513 log_write("mlockall(): %s", pwmd_strerror(gpg_error_from_syserror()));
1514 goto do_exit;
1516 #endif
1518 rc = cache_init(free_cache_data);
1519 if (rc) {
1520 log_write("pwmd: gpg-agent: %s",
1521 gpg_err_code(rc) == GPG_ERR_UNKNOWN_VERSION
1522 ? _("incompatible version: 2.1.0 or later required")
1523 : pwmd_strerror(rc));
1524 goto do_exit;
1527 if (s2k_count == -1)
1528 s2k_count = get_key_file_ulong(NULL, "s2k_count");
1530 if (convertfile) {
1531 if (!outfile) {
1532 gchar *tmp = g_option_context_get_help(context, TRUE, NULL);
1533 fprintf(stderr, "%s", tmp);
1534 g_free(tmp);
1535 exit(EXIT_FAILURE);
1538 estatus = convert_v2_datafile(convertfile, cipher, keyfile, keygrip,
1539 sign_keygrip, no_passphrase, outfile, keyparam,
1540 (gulong)s2k_count);
1541 g_key_file_free(keyfileh);
1542 g_free(rcfile);
1543 exit(!estatus);
1546 if (import) {
1547 if (!outfile) {
1548 gchar *tmp = g_option_context_get_help(context, TRUE, NULL);
1549 fprintf(stderr, "%s", tmp);
1550 g_free(tmp);
1551 exit(EXIT_FAILURE);
1554 if (outfile[0] == '-' && outfile[1] == 0)
1555 outfile = NULL;
1557 estatus = xml_import(import, outfile, keygrip, sign_keygrip, keyfile,
1558 no_passphrase, cipher, keyparam, (gulong)s2k_count);
1559 g_key_file_free(keyfileh);
1560 g_free(rcfile);
1561 exit(!estatus);
1564 g_option_context_free(context);
1565 if ((p = g_key_file_get_string(keyfileh, "global", "socket_path", NULL)) == NULL)
1566 errx(EXIT_FAILURE, _("%s: socket_path not defined"), rcfile);
1568 socketarg = expand_homedir(p);
1569 g_free(p);
1571 if ((p = g_key_file_get_string(keyfileh, "global", "data_directory", NULL)) == NULL)
1572 errx(EXIT_FAILURE, _("%s: data_directory not defined"), rcfile);
1574 datadir = expand_homedir(p);
1575 g_free(p);
1577 if (secure == FALSE && g_key_file_has_key(keyfileh, "global", "disable_list_and_dump", NULL) == TRUE) {
1578 n = g_key_file_get_boolean(keyfileh, "global", "disable_list_and_dump", NULL);
1579 disable_list_and_dump = n;
1581 else
1582 disable_list_and_dump = secure;
1584 setup_logging(keyfileh);
1586 if (g_key_file_has_key(keyfileh, "global", "cache_push", NULL) == TRUE)
1587 cache_push = g_key_file_get_string_list(keyfileh, "global", "cache_push", NULL, NULL);
1589 for (gint n = 1; n < argc; n++) {
1590 if (strv_printf(&cache_push, "%s", argv[n]) == FALSE)
1591 errx(EXIT_FAILURE, "%s", pwmd_strerror(GPG_ERR_ENOMEM));
1594 if (strchr(socketarg, '/') == NULL) {
1595 socketdir = g_get_current_dir();
1596 socketname = g_strdup(socketarg);
1597 socketpath = g_strdup_printf("%s/%s", socketdir, socketname);
1599 else {
1600 socketname = g_strdup(strrchr(socketarg, '/'));
1601 socketname++;
1602 socketarg[strlen(socketarg) - strlen(socketname) -1] = 0;
1603 socketdir = g_strdup(socketarg);
1604 socketpath = g_strdup_printf("%s/%s", socketdir, socketname);
1607 if (chdir(datadir)) {
1608 log_write("%s: %s", datadir, pwmd_strerror(gpg_error_from_syserror()));
1609 unlink(socketpath);
1610 goto do_exit;
1614 * Set the cache entry for a file. Prompts for the password.
1616 if (cache_push) {
1617 struct crypto_s *crypto;
1618 gpg_error_t rc = init_client_crypto(&crypto);
1620 if (rc) {
1621 estatus = EXIT_FAILURE;
1622 goto do_exit;
1625 rc = set_pinentry_options(crypto->agent);
1626 if (rc) {
1627 estatus = EXIT_FAILURE;
1628 goto do_exit;
1631 for (opt = 0; cache_push[opt]; opt++) {
1632 if (!do_cache_push(cache_push[opt], crypto) && !force) {
1633 g_strfreev(cache_push);
1634 startup_failure();
1635 estatus = EXIT_FAILURE;
1636 cleanup_crypto(&crypto);
1637 goto do_exit;
1640 cleanup_crypto_stage1(crypto);
1643 (void)kill_scd(crypto->agent);
1644 cleanup_crypto(&crypto);
1645 g_strfreev(cache_push);
1646 log_write(!nofork ? _("Done. Daemonizing...") : _("Done. Waiting for connections..."));
1649 clear_rcfile_keys();
1652 * bind() doesn't like the full pathname of the socket or any non alphanum
1653 * characters so change to the directory where the socket is wanted then
1654 * create it then change to datadir.
1656 if (chdir(socketdir)) {
1657 log_write("%s: %s", socketdir, pwmd_strerror(gpg_error_from_syserror()));
1658 goto do_exit;
1661 g_free(socketdir);
1663 if ((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
1664 log_write("socket(): %s", pwmd_strerror(gpg_error_from_syserror()));
1665 goto do_exit;
1668 addr.sun_family = AF_UNIX;
1669 g_snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socketname);
1671 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
1672 log_write("bind(): %s", pwmd_strerror(gpg_error_from_syserror()));
1674 if (errno == EADDRINUSE)
1675 log_write(_("Either there is another pwmd running or '%s' is a \n"
1676 "stale socket. Please remove it manually."), socketpath);
1678 goto do_exit;
1681 do_unlink = 1;
1682 if (g_key_file_has_key(keyfileh, "global", "socket_perms", NULL) == TRUE) {
1683 gchar *t = g_key_file_get_string(keyfileh, "global", "socket_perms", NULL);
1684 mode_t mode = strtol(t, NULL, 8);
1685 mode_t mask = umask(0);
1687 g_free(t);
1689 if (chmod(socketname, mode) == -1) {
1690 log_write("%s: %s", socketname, pwmd_strerror(gpg_error_from_syserror()));
1691 close(sockfd);
1692 unlink(socketpath);
1693 umask(mask);
1694 goto do_exit;
1697 umask(mask);
1700 g_free(--socketname);
1702 if (chdir(datadir)) {
1703 log_write("%s: %s", datadir, pwmd_strerror(gpg_error_from_syserror()));
1704 close(sockfd);
1705 unlink(socketpath);
1706 goto do_exit;
1709 g_free(datadir);
1711 if (listen(sockfd, 0) == -1) {
1712 log_write("listen(): %s", pwmd_strerror(gpg_error_from_syserror()));
1713 goto do_exit;
1716 cmdline = FALSE;
1718 if (!nofork) {
1719 switch (fork()) {
1720 case -1:
1721 log_write("fork(): %s", pwmd_strerror(gpg_error_from_syserror()));
1722 goto do_exit;
1723 case 0:
1724 close(0);
1725 close(1);
1726 close(2);
1727 setsid();
1728 break;
1729 default:
1730 _exit(EXIT_SUCCESS);
1734 pthread_key_create(&thread_name_key, free_key);
1735 pthread_setspecific(thread_name_key, g_strdup("main"));
1736 pthread_cond_init(&rcfile_cond, NULL);
1737 pthread_key_create(&last_error_key, free_key);
1738 estatus = server_loop(sockfd, &socketpath);
1740 do_exit:
1741 if (socketpath && do_unlink) {
1742 unlink(socketpath);
1743 g_free(socketpath);
1746 g_free(socketarg);
1747 if (keyfileh)
1748 g_key_file_free(keyfileh);
1749 g_free(rcfile);
1750 xmlCleanupParser();
1751 xmlCleanupGlobals();
1753 if (estatus == EXIT_SUCCESS)
1754 log_write(_("pwmd exiting normally"));
1756 #if defined(DEBUG) && !defined(MEM_DEBUG)
1757 xdump();
1758 #endif
1759 exit(estatus);