Remove GLib dependency.
[pwmd.git] / src / pwmd.c
blobaf82c69842d1918877a72f636714f50f1e08a13a
1 /*
2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of pwmd.
7 Pwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Pwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
20 #ifdef HAVE_CONFIG_H
21 #include <config.h>
22 #endif
24 #include <stdio.h>
25 #include <stdlib.h>
26 #include <unistd.h>
27 #include <err.h>
28 #include <ctype.h>
29 #include <string.h>
30 #include <sys/socket.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 <sys/mman.h>
41 #include <termios.h>
42 #include <assert.h>
43 #include <syslog.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
46 #include <netdb.h>
47 #include <sys/time.h>
48 #include <sys/resource.h>
49 #include <setjmp.h>
51 #ifdef TM_IN_SYS_TIME
52 #include <sys/time.h>
53 #else
54 #include <time.h>
55 #endif
57 #ifdef HAVE_LIMITS_H
58 #include <limits.h>
59 #endif
61 #ifdef HAVE_GETOPT_LONG
62 #ifdef HAVE_GETOPT_H
63 #include <getopt.h>
64 #endif
65 #else
66 #include "getopt_long.h"
67 #endif
69 #ifdef HAVE_PR_SET_NAME
70 #include <sys/prctl.h>
71 #endif
73 #include "pwmd-error.h"
74 #include <gcrypt.h>
76 #include "mem.h"
77 #include "xml.h"
78 #include "common.h"
79 #include "commands.h"
80 #include "cache.h"
81 #include "util-misc.h"
82 #include "util-string.h"
83 #include "mutex.h"
84 #include "rcfile.h"
85 #include "agent.h"
86 #include "convert.h"
88 static int quit;
89 static int exiting;
90 static int cmdline;
91 static jmp_buf jmp;
92 static int nofork;
93 static pthread_cond_t quit_cond;
94 static pthread_mutex_t quit_mutex;
95 static int no_passphrase_file = 0;
96 #ifdef WITH_GNUTLS
97 static int tls_fd;
98 static int tls6_fd;
99 static pthread_t tls_tid;
100 static pthread_t tls6_tid;
102 static int start_stop_tls(int term);
103 #endif
105 static int do_cache_push(const char *filename, struct crypto_s *crypto);
106 static int signal_loop(sigset_t sigset);
108 GCRY_THREAD_OPTION_PTHREAD_IMPL;
110 static void cache_push_from_rcfile()
112 struct crypto_s *crypto;
113 char **cache_push;
114 gpg_error_t rc = init_client_crypto(&crypto);
116 if (rc) {
117 log_write("%s: %s", __FUNCTION__, pwmd_strerror(rc));
118 return;
121 rc = set_agent_option(crypto->agent, "pinentry-mode", "error");
122 if (rc) {
123 log_write("%s: %s", __FUNCTION__, pwmd_strerror(rc));
124 return;
127 cache_push = config_get_list("global", "cache_push");
128 if (cache_push) {
129 char **p;
131 for (p = cache_push; *p; p++) {
132 (void)do_cache_push(*p, crypto);
133 cleanup_crypto_stage1(crypto);
136 strv_free(cache_push);
139 (void)kill_scd(crypto->agent);
140 cleanup_crypto(&crypto);
143 static void setup_logging()
145 int n = config_get_boolean("global", "enable_logging");
147 if (n) {
148 char *p = config_get_string("global", "log_path");
150 xfree(logfile);
151 logfile = expand_homedir(p);
152 xfree(p);
154 else {
155 xfree(logfile);
156 logfile = NULL;
159 log_syslog = config_get_boolean("global", "syslog");
160 if (log_syslog == 1)
161 openlog("pwmd", LOG_NDELAY|LOG_PID, LOG_DAEMON);
164 static void *reload_rcfile_thread(void *arg)
166 #ifdef HAVE_PR_SET_NAME
167 prctl(PR_SET_NAME, "reload rcfile");
168 #endif
169 pthread_setspecific(thread_name_key, str_dup(__FUNCTION__));
170 MUTEX_LOCK(&rcfile_mutex);
171 pthread_cleanup_push(cleanup_mutex_cb, &rcfile_mutex);
173 for (;;) {
174 int exists;
175 struct slist_s *config;
176 char **users;
177 int b = disable_list_and_dump;
178 #ifdef WITH_GNUTLS
179 int tcp_require_key = config_get_bool_param(global_config, "global",
180 "tcp_require_key", &exists);
181 #endif
183 pthread_cond_wait(&rcfile_cond, &rcfile_mutex);
184 users = config_get_list("global", "allowed");
185 log_write(_("reloading configuration file '%s'"), rcfile);
186 config = config_parse(rcfile);
187 if (config) {
188 config_free(global_config);
189 global_config = config;
190 setup_logging();
191 cache_push_from_rcfile();
192 config_clear_keyss();
195 disable_list_and_dump = !disable_list_and_dump ? b : 1;
196 #ifdef WITH_GNUTLS
197 if (config_get_bool_param(global_config, "global", "tcp_require_key",
198 &exists) && exists)
199 tcp_require_key = 1;
201 config_set_bool_param(&global_config, "global", "tcp_require_key",
202 tcp_require_key ? "true" : "false");
203 #endif
204 char *tmp = strv_join(",", users);
205 config_set_list_param(&global_config, "global", "allowed", tmp);
206 xfree(tmp);
207 strv_free(users);
208 #ifdef WITH_GNUTLS
209 /* Kill existing listening threads since the configured listening
210 * protocols may have changed. */
211 start_stop_tls(1);
212 start_stop_tls(0);
213 #endif
216 pthread_cleanup_pop(1);
217 return NULL;
220 gpg_error_t send_error(assuan_context_t ctx, gpg_error_t e)
222 struct client_s *client = assuan_get_pointer(ctx);
224 if (gpg_err_source(e) == GPG_ERR_SOURCE_UNKNOWN)
225 e = gpg_error(e);
227 if (client)
228 client->last_rc = e;
230 if (!e)
231 return assuan_process_done(ctx, 0);
233 if (!ctx) {
234 log_write("%s", pwmd_strerror(e));
235 return e;
238 if (gpg_err_code(e) == GPG_ERR_BAD_DATA) {
239 xmlErrorPtr xe = client->xml_error;
241 if (!xe)
242 xe = xmlGetLastError();
243 if (xe) {
244 log_write("%s", xe->message);
245 if (client->last_error)
246 xfree(client->last_error);
248 client->last_error = str_dup(xe->message);
251 e = assuan_process_done(ctx, assuan_set_error(ctx, e,
252 xe ? xe->message : NULL));
254 if (xe == client->xml_error)
255 xmlResetError(xe);
256 else
257 xmlResetLastError();
259 client->xml_error = NULL;
260 return e;
263 return assuan_process_done(ctx, assuan_set_error(ctx, e, pwmd_strerror(e)));
266 int assuan_log_cb(assuan_context_t ctx, void *data, unsigned cat,
267 const char *msg)
269 static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
270 int i, t;
271 int match = 0;
273 pthread_mutex_lock(&m);
274 pthread_cleanup_push((void (*)(void *))pthread_mutex_unlock, &m);
275 t = strv_length(debug_level);
277 for (i = 0; i < t; i++) {
278 if (!strcasecmp(debug_level[i], (char *)"init")
279 && cat == ASSUAN_LOG_INIT) {
280 match = 1;
281 break;
284 if (!strcasecmp(debug_level[i], (char *)"ctx")
285 && cat == ASSUAN_LOG_CTX) {
286 match = 1;
287 break;
290 if (!strcasecmp(debug_level[i], (char *)"engine")
291 && cat == ASSUAN_LOG_ENGINE) {
292 match = 1;
293 break;
296 if (!strcasecmp(debug_level[i], (char *)"data")
297 && cat == ASSUAN_LOG_DATA) {
298 match = 1;
299 break;
302 if (!strcasecmp(debug_level[i], (char *)"sysio")
303 && cat == ASSUAN_LOG_SYSIO) {
304 match = 1;
305 break;
308 if (!strcasecmp(debug_level[i], (char *)"control")
309 && cat == ASSUAN_LOG_CONTROL) {
310 match = 1;
311 break;
315 if (match && msg) {
316 if (logfile) {
317 int fd;
319 if ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600)) == -1)
320 warn("%s", logfile);
321 else {
322 pthread_cleanup_push(cleanup_fd_cb, &fd);
323 write(fd, msg, strlen(msg));
324 pthread_cleanup_pop(1);
328 if (nofork) {
329 fprintf(stderr, "%s%s", data ? (char *)data : "", msg);
330 fflush(stderr);
334 pthread_cleanup_pop(1);
335 return match;
338 void log_write(const char *fmt, ...)
340 char *args, *line;
341 va_list ap;
342 struct tm *tm;
343 time_t now;
344 char tbuf[21];
345 int fd = -1;
346 char *name = NULL;
347 char buf[255];
348 pthread_t tid = pthread_self();
349 static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
351 if ((!logfile && !isatty(STDERR_FILENO) && !log_syslog) || !fmt)
352 return;
354 pthread_mutex_lock(&m);
355 pthread_cleanup_push((void (*)(void *))pthread_mutex_unlock, &m);
356 pthread_cleanup_push(cleanup_fd_cb, &fd);
358 if (!cmdline && logfile) {
359 if ((fd = open(logfile, O_WRONLY|O_CREAT|O_APPEND, 0600)) == -1)
360 warn("%s", logfile);
363 va_start(ap, fmt);
365 if (str_vasprintf(&args, fmt, ap) != -1) {
366 if (cmdline) {
367 pthread_cleanup_push(xfree, args);
368 fprintf(stderr, "%s\n", args);
369 fflush(stderr);
370 pthread_cleanup_pop(1);
372 else {
373 pthread_cleanup_push(xfree, args);
374 name = pthread_getspecific(thread_name_key);
375 snprintf(buf, sizeof(buf), "%s(%p): ", name ? name : _("unknown"),
376 (pthread_t *)tid);
377 name = buf;
379 if (!cmdline && log_syslog && !nofork)
380 syslog(LOG_INFO, "%s%s", name, args);
382 time(&now);
383 tm = localtime(&now);
384 strftime(tbuf, sizeof(tbuf), "%b %d %Y %H:%M:%S ", tm);
385 tbuf[sizeof(tbuf) - 1] = 0;
387 if (args[strlen(args)-1] == '\n')
388 args[strlen(args)-1] = 0;
390 line = str_asprintf("%s %i %s%s\n", tbuf, getpid(), name,
391 args);
392 pthread_cleanup_pop(1);
393 if (line) {
394 pthread_cleanup_push(xfree, line);
395 if (logfile && fd != -1) {
396 write(fd, line, strlen(line));
397 fsync(fd);
400 if (nofork) {
401 fprintf(stdout, "%s", line);
402 fflush(stdout);
405 pthread_cleanup_pop(1);
410 va_end(ap);
411 pthread_cleanup_pop(1);
412 pthread_cleanup_pop(0);
413 pthread_mutex_unlock(&m);
416 #ifdef WITH_GNUTLS
417 static int secure_mem_check(const void *arg)
419 return 1;
421 #endif
423 static gpg_error_t setup_crypto()
425 gcry_control(GCRYCTL_SET_THREAD_CBS, &gcry_threads_pthread);
427 if (!gcry_check_version(GCRYPT_VERSION)) {
428 fprintf(stderr, _("gcry_check_version(): Incompatible libgcrypt. "
429 "Wanted %s, got %s.\n"), GCRYPT_VERSION,
430 gcry_check_version(NULL));
431 return GPG_ERR_UNKNOWN_VERSION;
434 gcry_set_allocation_handler(xmalloc, xmalloc, NULL, xrealloc, xfree);
435 return 0;
438 static gpg_error_t validate_peer(struct client_s *cl)
440 char **users;
441 int allowed = 0;
442 assuan_peercred_t peercred;
443 gpg_error_t rc;
445 #ifdef WITH_GNUTLS
446 if (cl->thd->remote)
447 return 0;
448 #endif
450 rc = assuan_get_peercred(cl->ctx, &peercred);
451 if (rc)
452 return rc;
454 users = config_get_list("global", "allowed");
455 if (users) {
456 for (char **p = users; *p; p++) {
457 struct passwd pw, *result;
458 struct group gr, *gresult;
459 char *buf;
461 if (*(*p) == '@') {
462 size_t len = sysconf(_SC_GETGR_R_SIZE_MAX);
464 if (len == -1)
465 len = 16384;
467 buf = xmalloc(len);
469 if (!buf) {
470 strv_free(users);
471 return GPG_ERR_ENOMEM;
474 if (!getgrnam_r(*(p)+1, &gr, buf, len, &gresult) && gresult) {
475 if (gresult->gr_gid == peercred->gid) {
476 xfree(buf);
477 allowed = 1;
478 break;
481 len = sysconf(_SC_GETPW_R_SIZE_MAX);
483 if (len == -1)
484 len = 16384;
486 char *tbuf = xmalloc(len);
488 for (char **t = gresult->gr_mem; *t; t++) {
489 if (!getpwnam_r(*t, &pw, tbuf, len, &result) && result) {
490 if (result->pw_uid == peercred->uid) {
491 xfree(buf);
492 allowed = 1;
493 break;
498 xfree(tbuf);
500 if (allowed)
501 break;
504 else {
505 size_t len = sysconf(_SC_GETPW_R_SIZE_MAX);
507 if (len == -1)
508 len = 16384;
510 buf = xmalloc(len);
512 if (!buf) {
513 strv_free(users);
514 return GPG_ERR_ENOMEM;
517 if (!getpwnam_r(*p, &pw, buf, len, &result) && result) {
518 if (result->pw_uid == peercred->uid) {
519 xfree(buf);
520 allowed = 1;
521 break;
526 xfree(buf);
529 strv_free(users);
532 log_write("peer %s: uid=%i, gid=%i, pid=%i",
533 allowed ? _("accepted") : _("rejected"), peercred->uid,
534 peercred->gid, peercred->pid);
535 return allowed ? 0 : GPG_ERR_INV_USER_ID;
538 static void xml_error_cb(void *data, xmlErrorPtr e)
540 struct client_s *client = data;
543 * Keep the first reported error as the one to show in the error
544 * description. Reset in send_error().
546 if (client->xml_error)
547 return;
549 xmlCopyError(e, client->xml_error);
552 static pid_t hook_waitpid(assuan_context_t ctx, pid_t pid, int action,
553 int *status, int options)
555 return waitpid(pid, status, options);
558 static ssize_t hook_read(assuan_context_t ctx, assuan_fd_t fd, void *data,
559 size_t len)
561 #ifdef WITH_GNUTLS
562 struct client_s *client = assuan_get_pointer(ctx);
564 if (client->thd->remote)
565 return tls_read_hook(ctx, (int)fd, data, len);
566 #endif
568 return read((int)fd, data, len);
571 static ssize_t hook_write(assuan_context_t ctx, assuan_fd_t fd,
572 const void *data, size_t len)
574 #ifdef WITH_GNUTLS
575 struct client_s *client = assuan_get_pointer(ctx);
577 if (client->thd->remote)
578 return tls_write_hook(ctx, (int)fd, data, len);
579 #endif
581 return write((int)fd, data, len);
584 static int new_connection(struct client_s *cl)
586 gpg_error_t rc;
587 static struct assuan_malloc_hooks mhooks = { xmalloc, xrealloc, xfree };
588 static struct assuan_system_hooks shooks = {
589 ASSUAN_SYSTEM_HOOKS_VERSION,
590 __assuan_usleep,
591 __assuan_pipe,
592 __assuan_close,
593 hook_read,
594 hook_write,
595 //FIXME
596 NULL, //recvmsg
597 NULL, //sendmsg both are used for FD passing
598 __assuan_spawn,
599 hook_waitpid,
600 __assuan_socketpair,
601 __assuan_socket,
602 __assuan_connect
605 #ifdef WITH_GNUTLS
606 if (cl->thd->remote) {
607 char *prio = config_get_string("global", "tls_cipher_suite");
609 cl->thd->tls = tls_init(cl->thd->fd, prio);
610 xfree(prio);
611 if (!cl->thd->tls)
612 return 0;
614 #endif
616 rc = assuan_new_ext(&cl->ctx, GPG_ERR_SOURCE_DEFAULT, &mhooks,
617 debug_level ? assuan_log_cb : NULL, NULL);
618 if (rc)
619 goto fail;
621 assuan_ctx_set_system_hooks(cl->ctx, &shooks);
622 rc = assuan_init_socket_server(cl->ctx, cl->thd->fd, 2);
623 if (rc)
624 goto fail;
626 assuan_set_pointer(cl->ctx, cl);
627 assuan_set_hello_line(cl->ctx, PACKAGE_STRING);
628 rc = register_commands(cl->ctx);
629 if (rc)
630 goto fail;
632 rc = assuan_accept(cl->ctx);
633 if (rc)
634 goto fail;
636 rc = validate_peer(cl);
637 /* May not be implemented on all platforms. */
638 if (rc && gpg_err_code(rc) != GPG_ERR_ASS_GENERAL)
639 goto fail;
641 rc = init_client_crypto(&cl->crypto);
642 if (rc)
643 goto fail;
645 cl->crypto->agent->client_ctx = cl->ctx;
646 cl->crypto->client_ctx = cl->ctx;
647 xmlSetStructuredErrorFunc(cl, xml_error_cb);
648 return 1;
650 fail:
651 log_write("%s", pwmd_strerror(rc));
652 return 0;
656 * This is called after a client_thread() terminates. Set with
657 * pthread_cleanup_push().
659 static void cleanup_cb(void *arg)
661 struct client_thread_s *cn = arg;
662 struct client_s *cl = cn->cl;
664 MUTEX_LOCK(&cn_mutex);
665 cn_thread_list = slist_remove(cn_thread_list, cn);
666 MUTEX_UNLOCK(&cn_mutex);
668 if (cl) {
669 cleanup_client(cl);
671 #ifdef WITH_GNUTLS
672 if (cn->tls) {
673 gnutls_deinit(cn->tls->ses);
674 xfree(cn->tls->fp);
675 xfree(cn->tls);
677 #endif
679 if (cl->ctx)
680 assuan_release(cl->ctx);
681 else if (cl->thd && cl->thd->fd != -1)
682 close(cl->thd->fd);
684 if (cl->crypto)
685 cleanup_crypto(&cl->crypto);
687 xfree(cl);
689 else {
690 if (cn->fd != -1)
691 close(cn->fd);
694 while (cn->msg_queue) {
695 struct status_msg_s *msg = cn->msg_queue;
697 cn->msg_queue = msg->next;
698 xfree(msg->line);
699 xfree(msg);
702 if (cn->status_msg_pipe[0] != -1)
703 close(cn->status_msg_pipe[0]);
705 if (cn->status_msg_pipe[1] != -1)
706 close(cn->status_msg_pipe[1]);
708 pthread_mutex_destroy(&cn->status_mutex);
709 log_write(_("exiting, fd=%i"), cn->fd);
710 xfree(cn);
711 send_status_all(STATUS_CLIENTS, NULL);
712 pthread_cond_signal(&quit_cond);
715 static gpg_error_t send_msg_queue(struct client_thread_s *thd)
717 MUTEX_LOCK(&thd->status_mutex);
718 gpg_error_t rc = 0;
719 char c;
721 read(thd->status_msg_pipe[0], &c, 1);
723 while (thd->msg_queue) {
724 struct status_msg_s *msg = thd->msg_queue;
726 thd->msg_queue = thd->msg_queue->next;
727 MUTEX_UNLOCK(&thd->status_mutex);
728 rc = send_status(thd->cl->ctx, msg->s, msg->line);
729 MUTEX_LOCK(&thd->status_mutex);
730 xfree(msg->line);
731 xfree(msg);
733 if (rc)
734 break;
737 MUTEX_UNLOCK(&thd->status_mutex);
738 return rc;
741 static void *client_thread(void *data)
743 struct client_thread_s *thd = data;
744 struct client_s *cl = xcalloc(1, sizeof(struct client_s));
746 #ifdef HAVE_PR_SET_NAME
747 prctl(PR_SET_NAME, "client");
748 #endif
749 pthread_setspecific(thread_name_key, str_dup(__FUNCTION__));
751 if (!cl) {
752 log_write("%s(%i): %s", __FILE__, __LINE__,
753 pwmd_strerror(GPG_ERR_ENOMEM));
754 return NULL;
757 MUTEX_LOCK(&cn_mutex);
758 pthread_cleanup_push(cleanup_cb, thd);
759 thd->cl = cl;
760 cl->thd = thd;
761 MUTEX_UNLOCK(&cn_mutex);
763 if (new_connection(cl)) {
764 int finished = 0;
765 gpg_error_t rc;
767 send_status_all(STATUS_CLIENTS, NULL);
768 rc = send_status(cl->ctx, STATUS_CACHE, NULL);
769 if (rc) {
770 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(rc));
771 finished = 1;
774 while (!finished) {
775 fd_set rfds;
776 int n;
777 int eof;
779 FD_ZERO(&rfds);
780 FD_SET(thd->fd, &rfds);
781 FD_SET(thd->status_msg_pipe[0], &rfds);
782 n = thd->fd > thd->status_msg_pipe[0] ? thd->fd : thd->status_msg_pipe[0];
784 n = select(n+1, &rfds, NULL, NULL, NULL);
785 if (n == -1) {
786 log_write("%s", strerror(errno));
787 break;
790 if (FD_ISSET(thd->status_msg_pipe[0], &rfds)) {
791 rc = send_msg_queue(thd);
792 if (rc && gpg_err_code(rc) != GPG_ERR_EPIPE) {
793 log_write("%s(%i): %s", __FUNCTION__, __LINE__,
794 pwmd_strerror(rc));
795 break;
799 if (!FD_ISSET(thd->fd, &rfds))
800 continue;
802 rc = assuan_process_next(cl->ctx, &eof);
803 if (rc || eof) {
804 if (gpg_err_code(rc) == GPG_ERR_EOF || eof)
805 break;
807 log_write("assuan_process_next(): %s", pwmd_strerror(rc));
808 rc = send_error(cl->ctx, rc);
810 if (rc) {
811 log_write("assuan_process_done(): %s", pwmd_strerror(rc));
812 break;
816 /* Since the msg queue pipe fd's are non-blocking, check for
817 * pending status msgs here. GPG_ERR_EPIPE can be seen when the
818 * client has already disconnected and will be converted to
819 * GPG_ERR_EOF during assuan_process_next().
821 rc = send_msg_queue(thd);
822 if (rc && gpg_err_code(rc) != GPG_ERR_EPIPE) {
823 log_write("%s(%i): %s", __FUNCTION__, __LINE__,
824 pwmd_strerror(rc));
825 break;
830 pthread_cleanup_pop(1);
831 return NULL;
834 static int xml_import(const char *filename, const char *outfile,
835 const char *keygrip, const char *sign_keygrip, const char *keyfile,
836 int no_passphrase, const char *cipher, const char *params,
837 unsigned long s2k_count, uint64_t iterations)
839 xmlDocPtr doc;
840 int fd;
841 struct stat st;
842 int len;
843 xmlChar *xmlbuf;
844 xmlChar *xml;
845 gpg_error_t rc;
846 struct crypto_s *crypto;
847 int algo = cipher ? cipher_string_to_gcrypt((char *)cipher) :
848 GCRY_CIPHER_AES256;
850 if (algo == -1) {
851 log_write("ERR %i: %s", gpg_error(GPG_ERR_CIPHER_ALGO),
852 pwmd_strerror(GPG_ERR_CIPHER_ALGO));
853 return 0;
856 if (stat(filename, &st) == -1) {
857 log_write("%s: %s", filename, pwmd_strerror(gpg_error_from_syserror()));
858 return 0;
861 rc = init_client_crypto(&crypto);
862 if (rc)
863 return 0;
865 memcpy(&crypto->save.hdr, &crypto->hdr, sizeof(file_header_t));
866 crypto->save.hdr.flags = set_cipher_flag(crypto->save.hdr.flags, algo);
867 log_write(_("Importing XML from '%s'. Output will be written to '%s' ..."),
868 filename, outfile);
870 if ((fd = open(filename, O_RDONLY)) == -1) {
871 log_write("%s: %s", filename, pwmd_strerror(gpg_error_from_syserror()));
872 goto fail;
875 if ((xmlbuf = xmalloc(st.st_size+1)) == NULL) {
876 close(fd);
877 log_write("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror(GPG_ERR_ENOMEM));
878 goto fail;
881 if (read(fd, xmlbuf, st.st_size) == -1) {
882 rc = gpg_error_from_syserror();
883 close(fd);
884 log_write("%s: %s", filename, pwmd_strerror(rc));
885 goto fail;
888 close(fd);
889 xmlbuf[st.st_size] = 0;
891 * Make sure the document validates.
893 if ((doc = xmlReadDoc(xmlbuf, NULL, "UTF-8", XML_PARSE_NOBLANKS)) == NULL) {
894 log_write("xmlReadDoc() failed");
895 xfree(xmlbuf);
896 goto fail;
899 xfree(xmlbuf);
900 xmlNodePtr n = xmlDocGetRootElement(doc);
901 if (!xmlStrEqual(n->name, (xmlChar *)"pwmd")) {
902 log_write(_("Could not find root \"pwmd\" element."));
903 rc = GPG_ERR_BAD_DATA;
906 if (!rc)
907 rc = validate_import(n ? n->children : n);
909 if (rc) {
910 log_write("ERR %i: %s", rc, pwmd_strerror(rc));
911 xmlFreeDoc(doc);
912 goto fail;
915 xmlDocDumpMemory(doc, &xml, &len);
916 xmlFreeDoc(doc);
917 crypto->save.s2k_count = s2k_count;
918 crypto->save.hdr.iterations = iterations;
919 rc = set_pinentry_options(crypto->agent);
920 if (!rc)
921 rc = export_common(crypto, keygrip, sign_keygrip, no_passphrase, xml,
922 len, outfile, params, keyfile);
924 xmlFree(xml);
925 if (rc) {
926 send_error(NULL, rc);
927 goto fail;
930 cleanup_crypto(&crypto);
931 return 1;
933 fail:
934 cleanup_crypto(&crypto);
935 return 0;
938 static int do_cache_push(const char *filename, struct crypto_s *crypto)
940 unsigned char md5file[16];
941 gpg_error_t rc;
942 char *key = NULL;
943 size_t keylen;
944 xmlDocPtr doc;
945 struct cache_data_s *cdata;
946 unsigned char *crc;
947 size_t len;
949 log_write(_("Trying to add datafile '%s' to the file cache ..."),
950 filename);
952 if (valid_filename(filename) == 0) {
953 log_write(_("%s: Invalid characters in filename"), filename);
954 return 0;
957 rc = read_data_file(filename, crypto);
958 if (rc) {
959 log_write("ERR %i: %s", rc, pwmd_strerror(rc));
960 return 0;
963 if ((key = config_get_string(filename, "passphrase"))) {
964 log_write(_("Trying the passphrase specified in config ..."));
965 keylen = strlen(key);
967 else if ((key = config_get_string(filename, "passphrase_file"))) {
968 int fd = open((char *)key, O_RDONLY);
969 struct stat st;
971 log_write(_("Trying the passphrase using file '%s' ..."), key);
972 if (fd == -1) {
973 log_write("%s: %s", key, pwmd_strerror(gpg_error_from_syserror()));
974 xfree(key);
975 return 0;
978 stat((char *)key, &st);
979 xfree(key);
980 key = xmalloc(st.st_size);
981 if (read(fd, key, st.st_size) != st.st_size) {
982 log_write("short read() count");
983 xfree(key);
984 close(fd);
985 return 0;
988 keylen = st.st_size;
991 if (key) {
992 rc = set_agent_passphrase(crypto, key, keylen);
993 xfree(key);
994 if (rc) {
995 log_write("ERR %i: %s", rc, pwmd_strerror(rc));
996 return 0;
1000 crypto->filename = str_dup(filename);
1001 rc = decrypt_data(NULL, crypto);
1002 if (rc) {
1003 log_write("ERR %i: %s", rc, pwmd_strerror(rc));
1004 return 0;
1007 doc = parse_doc((char *)crypto->plaintext, crypto->plaintext_len);
1008 if (!doc) {
1009 log_write("%s", pwmd_strerror(GPG_ERR_ENOMEM));
1010 return 0;
1013 gcry_md_hash_buffer(GCRY_MD_MD5, md5file, filename, strlen(filename));
1014 cdata = xcalloc(1, sizeof(struct cache_data_s));
1015 if (!cdata) {
1016 xmlFreeDoc(doc);
1017 log_write("%s", pwmd_strerror(GPG_ERR_ENOMEM));
1018 return 0;
1021 rc = get_checksum(filename, &crc, &len);
1022 if (rc) {
1023 log_write("ERR %i: %s", rc, pwmd_strerror(rc));
1024 xmlFreeDoc(doc);
1025 free_cache_data_once(cdata);
1026 return 0;
1029 cdata->crc = crc;
1030 rc = encrypt_xml(NULL, cache_key, cache_keysize, GCRY_CIPHER_AES,
1031 crypto->plaintext, crypto->plaintext_len, &cdata->doc,
1032 &cdata->doclen, &cache_iv, &cache_blocksize, 0);
1033 if (rc) {
1034 log_write("ERR %i: %s", rc, pwmd_strerror(rc));
1035 xmlFreeDoc(doc);
1036 free_cache_data_once(cdata);
1037 return 0;
1040 gcry_sexp_build((gcry_sexp_t *)&cdata->pubkey, NULL, "%S", crypto->pkey_sexp);
1041 gcry_sexp_build((gcry_sexp_t *)&cdata->sigkey, NULL, "%S", crypto->sigpkey_sexp);
1042 int timeout = config_get_integer(filename, "cache_timeout");
1043 cache_add_file(md5file, crypto->grip, cdata, timeout);
1044 log_write(_("Successfully added '%s' to the cache."), filename);
1045 return 1;
1048 static gpg_error_t init_client_thread(int fd, const char *addr)
1050 gpg_error_t rc = 0;
1051 struct client_thread_s *new = xcalloc(1, sizeof(struct client_thread_s));
1053 if (!new) {
1054 close(fd);
1055 return GPG_ERR_ENOMEM;
1058 MUTEX_LOCK(&cn_mutex);
1059 pthread_cleanup_push(cleanup_mutex_cb, &cn_mutex);
1061 if (pipe(new->status_msg_pipe) == -1)
1062 rc = gpg_error_from_syserror();
1064 if (!rc) {
1065 fcntl(new->status_msg_pipe[0], F_SETFL, O_NONBLOCK);
1066 fcntl(new->status_msg_pipe[1], F_SETFL, O_NONBLOCK);
1067 pthread_mutex_init(&new->status_mutex, NULL);
1070 if (!rc) {
1071 #ifdef WITH_GNUTLS
1072 new->remote = addr ? 1 : 0;
1073 #endif
1074 new->fd = fd;
1075 rc = create_thread(client_thread, new, &new->tid, 1);
1076 if (rc) {
1077 close(new->status_msg_pipe[0]);
1078 close(new->status_msg_pipe[1]);
1079 pthread_mutex_destroy(&new->status_mutex);
1083 if (!rc) {
1084 struct slist_s *list = slist_append(cn_thread_list, new);
1086 if (list) {
1087 cn_thread_list = list;
1088 if (addr)
1089 log_write(_("new connection: tid=%p, fd=%i, addr=%s"),
1090 (pthread_t *)new->tid, fd, addr);
1091 else
1092 log_write(_("new connection: tid=%p, fd=%i"),
1093 (pthread_t *)new->tid, fd);
1095 else
1096 rc = GPG_ERR_ENOMEM;
1099 pthread_cleanup_pop(1);
1101 if (rc) {
1102 xfree(new);
1103 close(fd);
1104 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1105 pwmd_strerror(rc));
1107 return rc;
1110 #ifdef WITH_GNUTLS
1111 /* From Beej's Guide to Network Programming. It's a good tutorial. */
1112 static void *get_in_addr(struct sockaddr *sa)
1114 if (sa->sa_family == AF_INET)
1115 return &(((struct sockaddr_in*)sa)->sin_addr);
1117 return &(((struct sockaddr_in6*)sa)->sin6_addr);
1120 static void *tcp_accept_thread(void *arg)
1122 int sockfd = *(int*)arg;
1124 #ifdef HAVE_PR_SET_NAME
1125 prctl(PR_SET_NAME, "tcp_accept");
1126 #endif
1127 pthread_setspecific(thread_name_key, str_dup(__FUNCTION__));
1129 for (;;) {
1130 struct sockaddr_storage raddr;
1131 socklen_t slen = sizeof(raddr);
1132 int fd = -1;
1133 unsigned long n;
1134 char s[INET6_ADDRSTRLEN];
1136 fd = accept(sockfd, (struct sockaddr *)&raddr, &slen);
1137 if (fd == -1) {
1138 if (errno == EMFILE || errno == ENFILE)
1139 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
1140 else if (errno != EAGAIN) {
1141 if (!quit) // probably EBADF
1142 log_write("accept(): %s", strerror(errno));
1144 break;
1147 continue;
1150 if (quit)
1151 break;
1153 inet_ntop(raddr.ss_family, get_in_addr((struct sockaddr *)&raddr),
1154 s, sizeof s);
1155 (void)init_client_thread(fd, s);
1156 n = config_get_integer("global", "tcp_wait");
1157 if (n > 0)
1158 usleep(n*100000);
1161 /* Just in case accept() failed for some reason other than EBADF */
1162 quit = 1;
1163 return NULL;
1166 static int start_stop_tls_with_protocol(int ipv6, int term)
1168 struct addrinfo hints, *servinfo, *p;
1169 int port = config_get_integer("global", "tcp_port");
1170 char buf[7];
1171 int n;
1172 gpg_error_t rc;
1173 int *fd = ipv6 ? &tls6_fd : &tls_fd;
1175 if (term || config_get_boolean("global", "enable_tcp") == 0) {
1176 if (tls6_fd != -1) {
1177 pthread_cancel(tls6_tid);
1178 pthread_join(tls6_tid, NULL);
1179 shutdown(tls6_fd, SHUT_RDWR);
1180 close(tls6_fd);
1181 tls6_fd = -1;
1184 if (tls_fd != -1) {
1185 pthread_cancel(tls_tid);
1186 pthread_join(tls_tid, NULL);
1187 shutdown(tls_fd, SHUT_RDWR);
1188 close(tls_fd);
1189 tls_fd = -1;
1192 /* A client may still be connected. */
1193 if (!quit && x509_cred != NULL)
1194 tls_deinit_params();
1196 return 1;
1199 if ((ipv6 && tls6_fd != -1) || (!ipv6 && tls_fd != -1))
1200 return 1;
1202 memset(&hints, 0, sizeof(hints));
1203 hints.ai_family = ipv6 ? AF_INET6 : AF_INET;
1204 hints.ai_socktype = SOCK_STREAM;
1205 hints.ai_flags = AI_PASSIVE;
1206 snprintf(buf, sizeof(buf), "%i", port);
1208 if ((n = getaddrinfo(NULL, buf, &hints, &servinfo)) == -1) {
1209 log_write("getaddrinfo(): %s", gai_strerror(n));
1210 return 0;
1213 for (n = 0, p = servinfo; p != NULL; p = p->ai_next) {
1214 if ((ipv6 && p->ai_family != AF_INET6)
1215 || (!ipv6 && p->ai_family != AF_INET))
1216 continue;
1218 if ((*fd = socket(p->ai_family, p->ai_socktype,
1219 p->ai_protocol)) == -1) {
1220 log_write("socket(): %s", strerror(errno));
1221 continue;
1224 if (setsockopt(*fd, SOL_SOCKET, SO_REUSEADDR, &n,
1225 sizeof(int)) == -1) {
1226 log_write("setsockopt(): %s", strerror(errno));
1227 freeaddrinfo(servinfo);
1228 goto fail;
1231 if (bind(*fd, p->ai_addr, p->ai_addrlen) == -1) {
1232 close(*fd);
1233 log_write("bind(): %s", strerror(errno));
1234 continue;
1237 n++;
1238 break;
1241 freeaddrinfo(servinfo);
1243 if (!n) {
1244 log_write("%s", _("could not bind"));
1245 goto fail;
1248 #ifdef HAVE_DECL_SO_BINDTODEVICE
1249 char *tmp = config_get_string("global", "tcp_interface");
1250 if (setsockopt(*fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, 1) == -1) {
1251 log_write("setsockopt(): %s", strerror(errno));
1252 xfree(tmp);
1253 goto fail;
1256 xfree(tmp);
1257 #endif
1259 if (x509_cred == NULL) {
1260 rc = tls_init_params();
1261 if (rc)
1262 goto fail;
1265 if (listen(*fd, 0) == -1) {
1266 log_write("listen(): %s", strerror(errno));
1267 goto fail;
1270 if (ipv6)
1271 rc = create_thread(tcp_accept_thread, fd, &tls6_tid, 0);
1272 else
1273 rc = create_thread(tcp_accept_thread, fd, &tls_tid, 0);
1275 if (rc) {
1276 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1277 pwmd_strerror(rc));
1278 goto fail;
1281 return 1;
1283 fail:
1284 start_stop_tls_with_protocol(0, 1);
1285 if (tls_fd != -1)
1286 close(tls_fd);
1288 if (tls6_fd != -1)
1289 close(tls6_fd);
1291 tls_fd = -1;
1292 tls6_fd = -1;
1293 return 0;
1296 static int start_stop_tls(int term)
1298 char *s = config_get_string("global", "tcp_bind");
1299 int b;
1301 if (!s)
1302 return 0;
1304 if (!strcmp(s, "any")) {
1305 b = start_stop_tls_with_protocol(0, term);
1306 if (b)
1307 b = start_stop_tls_with_protocol(1, term);
1309 else if (!strcmp(s, "ipv4"))
1310 b = start_stop_tls_with_protocol(0, term);
1311 else if (!strcmp(s, "ipv6"))
1312 b = start_stop_tls_with_protocol(1, term);
1313 else
1314 b = 0;
1316 xfree(s);
1317 return b;
1319 #endif
1321 static void *accept_thread(void *arg)
1323 int sockfd = *(int *)arg;
1325 #ifdef HAVE_PR_SET_NAME
1326 prctl(PR_SET_NAME, "accept");
1327 #endif
1328 pthread_setspecific(thread_name_key, str_dup(__FUNCTION__));
1330 for (;;) {
1331 socklen_t slen = sizeof(struct sockaddr_un);
1332 struct sockaddr_un raddr;
1333 int fd;
1335 fd = accept(sockfd, (struct sockaddr *)&raddr, &slen);
1336 if (fd == -1) {
1337 if (errno == EMFILE || errno == ENFILE)
1338 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
1339 else if (errno != EAGAIN) {
1340 if (!quit) // probably EBADF
1341 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
1343 break;
1345 continue;
1348 (void)init_client_thread(fd, NULL);
1351 /* Just in case accept() failed for some reason other than EBADF */
1352 quit = 1;
1353 return NULL;
1356 static void *cache_timer_thread(void *arg)
1358 #ifdef HAVE_PR_SET_NAME
1359 prctl(PR_SET_NAME, "cache timer");
1360 #endif
1361 pthread_setspecific(thread_name_key, str_dup(__FUNCTION__));
1363 for (;;) {
1364 sleep(1);
1365 cache_adjust_timeout();
1368 return NULL;
1371 static void catch_sigabrt(int sig)
1373 cache_clear(NULL);
1374 #ifndef MEM_DEBUG
1375 xpanic();
1376 #endif
1379 static int signal_loop(sigset_t sigset)
1381 int done = 0;
1382 int siint = 0;
1384 do {
1385 int sig = sigwaitinfo(&sigset, NULL);
1387 if (sig == -1) {
1388 if (errno != EAGAIN)
1389 log_write("sigwaitinfo(): %s", strerror(errno));
1390 continue;
1393 if (sig != SIGUSR2)
1394 log_write(_("caught signal %i (%s)"), sig, strsignal(sig));
1396 switch (sig) {
1397 case SIGHUP:
1398 pthread_cond_signal(&rcfile_cond);
1399 break;
1400 case SIGABRT:
1401 // not really handled here.
1402 catch_sigabrt(SIGABRT);
1403 break;
1404 case SIGUSR1:
1405 log_write(_("clearing file cache"));
1406 cache_clear(NULL);
1407 send_status_all(STATUS_CACHE, NULL);
1408 break;
1409 case SIGUSR2:
1410 done = 1;
1411 break;
1412 default:
1413 siint = 1;
1414 done = 1;
1415 break;
1417 } while (!done);
1419 return siint;
1422 static void catchsig(int sig)
1424 log_write("Caught SIGSEGV. Exiting.");
1425 #ifdef HAVE_BACKTRACE
1426 BACKTRACE(__FUNCTION__);
1427 #endif
1428 longjmp(jmp, 1);
1431 static void *waiting_for_exit(void *arg)
1433 #ifdef HAVE_PR_SET_NAME
1434 prctl(PR_SET_NAME, "exiting");
1435 #endif
1436 pthread_setspecific(thread_name_key, str_dup(__FUNCTION__));
1437 log_write(_("waiting for all clients to disconnect"));
1438 MUTEX_LOCK(&quit_mutex);
1439 pthread_cleanup_push(cleanup_mutex_cb, &quit_mutex);
1441 for (;;) {
1442 MUTEX_LOCK(&cn_mutex);
1443 int n = slist_length(cn_thread_list);
1444 MUTEX_UNLOCK(&cn_mutex);
1445 if (!n)
1446 break;
1448 log_write(_("%i clients remain"), n);
1449 pthread_cond_wait(&quit_cond, &quit_mutex);
1452 pthread_cleanup_pop(1);
1453 kill(getpid(), SIGUSR2);
1454 return NULL;
1457 static int server_loop(int sockfd, char **socketpath)
1459 pthread_t accept_tid;
1460 pthread_t cache_timeout_tid;
1461 int cancel_timeout_thread = 0, cancel_accept_thread = 0;
1462 int n, i;
1463 sigset_t sigset;
1464 int segv = 0;
1465 gpg_error_t rc;
1467 init_commands();
1468 sigemptyset(&sigset);
1470 /* Termination */
1471 sigaddset(&sigset, SIGTERM);
1472 sigaddset(&sigset, SIGINT);
1474 /* Clears the file cache. */
1475 sigaddset(&sigset, SIGUSR1);
1477 /* Configuration file reloading. */
1478 sigaddset(&sigset, SIGHUP);
1480 /* For exiting cleanly. */
1481 sigaddset(&sigset, SIGUSR2);
1483 /* Clears the cache and exits when something bad happens. */
1484 signal(SIGABRT, catch_sigabrt);
1485 sigaddset(&sigset, SIGABRT);
1486 sigprocmask(SIG_BLOCK, &sigset, NULL);
1488 /* Ignored everywhere. When a client disconnects abnormally this signal
1489 * gets raised. It isn't needed though because client_thread() will check
1490 * for rcs even after the client disconnects. */
1491 signal(SIGPIPE, SIG_IGN);
1493 /* Can show a backtrace of the stack in the log. */
1494 signal(SIGSEGV, catchsig);
1496 #ifdef WITH_GNUTLS
1497 /* Needs to be done after the fork(). */
1498 if (!start_stop_tls(0)) {
1499 segv = 1;
1500 goto done;
1502 #endif
1504 pthread_mutex_init(&quit_mutex, NULL);
1505 pthread_cond_init(&quit_cond, NULL);
1506 log_write(_("%s started for user %s"), PACKAGE_STRING, get_username());
1507 #ifndef HAVE_DECL_SO_PEERCRED
1508 log_write(_("Peer credential checking is NOT supported on this OS."));
1509 #endif
1510 #ifdef WITH_GNUTLS
1511 if (config_get_boolean("global", "enable_tcp"))
1512 log_write(_("Listening on %s and TCP port %i"), *socketpath,
1513 config_get_integer("global", "tcp_port"));
1514 else
1515 log_write(_("Listening on %s"), *socketpath);
1516 #else
1517 log_write(_("Listening on %s"), *socketpath);
1518 #endif
1520 rc = create_thread(reload_rcfile_thread, NULL, &rcfile_tid, 0);
1521 if (rc) {
1522 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1523 pwmd_strerror(rc));
1524 goto done;
1527 rc = create_thread(cache_timer_thread, NULL, &cache_timeout_tid, 1);
1528 if (rc) {
1529 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1530 pwmd_strerror(rc));
1531 goto done;
1534 cancel_timeout_thread = 1;
1535 rc = create_thread(accept_thread, &sockfd, &accept_tid, 1);
1536 if (rc) {
1537 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1538 pwmd_strerror(rc));
1539 goto done;
1542 cancel_accept_thread = 1;
1543 sigdelset(&sigset, SIGUSR2);
1544 if (!setjmp(jmp))
1545 signal_loop(sigset);
1546 else
1547 segv = 1;
1549 done:
1551 * We're out of the main server loop. This happens when a signal was sent
1552 * to terminate the daemon. We'll wait for all clients to disconnect
1553 * before exiting but exit immediately if another termination signal is
1554 * sent.
1556 if (cancel_accept_thread)
1557 pthread_cancel(accept_tid);
1559 shutdown(sockfd, SHUT_RDWR);
1560 close(sockfd);
1561 unlink(*socketpath);
1562 xfree(*socketpath);
1563 *socketpath = NULL;
1564 MUTEX_LOCK(&cn_mutex);
1565 n = slist_length(cn_thread_list);
1566 MUTEX_UNLOCK(&cn_mutex);
1568 if (n && !segv) {
1569 pthread_t tid;
1571 rc = create_thread(waiting_for_exit, NULL, &tid, 1);
1572 if (!rc) {
1573 sigaddset(&sigset, SIGUSR2);
1574 if (signal_loop(sigset)) {
1575 log_write(_("Received second termination request. Exiting."));
1576 pthread_cancel(tid);
1579 else
1580 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1581 pwmd_strerror(rc));
1584 if (cancel_timeout_thread)
1585 pthread_cancel(cache_timeout_tid);
1587 MUTEX_LOCK(&cn_mutex);
1588 i = 0;
1589 n = slist_length(cn_thread_list);
1591 for (i = 0; i < n; i++) {
1592 struct client_thread_s *thd = slist_nth_data(cn_thread_list, i);
1594 if (thd->fd != -1) {
1595 close(thd->fd);
1596 thd->fd = -1;
1600 exiting = 1;
1601 MUTEX_UNLOCK(&cn_mutex);
1602 #ifdef WITH_GNUTLS
1603 start_stop_tls(1);
1604 #endif
1605 cache_deinit();
1606 deinit_commands();
1607 pthread_cond_destroy(&quit_cond);
1608 pthread_mutex_destroy(&quit_mutex);
1609 return segv ? EXIT_FAILURE : EXIT_SUCCESS;;
1612 static void startup_failure()
1614 log_write(_("Failed to add a file to the cache. Use --ignore to force startup. Exiting."));
1615 cache_clear(NULL);
1618 /* This is called from cache.c:clear_once(). See
1619 * command.c:clearcache_command() for details about lock checking.
1621 static gpg_error_t free_cache_data(file_cache_t *cache)
1623 gpg_error_t rc = GPG_ERR_NO_DATA;
1624 int i, t;
1625 struct client_thread_s *found = NULL;
1626 int self = 0;
1628 if (!cache->data)
1629 return 0;
1631 cache_lock();
1632 MUTEX_LOCK(&cn_mutex);
1633 pthread_cleanup_push(cleanup_mutex_cb, &cn_mutex);
1634 t = slist_length(cn_thread_list);
1636 for (i = 0; i < t; i++) {
1637 struct client_thread_s *thd = slist_nth_data(cn_thread_list, i);
1639 if (!thd->cl)
1640 continue;
1642 if (!memcmp(thd->cl->md5file, cache->filename,
1643 sizeof(cache->filename))) {
1644 if (pthread_equal(pthread_self(), thd->tid)) {
1645 found = thd;
1646 self = 1;
1647 continue;
1650 /* Continue trying to find a client who has the same file open and
1651 * also has a lock. */
1652 rc = cache_lock_mutex(thd->cl->ctx, thd->cl->md5file, -1, 0, -1);
1653 if (!rc) {
1654 self = 0;
1655 found = thd;
1656 break;
1661 if (self && (!rc || rc == GPG_ERR_NO_DATA))
1662 rc = cache_lock_mutex(found->cl->ctx, found->cl->md5file, -1, 0, -1);
1664 if (exiting || !rc || rc == GPG_ERR_NO_DATA) {
1665 free_cache_data_once(cache->data);
1666 cache->data = NULL;
1667 cache->defer_clear = 0;
1668 cache->timeout = -1;
1670 if (found)
1671 cache_unlock_mutex(found->cl->md5file, 0);
1673 rc = 0;
1676 if (rc)
1677 cache->defer_clear = 1;
1679 pthread_cleanup_pop(1);
1680 cache_unlock();
1681 return rc;
1684 static int convert_v2_datafile(const char *filename, const char *cipher,
1685 const char *keyfile, const char *keygrip, const char *sign_keygrip,
1686 int nopass, const char *outfile, const char *keyparam,
1687 unsigned long s2k_count, uint64_t iterations)
1689 gpg_error_t rc;
1690 void * data = NULL;
1691 size_t datalen;
1692 struct crypto_s *crypto = NULL;
1693 uint16_t ver;
1694 int algo;
1696 if (outfile[0] == '-' && outfile[1] == 0)
1697 outfile = NULL;
1699 log_write(_("Converting version 2 data file \"%s\" ..."), filename);
1700 if (access(filename, R_OK) == -1) {
1701 log_write("%s: %s", filename, pwmd_strerror(gpg_error_from_syserror()));
1702 return 0;
1705 if (keyfile) {
1706 log_write(_("Using passphrase file \"%s\" for decryption ..."),
1707 keyfile);
1708 if (access(keyfile, R_OK) == -1) {
1709 log_write("%s: %s", keyfile,
1710 pwmd_strerror(gpg_error_from_syserror()));
1711 return 0;
1715 rc = read_v2_datafile(filename, keyfile, &data, &datalen, &ver, &algo);
1716 if (rc) {
1717 log_write("ERR %i: %s", rc, pwmd_strerror(rc));
1718 return 0;
1721 if (cipher) {
1722 algo = cipher_string_to_gcrypt(cipher);
1723 if (algo == -1) {
1724 rc = GPG_ERR_CIPHER_ALGO;
1725 goto fail;
1729 if (ver < 0x212) {
1730 xmlDocPtr doc = parse_doc(data, datalen);
1732 if (!doc) {
1733 rc = GPG_ERR_BAD_DATA;
1734 goto fail;
1737 rc = convert_pre_212_elements(doc);
1738 gcry_free(data);
1739 data = NULL;
1740 if (!rc) {
1741 xmlDocDumpFormatMemory(doc, (xmlChar **)&data, (int *)&datalen, 0);
1742 if (!data)
1743 rc = GPG_ERR_ENOMEM;
1746 xmlFreeDoc(doc);
1747 if (rc)
1748 goto fail;
1751 rc = init_client_crypto(&crypto);
1752 if (!rc) {
1753 rc = set_pinentry_options(crypto->agent);
1754 if (!rc) {
1755 memcpy(&crypto->save.hdr, &crypto->hdr,
1756 sizeof(file_header_t));
1757 crypto->save.hdr.flags = set_cipher_flag(crypto->save.hdr.flags, algo);
1758 crypto->save.s2k_count = s2k_count;
1759 crypto->save.hdr.iterations = iterations;
1760 rc = export_common(crypto, keygrip, sign_keygrip, nopass, data,
1761 datalen, outfile, keyparam,
1762 no_passphrase_file ? NULL : keyfile);
1763 if (!rc)
1764 log_write(_("Output written to \"%s\"."), outfile);
1768 fail:
1769 if (ver < 0x212)
1770 xmlFree(data);
1771 else
1772 gcry_free(data);
1773 cleanup_crypto(&crypto);
1775 if (rc)
1776 log_write("ERR %i: %s", rc, pwmd_strerror(rc));
1777 return rc ? 0 : 1;
1780 static void usage(const char *pn, int status)
1782 FILE *fp = status == EXIT_FAILURE ? stderr : stdout;
1784 fprintf(fp, _(
1785 "Usage: %s [OPTIONS] [file1] [...]\n"
1786 " -f, --rcfile=filename load the specfied configuration file\n"
1787 " (~/.pwmd/config)\n"
1788 " --homedir alternate pwmd home directory (~/.pwmd)\n"
1789 " -n, --no-fork run as a foreground process\n"
1790 " -D, --disable-dump disable the LIST, XPATH and DUMP commands\n"
1791 " --ignore ignore file errors during startup\n"
1792 " --debug-level=keywords log protocol output (see manual for details)\n"
1793 " -o, --outfile=filename output file when importing or converting\n"
1794 " -C, --convert=filename convert a version 2 data file to version 3\n"
1795 " -I, --import=filename import a pwmd DTD formatted XML file)\n"
1796 " -k, --passphrase-file=file for use when importing or converting\n"
1797 " --no-passphrase-file prompt instead of using --passphrase-file when\n"
1798 " converting\n"
1799 " --no-passphrase when importing or converting\n"
1800 " --keygrip=hex public key to use when encrypting\n"
1801 " --sign-keygrip=hex private key to use when signing\n"
1802 " --keyparam=s-exp custom key parameters to use (RSA-2048)\n"
1803 " --cipher=string encryption cipher (aes256)\n"
1804 " --iterations=N cipher iteration count (N+1)\n"
1805 " --s2k-count=N hash iteration count (>65536, calibrated)\n"
1806 " --help this help text\n"
1807 " --version show version and compile time features\n"
1808 ), pn);
1809 exit(status);
1812 int main(int argc, char *argv[])
1814 int opt;
1815 struct sockaddr_un addr;
1816 char buf[PATH_MAX];
1817 char *socketpath = NULL, *socketdir, *socketname = NULL;
1818 char *socketarg = NULL;
1819 char *datadir = NULL;
1820 int x;
1821 char *p;
1822 char **cache_push = NULL;
1823 char *import = NULL, *keygrip = NULL, *sign_keygrip = NULL;
1824 char *keyparam = NULL;
1825 int estatus = EXIT_FAILURE;
1826 int sockfd;
1827 char *outfile = NULL;
1828 int do_unlink = 0;
1829 int secure = 0;
1830 int show_version = 0;
1831 int force = 0;
1832 int no_passphrase = 0;
1833 gpg_error_t rc;
1834 char *convertfile = NULL;
1835 char *cipher = NULL;
1836 char *keyfile = NULL;
1837 unsigned long s2k_count = 0;
1838 uint64_t iterations = 0;
1839 int exists;
1840 char *debug_level_opt = NULL;
1841 int optindex;
1842 /* Must maintain the same order as longopts[] */
1843 enum { OPT_VERSION, OPT_HELP, OPT_DEBUG_LEVEL, OPT_HOMEDIR, OPT_NO_FORK,
1844 OPT_DISABLE_DUMP, OPT_IGNORE, OPT_RCFILE, OPT_CONVERT,
1845 OPT_PASSPHRASE_FILE, OPT_IMPORT, OPT_OUTFILE, OPT_NO_PASSPHRASE_FILE,
1846 OPT_KEYGRIP, OPT_SIGN_KEYGRIP, OPT_KEYPARAM, OPT_CIPHER,
1847 OPT_ITERATIONS, OPT_S2K_COUNT, OPT_NO_PASSPHRASE
1849 const char *optstring = "nf:C:k:I:o:";
1850 const struct option longopts[] = {
1851 {"version", no_argument, 0, 0 },
1852 {"help", no_argument, 0, 0 },
1853 {"debug-level", required_argument, 0, 0 },
1854 {"homedir", required_argument, 0, 0 },
1855 {"no-fork", no_argument, 0, 'n' },
1856 {"disable_dump", no_argument, 0, 0 },
1857 {"ignore", no_argument, 0, 0 },
1858 {"rcfile", required_argument, 0, 'f' },
1859 {"convert", required_argument, 0, 'C' },
1860 {"passphrase-file", required_argument, 0, 'k' },
1861 {"import", required_argument, 0, 'I' },
1862 {"outfile", required_argument, 0, 'o' },
1863 {"no-passphrase-file", no_argument, 0, 0 },
1864 {"keygrip", required_argument, 0, 0 },
1865 {"sign-keygrip", required_argument, 0, 0 },
1866 {"keyparam", required_argument, 0, 0 },
1867 {"cipher", required_argument, 0, 0 },
1868 {"cipher-iterations", required_argument, 0, 0 },
1869 {"s2k-count", required_argument, 0, 0 },
1870 {"no-passphrase", no_argument, 0, 0 },
1871 {0, 0, 0, 0 }
1874 #ifndef DEBUG
1875 #ifdef HAVE_SETRLIMIT
1876 struct rlimit rl;
1878 rl.rlim_cur = rl.rlim_max = 0;
1880 if (setrlimit(RLIMIT_CORE, &rl) != 0)
1881 err(EXIT_FAILURE, "setrlimit()");
1882 #endif
1883 #endif
1885 #ifdef ENABLE_NLS
1886 setlocale(LC_ALL, "");
1887 bindtextdomain("pwmd", LOCALEDIR);
1888 textdomain("pwmd");
1889 #endif
1891 #ifndef MEM_DEBUG
1892 xmem_init();
1893 #endif
1894 gpg_err_init();
1896 if (setup_crypto())
1897 exit(EXIT_FAILURE);
1899 #ifdef WITH_GNUTLS
1900 gnutls_global_set_mem_functions(xmalloc, xmalloc, secure_mem_check,
1901 xrealloc, xfree);
1902 gnutls_global_init();
1903 gnutls_global_set_log_function(tls_log);
1904 gnutls_global_set_log_level(1);
1905 tls_fd = -1;
1906 tls6_fd = -1;
1907 #endif
1908 xmlMemSetup(xfree, xmalloc, xrealloc, str_dup);
1909 xmlInitMemory();
1910 xmlInitGlobals();
1911 xmlInitParser();
1912 xmlXPathInit();
1913 cmdline = 1;
1915 while ((opt = getopt_long(argc, argv, optstring, longopts, &optindex)) != -1) {
1916 switch (opt) {
1917 case 'I':
1918 import = optarg;
1919 break;
1920 case 'C':
1921 convertfile = optarg;
1922 break;
1923 case 'k':
1924 keyfile = optarg;
1925 break;
1926 case 'o':
1927 outfile = optarg;
1928 break;
1929 case 'D':
1930 secure = 1;
1931 break;
1932 case 'n':
1933 nofork = 1;
1934 break;
1935 case 'f':
1936 rcfile = str_dup(optarg);
1937 break;
1938 default:
1939 usage(argv[0], EXIT_FAILURE);
1940 break;
1941 case 0:
1942 switch (optindex) {
1943 case OPT_VERSION:
1944 show_version = 1;
1945 break;
1946 case OPT_HELP:
1947 usage(argv[0], 0);
1948 break;
1949 case OPT_DEBUG_LEVEL:
1950 debug_level_opt = optarg;
1951 break;
1952 case OPT_HOMEDIR:
1953 homedir = str_dup(optarg);
1954 break;
1955 case OPT_NO_FORK:
1956 nofork = 1;
1957 break;
1958 case OPT_DISABLE_DUMP:
1959 secure = 1;
1960 break;
1961 case OPT_IGNORE:
1962 force = 1;
1963 break;
1964 case OPT_RCFILE:
1965 rcfile = str_dup(optarg);
1966 break;
1967 case OPT_CONVERT:
1968 convertfile = optarg;
1969 break;
1970 case OPT_PASSPHRASE_FILE:
1971 keyfile = optarg;
1972 break;
1973 case OPT_IMPORT:
1974 import = optarg;
1975 break;
1976 case OPT_OUTFILE:
1977 outfile = optarg;
1978 break;
1979 case OPT_NO_PASSPHRASE_FILE:
1980 no_passphrase_file = 1;
1981 break;
1982 case OPT_KEYGRIP:
1983 keygrip = optarg;
1984 break;
1985 case OPT_SIGN_KEYGRIP:
1986 sign_keygrip = optarg;
1987 break;
1988 case OPT_KEYPARAM:
1989 keyparam = optarg;
1990 break;
1991 case OPT_CIPHER:
1992 cipher = optarg;
1993 break;
1994 case OPT_ITERATIONS:
1995 iterations = strtoull(optarg, NULL, 10);
1996 break;
1997 case OPT_S2K_COUNT:
1998 s2k_count = strtoul(optarg, NULL, 10);
1999 break;
2000 case OPT_NO_PASSPHRASE:
2001 no_passphrase = 1;
2002 break;
2003 default:
2004 usage(argv[0], 1);
2009 if (show_version) {
2010 printf(_("%s\n\n"
2011 "Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012\n"
2012 "%s\n"
2013 "Released under the terms of the GPL v2. Use at your own risk.\n\n"
2014 "Compile time features:\n%s"), PACKAGE_STRING, PACKAGE_BUGREPORT,
2015 #ifdef WITH_GNUTLS
2016 "+WITH_GNUTLS\n"
2017 #else
2018 "-WITH_GNUTLS\n"
2019 #endif
2020 #ifdef WITH_LIBACL
2021 "+WITH_LIBACL\n"
2022 #else
2023 "-WITH_LIBACL\n"
2024 #endif
2025 #ifdef DEBUG
2026 "+DEBUG\n"
2027 #else
2028 "-DEBUG\n"
2029 #endif
2030 #ifdef MEM_DEBUG
2031 "+MEM_DEBUG\n"
2032 #else
2033 "-MEM_DEBUG\n"
2034 #endif
2035 #ifdef MUTEX_DEBUG
2036 "+MUTEX_DEBUG\n"
2037 #else
2038 "-MUTEX_DEBUG\n"
2039 #endif
2041 exit(EXIT_SUCCESS);
2044 if (!homedir)
2045 homedir = str_asprintf("%s/.pwmd", get_home_dir());
2047 if (mkdir(homedir, 0700) == -1 && errno != EEXIST)
2048 err(EXIT_FAILURE, "%s", homedir);
2050 snprintf(buf, sizeof(buf), "%s/data", homedir);
2051 if (mkdir(buf, 0700) == -1 && errno != EEXIST)
2052 err(EXIT_FAILURE, "%s", buf);
2054 datadir = str_dup(buf);
2055 pthread_mutexattr_t attr;
2056 pthread_mutexattr_init(&attr);
2057 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
2058 pthread_mutex_init(&rcfile_mutex, &attr);
2059 pthread_cond_init(&rcfile_cond, NULL);
2060 pthread_mutex_init(&cn_mutex, &attr);
2061 pthread_mutexattr_destroy(&attr);
2062 pthread_key_create(&last_error_key, free_key);
2064 if (!rcfile)
2065 rcfile = str_asprintf("%s/config", homedir);
2067 global_config = config_parse(rcfile);
2068 if (!global_config)
2069 exit(EXIT_FAILURE);
2071 setup_logging();
2073 if (debug_level_opt)
2074 debug_level = str_split(debug_level_opt, ",", 0);
2076 x = config_get_int_param(global_config, "global", "priority", &exists);
2077 if (exists) {
2078 errno = 0;
2079 if (setpriority(PRIO_PROCESS, 0, x) == -1) {
2080 log_write("setpriority(): %s", pwmd_strerror(gpg_error_from_syserror()));
2081 goto do_exit;
2084 #ifdef HAVE_MLOCKALL
2085 if (disable_mlock == 0 && mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
2086 log_write("mlockall(): %s", pwmd_strerror(gpg_error_from_syserror()));
2087 goto do_exit;
2089 #endif
2091 rc = cache_init(free_cache_data);
2092 if (rc) {
2093 log_write("pwmd: gpg-agent: ERR %i: %s", rc,
2094 gpg_err_code(rc) == GPG_ERR_UNKNOWN_VERSION
2095 ? _("incompatible version: 2.1.0 or later required")
2096 : pwmd_strerror(rc));
2097 goto do_exit;
2100 if (s2k_count == 0)
2101 s2k_count = config_get_ulong(NULL, "s2k_count");
2103 if (convertfile) {
2104 if (!outfile)
2105 usage(argv[0], EXIT_FAILURE);
2107 estatus = convert_v2_datafile(convertfile, cipher, keyfile, keygrip,
2108 sign_keygrip, no_passphrase, outfile,
2109 keyparam, s2k_count, iterations);
2110 config_free(global_config);
2111 xfree(rcfile);
2112 exit(!estatus);
2115 if (import) {
2116 if (!outfile)
2117 usage(argv[0], EXIT_FAILURE);
2119 if (outfile[0] == '-' && outfile[1] == 0)
2120 outfile = NULL;
2122 estatus = xml_import(import, outfile, keygrip, sign_keygrip, keyfile,
2123 no_passphrase, cipher, keyparam, s2k_count, iterations);
2124 config_free(global_config);
2125 xfree(rcfile);
2126 exit(!estatus);
2129 p = config_get_string("global", "socket_path");
2130 if (!p)
2131 p = str_asprintf("%s/socket", homedir);
2133 socketarg = expand_homedir(p);
2134 xfree(p);
2136 if (!secure)
2137 disable_list_and_dump = config_get_boolean("global",
2138 "disable_list_and_dump");
2139 else
2140 disable_list_and_dump = secure;
2142 cache_push = config_get_list("global", "cache_push");
2144 while (optind < argc) {
2145 if (strv_printf(&cache_push, "%s", argv[optind++]) == 0)
2146 errx(EXIT_FAILURE, "%s", pwmd_strerror(GPG_ERR_ENOMEM));
2149 if (strchr(socketarg, '/') == NULL) {
2150 socketdir = getcwd(buf, sizeof(buf));
2151 socketname = str_dup(socketarg);
2152 socketpath = str_asprintf("%s/%s", socketdir, socketname);
2154 else {
2155 socketname = str_dup(strrchr(socketarg, '/'));
2156 socketname++;
2157 socketarg[strlen(socketarg) - strlen(socketname) -1] = 0;
2158 socketdir = str_dup(socketarg);
2159 socketpath = str_asprintf("%s/%s", socketdir, socketname);
2162 if (chdir(datadir)) {
2163 log_write("%s: %s", datadir, pwmd_strerror(gpg_error_from_syserror()));
2164 unlink(socketpath);
2165 goto do_exit;
2169 * Set the cache entry for a file. Prompts for the password.
2171 if (cache_push) {
2172 struct crypto_s *crypto;
2173 gpg_error_t rc = init_client_crypto(&crypto);
2175 if (rc) {
2176 estatus = EXIT_FAILURE;
2177 goto do_exit;
2180 rc = set_pinentry_options(crypto->agent);
2181 if (rc) {
2182 estatus = EXIT_FAILURE;
2183 goto do_exit;
2186 for (opt = 0; cache_push[opt]; opt++) {
2187 if (!do_cache_push(cache_push[opt], crypto) && !force) {
2188 strv_free(cache_push);
2189 startup_failure();
2190 estatus = EXIT_FAILURE;
2191 cleanup_crypto(&crypto);
2192 goto do_exit;
2195 cleanup_crypto_stage1(crypto);
2198 (void)kill_scd(crypto->agent);
2199 cleanup_crypto(&crypto);
2200 strv_free(cache_push);
2201 log_write(!nofork ? _("Done. Daemonizing...") : _("Done. Waiting for connections..."));
2204 config_clear_keyss();
2207 * bind() doesn't like the full pathname of the socket or any non alphanum
2208 * characters so change to the directory where the socket is wanted then
2209 * create it then change to datadir.
2211 if (chdir(socketdir)) {
2212 log_write("%s: %s", socketdir, pwmd_strerror(gpg_error_from_syserror()));
2213 goto do_exit;
2216 xfree(socketdir);
2218 if ((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
2219 log_write("socket(): %s", pwmd_strerror(gpg_error_from_syserror()));
2220 goto do_exit;
2223 addr.sun_family = AF_UNIX;
2224 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socketname);
2226 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
2227 log_write("bind(): %s", pwmd_strerror(gpg_error_from_syserror()));
2229 if (errno == EADDRINUSE)
2230 log_write(_("Either there is another pwmd running or '%s' is a \n"
2231 "stale socket. Please remove it manually."), socketpath);
2233 goto do_exit;
2236 do_unlink = 1;
2238 char *t = config_get_string("global", "socket_perms");
2239 mode_t mode;
2240 mode_t mask;
2242 if (t) {
2243 mode = strtol(t, NULL, 8);
2244 mask = umask(0);
2245 xfree(t);
2247 if (chmod(socketname, mode) == -1) {
2248 log_write("%s: %s", socketname,
2249 pwmd_strerror(gpg_error_from_syserror()));
2250 close(sockfd);
2251 unlink(socketpath);
2252 umask(mask);
2253 goto do_exit;
2256 umask(mask);
2260 xfree(--socketname);
2262 if (chdir(datadir)) {
2263 log_write("%s: %s", datadir, pwmd_strerror(gpg_error_from_syserror()));
2264 close(sockfd);
2265 unlink(socketpath);
2266 goto do_exit;
2269 xfree(datadir);
2271 if (listen(sockfd, 0) == -1) {
2272 log_write("listen(): %s", pwmd_strerror(gpg_error_from_syserror()));
2273 goto do_exit;
2276 cmdline = 0;
2278 if (!nofork) {
2279 switch (fork()) {
2280 case -1:
2281 log_write("fork(): %s", pwmd_strerror(gpg_error_from_syserror()));
2282 goto do_exit;
2283 case 0:
2284 close(0);
2285 close(1);
2286 close(2);
2287 setsid();
2288 break;
2289 default:
2290 _exit(EXIT_SUCCESS);
2294 pthread_key_create(&thread_name_key, free_key);
2295 pthread_setspecific(thread_name_key, str_dup("main"));
2296 estatus = server_loop(sockfd, &socketpath);
2298 do_exit:
2299 if (socketpath && do_unlink) {
2300 unlink(socketpath);
2301 xfree(socketpath);
2304 xfree(socketarg);
2305 #ifdef WITH_GNUTLS
2306 gnutls_global_deinit();
2307 #endif
2308 pthread_cancel(rcfile_tid);
2309 pthread_join(rcfile_tid, NULL);
2310 pthread_cond_destroy(&rcfile_cond);
2311 pthread_mutex_destroy(&rcfile_mutex);
2313 if (global_config)
2314 config_free(global_config);
2316 xfree(rcfile);
2317 xfree(home_directory);
2318 xfree(homedir);
2319 xmlCleanupParser();
2320 xmlCleanupGlobals();
2322 if (estatus == EXIT_SUCCESS)
2323 log_write(_("pwmd exiting normally"));
2325 closelog();
2326 #if defined(DEBUG) && !defined(MEM_DEBUG)
2327 xdump();
2328 #endif
2329 exit(estatus);