Move libxml2 linker flags to the end of LDFLAGS.
[pwmd.git] / src / pwmd.c
blobd1f6f789a824ceb7c67335de19f1b42be93d1a46
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 int r = 1;
1216 if ((ipv6 && p->ai_family != AF_INET6)
1217 || (!ipv6 && p->ai_family != AF_INET))
1218 continue;
1220 if ((*fd = socket(p->ai_family, p->ai_socktype,
1221 p->ai_protocol)) == -1) {
1222 log_write("socket(): %s", strerror(errno));
1223 continue;
1226 if (setsockopt(*fd, SOL_SOCKET, SO_REUSEADDR, &r,
1227 sizeof(int)) == -1) {
1228 log_write("setsockopt(): %s", strerror(errno));
1229 freeaddrinfo(servinfo);
1230 goto fail;
1233 if (bind(*fd, p->ai_addr, p->ai_addrlen) == -1) {
1234 close(*fd);
1235 log_write("bind(): %s", strerror(errno));
1236 continue;
1239 n++;
1240 break;
1243 freeaddrinfo(servinfo);
1245 if (!n) {
1246 log_write("%s", _("could not bind"));
1247 goto fail;
1250 #ifdef HAVE_DECL_SO_BINDTODEVICE
1251 char *tmp = config_get_string("global", "tcp_interface");
1252 if (tmp && setsockopt(*fd, SOL_SOCKET, SO_BINDTODEVICE, tmp, 1) == -1) {
1253 log_write("setsockopt(): %s", strerror(errno));
1254 xfree(tmp);
1255 goto fail;
1258 xfree(tmp);
1259 #endif
1261 if (x509_cred == NULL) {
1262 rc = tls_init_params();
1263 if (rc)
1264 goto fail;
1267 if (listen(*fd, 0) == -1) {
1268 log_write("listen(): %s", strerror(errno));
1269 goto fail;
1272 if (ipv6)
1273 rc = create_thread(tcp_accept_thread, fd, &tls6_tid, 0);
1274 else
1275 rc = create_thread(tcp_accept_thread, fd, &tls_tid, 0);
1277 if (rc) {
1278 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1279 pwmd_strerror(rc));
1280 goto fail;
1283 return 1;
1285 fail:
1286 start_stop_tls_with_protocol(0, 1);
1287 if (tls_fd != -1)
1288 close(tls_fd);
1290 if (tls6_fd != -1)
1291 close(tls6_fd);
1293 tls_fd = -1;
1294 tls6_fd = -1;
1295 return 0;
1298 static int start_stop_tls(int term)
1300 char *s = config_get_string("global", "tcp_bind");
1301 int b;
1303 if (!s)
1304 return 0;
1306 if (!strcmp(s, "any")) {
1307 b = start_stop_tls_with_protocol(0, term);
1308 if (b)
1309 b = start_stop_tls_with_protocol(1, term);
1311 else if (!strcmp(s, "ipv4"))
1312 b = start_stop_tls_with_protocol(0, term);
1313 else if (!strcmp(s, "ipv6"))
1314 b = start_stop_tls_with_protocol(1, term);
1315 else
1316 b = 0;
1318 xfree(s);
1319 return b;
1321 #endif
1323 static void *accept_thread(void *arg)
1325 int sockfd = *(int *)arg;
1327 #ifdef HAVE_PR_SET_NAME
1328 prctl(PR_SET_NAME, "accept");
1329 #endif
1330 pthread_setspecific(thread_name_key, str_dup(__FUNCTION__));
1332 for (;;) {
1333 socklen_t slen = sizeof(struct sockaddr_un);
1334 struct sockaddr_un raddr;
1335 int fd;
1337 fd = accept(sockfd, (struct sockaddr *)&raddr, &slen);
1338 if (fd == -1) {
1339 if (errno == EMFILE || errno == ENFILE)
1340 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
1341 else if (errno != EAGAIN) {
1342 if (!quit) // probably EBADF
1343 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
1345 break;
1347 continue;
1350 (void)init_client_thread(fd, NULL);
1353 /* Just in case accept() failed for some reason other than EBADF */
1354 quit = 1;
1355 return NULL;
1358 static void *cache_timer_thread(void *arg)
1360 #ifdef HAVE_PR_SET_NAME
1361 prctl(PR_SET_NAME, "cache timer");
1362 #endif
1363 pthread_setspecific(thread_name_key, str_dup(__FUNCTION__));
1365 for (;;) {
1366 sleep(1);
1367 cache_adjust_timeout();
1370 return NULL;
1373 static void catch_sigabrt(int sig)
1375 cache_clear(NULL);
1376 #ifndef MEM_DEBUG
1377 xpanic();
1378 #endif
1381 static int signal_loop(sigset_t sigset)
1383 int done = 0;
1384 int siint = 0;
1386 do {
1387 int sig = sigwaitinfo(&sigset, NULL);
1389 if (sig == -1) {
1390 if (errno != EAGAIN)
1391 log_write("sigwaitinfo(): %s", strerror(errno));
1392 continue;
1395 if (sig != SIGUSR2)
1396 log_write(_("caught signal %i (%s)"), sig, strsignal(sig));
1398 switch (sig) {
1399 case SIGHUP:
1400 pthread_cond_signal(&rcfile_cond);
1401 break;
1402 case SIGABRT:
1403 // not really handled here.
1404 catch_sigabrt(SIGABRT);
1405 break;
1406 case SIGUSR1:
1407 log_write(_("clearing file cache"));
1408 cache_clear(NULL);
1409 send_status_all(STATUS_CACHE, NULL);
1410 break;
1411 case SIGUSR2:
1412 done = 1;
1413 break;
1414 default:
1415 siint = 1;
1416 done = 1;
1417 break;
1419 } while (!done);
1421 return siint;
1424 static void catchsig(int sig)
1426 log_write("Caught SIGSEGV. Exiting.");
1427 #ifdef HAVE_BACKTRACE
1428 BACKTRACE(__FUNCTION__);
1429 #endif
1430 longjmp(jmp, 1);
1433 static void *waiting_for_exit(void *arg)
1435 #ifdef HAVE_PR_SET_NAME
1436 prctl(PR_SET_NAME, "exiting");
1437 #endif
1438 pthread_setspecific(thread_name_key, str_dup(__FUNCTION__));
1439 log_write(_("waiting for all clients to disconnect"));
1440 MUTEX_LOCK(&quit_mutex);
1441 pthread_cleanup_push(cleanup_mutex_cb, &quit_mutex);
1443 for (;;) {
1444 MUTEX_LOCK(&cn_mutex);
1445 int n = slist_length(cn_thread_list);
1446 MUTEX_UNLOCK(&cn_mutex);
1447 if (!n)
1448 break;
1450 log_write(_("%i clients remain"), n);
1451 pthread_cond_wait(&quit_cond, &quit_mutex);
1454 pthread_cleanup_pop(1);
1455 kill(getpid(), SIGUSR2);
1456 return NULL;
1459 static int server_loop(int sockfd, char **socketpath)
1461 pthread_t accept_tid;
1462 pthread_t cache_timeout_tid;
1463 int cancel_timeout_thread = 0, cancel_accept_thread = 0;
1464 int n, i;
1465 sigset_t sigset;
1466 int segv = 0;
1467 gpg_error_t rc;
1469 init_commands();
1470 sigemptyset(&sigset);
1472 /* Termination */
1473 sigaddset(&sigset, SIGTERM);
1474 sigaddset(&sigset, SIGINT);
1476 /* Clears the file cache. */
1477 sigaddset(&sigset, SIGUSR1);
1479 /* Configuration file reloading. */
1480 sigaddset(&sigset, SIGHUP);
1482 /* For exiting cleanly. */
1483 sigaddset(&sigset, SIGUSR2);
1485 /* Clears the cache and exits when something bad happens. */
1486 signal(SIGABRT, catch_sigabrt);
1487 sigaddset(&sigset, SIGABRT);
1488 sigprocmask(SIG_BLOCK, &sigset, NULL);
1490 /* Ignored everywhere. When a client disconnects abnormally this signal
1491 * gets raised. It isn't needed though because client_thread() will check
1492 * for rcs even after the client disconnects. */
1493 signal(SIGPIPE, SIG_IGN);
1495 /* Can show a backtrace of the stack in the log. */
1496 signal(SIGSEGV, catchsig);
1498 #ifdef WITH_GNUTLS
1499 /* Needs to be done after the fork(). */
1500 if (!start_stop_tls(0)) {
1501 segv = 1;
1502 goto done;
1504 #endif
1506 pthread_mutex_init(&quit_mutex, NULL);
1507 pthread_cond_init(&quit_cond, NULL);
1508 log_write(_("%s started for user %s"), PACKAGE_STRING, get_username());
1509 #ifndef HAVE_DECL_SO_PEERCRED
1510 log_write(_("Peer credential checking is NOT supported on this OS."));
1511 #endif
1512 #ifdef WITH_GNUTLS
1513 if (config_get_boolean("global", "enable_tcp"))
1514 log_write(_("Listening on %s and TCP port %i"), *socketpath,
1515 config_get_integer("global", "tcp_port"));
1516 else
1517 log_write(_("Listening on %s"), *socketpath);
1518 #else
1519 log_write(_("Listening on %s"), *socketpath);
1520 #endif
1522 rc = create_thread(reload_rcfile_thread, NULL, &rcfile_tid, 0);
1523 if (rc) {
1524 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1525 pwmd_strerror(rc));
1526 goto done;
1529 rc = create_thread(cache_timer_thread, NULL, &cache_timeout_tid, 1);
1530 if (rc) {
1531 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1532 pwmd_strerror(rc));
1533 goto done;
1536 cancel_timeout_thread = 1;
1537 rc = create_thread(accept_thread, &sockfd, &accept_tid, 1);
1538 if (rc) {
1539 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1540 pwmd_strerror(rc));
1541 goto done;
1544 cancel_accept_thread = 1;
1545 sigdelset(&sigset, SIGUSR2);
1546 if (!setjmp(jmp))
1547 signal_loop(sigset);
1548 else
1549 segv = 1;
1551 done:
1553 * We're out of the main server loop. This happens when a signal was sent
1554 * to terminate the daemon. We'll wait for all clients to disconnect
1555 * before exiting but exit immediately if another termination signal is
1556 * sent.
1558 if (cancel_accept_thread)
1559 pthread_cancel(accept_tid);
1561 shutdown(sockfd, SHUT_RDWR);
1562 close(sockfd);
1563 unlink(*socketpath);
1564 xfree(*socketpath);
1565 *socketpath = NULL;
1566 MUTEX_LOCK(&cn_mutex);
1567 n = slist_length(cn_thread_list);
1568 MUTEX_UNLOCK(&cn_mutex);
1570 if (n && !segv) {
1571 pthread_t tid;
1573 rc = create_thread(waiting_for_exit, NULL, &tid, 1);
1574 if (!rc) {
1575 sigaddset(&sigset, SIGUSR2);
1576 if (signal_loop(sigset)) {
1577 log_write(_("Received second termination request. Exiting."));
1578 pthread_cancel(tid);
1581 else
1582 log_write("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1583 pwmd_strerror(rc));
1586 if (cancel_timeout_thread)
1587 pthread_cancel(cache_timeout_tid);
1589 MUTEX_LOCK(&cn_mutex);
1590 i = 0;
1591 n = slist_length(cn_thread_list);
1593 for (i = 0; i < n; i++) {
1594 struct client_thread_s *thd = slist_nth_data(cn_thread_list, i);
1596 if (thd->fd != -1) {
1597 close(thd->fd);
1598 thd->fd = -1;
1602 exiting = 1;
1603 MUTEX_UNLOCK(&cn_mutex);
1604 #ifdef WITH_GNUTLS
1605 start_stop_tls(1);
1606 #endif
1607 cache_deinit();
1608 deinit_commands();
1609 pthread_cond_destroy(&quit_cond);
1610 pthread_mutex_destroy(&quit_mutex);
1611 return segv ? EXIT_FAILURE : EXIT_SUCCESS;;
1614 static void startup_failure()
1616 log_write(_("Failed to add a file to the cache. Use --ignore to force startup. Exiting."));
1617 cache_clear(NULL);
1620 /* This is called from cache.c:clear_once(). See
1621 * command.c:clearcache_command() for details about lock checking.
1623 static gpg_error_t free_cache_data(file_cache_t *cache)
1625 gpg_error_t rc = GPG_ERR_NO_DATA;
1626 int i, t;
1627 struct client_thread_s *found = NULL;
1628 int self = 0;
1630 if (!cache->data)
1631 return 0;
1633 cache_lock();
1634 MUTEX_LOCK(&cn_mutex);
1635 pthread_cleanup_push(cleanup_mutex_cb, &cn_mutex);
1636 t = slist_length(cn_thread_list);
1638 for (i = 0; i < t; i++) {
1639 struct client_thread_s *thd = slist_nth_data(cn_thread_list, i);
1641 if (!thd->cl)
1642 continue;
1644 if (!memcmp(thd->cl->md5file, cache->filename,
1645 sizeof(cache->filename))) {
1646 if (pthread_equal(pthread_self(), thd->tid)) {
1647 found = thd;
1648 self = 1;
1649 continue;
1652 /* Continue trying to find a client who has the same file open and
1653 * also has a lock. */
1654 rc = cache_lock_mutex(thd->cl->ctx, thd->cl->md5file, -1, 0, -1);
1655 if (!rc) {
1656 self = 0;
1657 found = thd;
1658 break;
1663 if (self && (!rc || rc == GPG_ERR_NO_DATA))
1664 rc = cache_lock_mutex(found->cl->ctx, found->cl->md5file, -1, 0, -1);
1666 if (exiting || !rc || rc == GPG_ERR_NO_DATA) {
1667 free_cache_data_once(cache->data);
1668 cache->data = NULL;
1669 cache->defer_clear = 0;
1670 cache->timeout = -1;
1672 if (found)
1673 cache_unlock_mutex(found->cl->md5file, 0);
1675 rc = 0;
1678 if (rc)
1679 cache->defer_clear = 1;
1681 pthread_cleanup_pop(1);
1682 cache_unlock();
1683 return rc;
1686 static int convert_v2_datafile(const char *filename, const char *cipher,
1687 const char *keyfile, const char *keygrip, const char *sign_keygrip,
1688 int nopass, const char *outfile, const char *keyparam,
1689 unsigned long s2k_count, uint64_t iterations)
1691 gpg_error_t rc;
1692 void * data = NULL;
1693 size_t datalen;
1694 struct crypto_s *crypto = NULL;
1695 uint16_t ver;
1696 int algo;
1698 if (outfile[0] == '-' && outfile[1] == 0)
1699 outfile = NULL;
1701 log_write(_("Converting version 2 data file \"%s\" ..."), filename);
1702 if (access(filename, R_OK) == -1) {
1703 log_write("%s: %s", filename, pwmd_strerror(gpg_error_from_syserror()));
1704 return 0;
1707 if (keyfile) {
1708 log_write(_("Using passphrase file \"%s\" for decryption ..."),
1709 keyfile);
1710 if (access(keyfile, R_OK) == -1) {
1711 log_write("%s: %s", keyfile,
1712 pwmd_strerror(gpg_error_from_syserror()));
1713 return 0;
1717 rc = read_v2_datafile(filename, keyfile, &data, &datalen, &ver, &algo);
1718 if (rc) {
1719 log_write("ERR %i: %s", rc, pwmd_strerror(rc));
1720 return 0;
1723 if (cipher) {
1724 algo = cipher_string_to_gcrypt(cipher);
1725 if (algo == -1) {
1726 rc = GPG_ERR_CIPHER_ALGO;
1727 goto fail;
1731 if (ver < 0x212) {
1732 xmlDocPtr doc = parse_doc(data, datalen);
1734 if (!doc) {
1735 rc = GPG_ERR_BAD_DATA;
1736 goto fail;
1739 rc = convert_pre_212_elements(doc);
1740 gcry_free(data);
1741 data = NULL;
1742 if (!rc) {
1743 xmlDocDumpFormatMemory(doc, (xmlChar **)&data, (int *)&datalen, 0);
1744 if (!data)
1745 rc = GPG_ERR_ENOMEM;
1748 xmlFreeDoc(doc);
1749 if (rc)
1750 goto fail;
1753 rc = init_client_crypto(&crypto);
1754 if (!rc) {
1755 rc = set_pinentry_options(crypto->agent);
1756 if (!rc) {
1757 memcpy(&crypto->save.hdr, &crypto->hdr,
1758 sizeof(file_header_t));
1759 crypto->save.hdr.flags = set_cipher_flag(crypto->save.hdr.flags, algo);
1760 crypto->save.s2k_count = s2k_count;
1761 crypto->save.hdr.iterations = iterations;
1762 rc = export_common(crypto, keygrip, sign_keygrip, nopass, data,
1763 datalen, outfile, keyparam,
1764 no_passphrase_file ? NULL : keyfile);
1765 if (!rc)
1766 log_write(_("Output written to \"%s\"."), outfile);
1770 fail:
1771 if (ver < 0x212)
1772 xmlFree(data);
1773 else
1774 gcry_free(data);
1775 cleanup_crypto(&crypto);
1777 if (rc)
1778 log_write("ERR %i: %s", rc, pwmd_strerror(rc));
1779 return rc ? 0 : 1;
1782 static void usage(const char *pn, int status)
1784 FILE *fp = status == EXIT_FAILURE ? stderr : stdout;
1786 fprintf(fp, _(
1787 "Usage: %s [OPTIONS] [file1] [...]\n"
1788 " -f, --rcfile=filename load the specfied configuration file\n"
1789 " (~/.pwmd/config)\n"
1790 " --homedir alternate pwmd home directory (~/.pwmd)\n"
1791 " -n, --no-fork run as a foreground process\n"
1792 " -D, --disable-dump disable the LIST, XPATH and DUMP commands\n"
1793 " --ignore ignore file errors during startup\n"
1794 " --debug-level=keywords log protocol output (see manual for details)\n"
1795 " -o, --outfile=filename output file when importing or converting\n"
1796 " -C, --convert=filename convert a version 2 data file to version 3\n"
1797 " -I, --import=filename import a pwmd DTD formatted XML file)\n"
1798 " -k, --passphrase-file=file for use when importing or converting\n"
1799 " --no-passphrase-file prompt instead of using --passphrase-file when\n"
1800 " converting\n"
1801 " --no-passphrase when importing or converting\n"
1802 " --keygrip=hex public key to use when encrypting\n"
1803 " --sign-keygrip=hex private key to use when signing\n"
1804 " --keyparam=s-exp custom key parameters to use (RSA-2048)\n"
1805 " --cipher=string encryption cipher (aes256)\n"
1806 " --iterations=N cipher iteration count (N+1)\n"
1807 " --s2k-count=N hash iteration count (>65536, calibrated)\n"
1808 " --help this help text\n"
1809 " --version show version and compile time features\n"
1810 ), pn);
1811 exit(status);
1814 int main(int argc, char *argv[])
1816 int opt;
1817 struct sockaddr_un addr;
1818 char buf[PATH_MAX];
1819 char *socketpath = NULL, *socketdir, *socketname = NULL;
1820 char *socketarg = NULL;
1821 char *datadir = NULL;
1822 int x;
1823 char *p;
1824 char **cache_push = NULL;
1825 char *import = NULL, *keygrip = NULL, *sign_keygrip = NULL;
1826 char *keyparam = NULL;
1827 int estatus = EXIT_FAILURE;
1828 int sockfd;
1829 char *outfile = NULL;
1830 int do_unlink = 0;
1831 int secure = 0;
1832 int show_version = 0;
1833 int force = 0;
1834 int no_passphrase = 0;
1835 gpg_error_t rc;
1836 char *convertfile = NULL;
1837 char *cipher = NULL;
1838 char *keyfile = NULL;
1839 unsigned long s2k_count = 0;
1840 uint64_t iterations = 0;
1841 int exists;
1842 char *debug_level_opt = NULL;
1843 int optindex;
1844 /* Must maintain the same order as longopts[] */
1845 enum { OPT_VERSION, OPT_HELP, OPT_DEBUG_LEVEL, OPT_HOMEDIR, OPT_NO_FORK,
1846 OPT_DISABLE_DUMP, OPT_IGNORE, OPT_RCFILE, OPT_CONVERT,
1847 OPT_PASSPHRASE_FILE, OPT_IMPORT, OPT_OUTFILE, OPT_NO_PASSPHRASE_FILE,
1848 OPT_KEYGRIP, OPT_SIGN_KEYGRIP, OPT_KEYPARAM, OPT_CIPHER,
1849 OPT_ITERATIONS, OPT_S2K_COUNT, OPT_NO_PASSPHRASE
1851 const char *optstring = "nf:C:k:I:o:";
1852 const struct option longopts[] = {
1853 {"version", no_argument, 0, 0 },
1854 {"help", no_argument, 0, 0 },
1855 {"debug-level", required_argument, 0, 0 },
1856 {"homedir", required_argument, 0, 0 },
1857 {"no-fork", no_argument, 0, 'n' },
1858 {"disable_dump", no_argument, 0, 0 },
1859 {"ignore", no_argument, 0, 0 },
1860 {"rcfile", required_argument, 0, 'f' },
1861 {"convert", required_argument, 0, 'C' },
1862 {"passphrase-file", required_argument, 0, 'k' },
1863 {"import", required_argument, 0, 'I' },
1864 {"outfile", required_argument, 0, 'o' },
1865 {"no-passphrase-file", no_argument, 0, 0 },
1866 {"keygrip", required_argument, 0, 0 },
1867 {"sign-keygrip", required_argument, 0, 0 },
1868 {"keyparam", required_argument, 0, 0 },
1869 {"cipher", required_argument, 0, 0 },
1870 {"cipher-iterations", required_argument, 0, 0 },
1871 {"s2k-count", required_argument, 0, 0 },
1872 {"no-passphrase", no_argument, 0, 0 },
1873 {0, 0, 0, 0 }
1876 #ifndef DEBUG
1877 #ifdef HAVE_SETRLIMIT
1878 struct rlimit rl;
1880 rl.rlim_cur = rl.rlim_max = 0;
1882 if (setrlimit(RLIMIT_CORE, &rl) != 0)
1883 err(EXIT_FAILURE, "setrlimit()");
1884 #endif
1885 #endif
1887 #ifdef ENABLE_NLS
1888 setlocale(LC_ALL, "");
1889 bindtextdomain("pwmd", LOCALEDIR);
1890 textdomain("pwmd");
1891 #endif
1893 #ifndef MEM_DEBUG
1894 xmem_init();
1895 #endif
1896 gpg_err_init();
1898 if (setup_crypto())
1899 exit(EXIT_FAILURE);
1901 #ifdef WITH_GNUTLS
1902 gnutls_global_set_mem_functions(xmalloc, xmalloc, secure_mem_check,
1903 xrealloc, xfree);
1904 gnutls_global_init();
1905 gnutls_global_set_log_function(tls_log);
1906 gnutls_global_set_log_level(1);
1907 tls_fd = -1;
1908 tls6_fd = -1;
1909 #endif
1910 xmlMemSetup(xfree, xmalloc, xrealloc, str_dup);
1911 xmlInitMemory();
1912 xmlInitGlobals();
1913 xmlInitParser();
1914 xmlXPathInit();
1915 cmdline = 1;
1917 while ((opt = getopt_long(argc, argv, optstring, longopts, &optindex)) != -1) {
1918 switch (opt) {
1919 case 'I':
1920 import = optarg;
1921 break;
1922 case 'C':
1923 convertfile = optarg;
1924 break;
1925 case 'k':
1926 keyfile = optarg;
1927 break;
1928 case 'o':
1929 outfile = optarg;
1930 break;
1931 case 'D':
1932 secure = 1;
1933 break;
1934 case 'n':
1935 nofork = 1;
1936 break;
1937 case 'f':
1938 rcfile = str_dup(optarg);
1939 break;
1940 default:
1941 usage(argv[0], EXIT_FAILURE);
1942 break;
1943 case 0:
1944 switch (optindex) {
1945 case OPT_VERSION:
1946 show_version = 1;
1947 break;
1948 case OPT_HELP:
1949 usage(argv[0], 0);
1950 break;
1951 case OPT_DEBUG_LEVEL:
1952 debug_level_opt = optarg;
1953 break;
1954 case OPT_HOMEDIR:
1955 homedir = str_dup(optarg);
1956 break;
1957 case OPT_NO_FORK:
1958 nofork = 1;
1959 break;
1960 case OPT_DISABLE_DUMP:
1961 secure = 1;
1962 break;
1963 case OPT_IGNORE:
1964 force = 1;
1965 break;
1966 case OPT_RCFILE:
1967 rcfile = str_dup(optarg);
1968 break;
1969 case OPT_CONVERT:
1970 convertfile = optarg;
1971 break;
1972 case OPT_PASSPHRASE_FILE:
1973 keyfile = optarg;
1974 break;
1975 case OPT_IMPORT:
1976 import = optarg;
1977 break;
1978 case OPT_OUTFILE:
1979 outfile = optarg;
1980 break;
1981 case OPT_NO_PASSPHRASE_FILE:
1982 no_passphrase_file = 1;
1983 break;
1984 case OPT_KEYGRIP:
1985 keygrip = optarg;
1986 break;
1987 case OPT_SIGN_KEYGRIP:
1988 sign_keygrip = optarg;
1989 break;
1990 case OPT_KEYPARAM:
1991 keyparam = optarg;
1992 break;
1993 case OPT_CIPHER:
1994 cipher = optarg;
1995 break;
1996 case OPT_ITERATIONS:
1997 iterations = strtoull(optarg, NULL, 10);
1998 break;
1999 case OPT_S2K_COUNT:
2000 s2k_count = strtoul(optarg, NULL, 10);
2001 break;
2002 case OPT_NO_PASSPHRASE:
2003 no_passphrase = 1;
2004 break;
2005 default:
2006 usage(argv[0], 1);
2011 if (show_version) {
2012 printf(_("%s\n\n"
2013 "Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012\n"
2014 "%s\n"
2015 "Released under the terms of the GPL v2. Use at your own risk.\n\n"
2016 "Compile time features:\n%s"), PACKAGE_STRING, PACKAGE_BUGREPORT,
2017 #ifdef WITH_GNUTLS
2018 "+WITH_GNUTLS\n"
2019 #else
2020 "-WITH_GNUTLS\n"
2021 #endif
2022 #ifdef WITH_LIBACL
2023 "+WITH_LIBACL\n"
2024 #else
2025 "-WITH_LIBACL\n"
2026 #endif
2027 #ifdef DEBUG
2028 "+DEBUG\n"
2029 #else
2030 "-DEBUG\n"
2031 #endif
2032 #ifdef MEM_DEBUG
2033 "+MEM_DEBUG\n"
2034 #else
2035 "-MEM_DEBUG\n"
2036 #endif
2037 #ifdef MUTEX_DEBUG
2038 "+MUTEX_DEBUG\n"
2039 #else
2040 "-MUTEX_DEBUG\n"
2041 #endif
2043 exit(EXIT_SUCCESS);
2046 if (!homedir)
2047 homedir = str_asprintf("%s/.pwmd", get_home_dir());
2049 if (mkdir(homedir, 0700) == -1 && errno != EEXIST)
2050 err(EXIT_FAILURE, "%s", homedir);
2052 snprintf(buf, sizeof(buf), "%s/data", homedir);
2053 if (mkdir(buf, 0700) == -1 && errno != EEXIST)
2054 err(EXIT_FAILURE, "%s", buf);
2056 datadir = str_dup(buf);
2057 pthread_mutexattr_t attr;
2058 pthread_mutexattr_init(&attr);
2059 pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
2060 pthread_mutex_init(&rcfile_mutex, &attr);
2061 pthread_cond_init(&rcfile_cond, NULL);
2062 pthread_mutex_init(&cn_mutex, &attr);
2063 pthread_mutexattr_destroy(&attr);
2064 pthread_key_create(&last_error_key, free_key);
2066 if (!rcfile)
2067 rcfile = str_asprintf("%s/config", homedir);
2069 global_config = config_parse(rcfile);
2070 if (!global_config)
2071 exit(EXIT_FAILURE);
2073 setup_logging();
2075 if (debug_level_opt)
2076 debug_level = str_split(debug_level_opt, ",", 0);
2078 x = config_get_int_param(global_config, "global", "priority", &exists);
2079 if (exists) {
2080 errno = 0;
2081 if (setpriority(PRIO_PROCESS, 0, x) == -1) {
2082 log_write("setpriority(): %s", pwmd_strerror(gpg_error_from_syserror()));
2083 goto do_exit;
2086 #ifdef HAVE_MLOCKALL
2087 if (disable_mlock == 0 && mlockall(MCL_CURRENT|MCL_FUTURE) == -1) {
2088 log_write("mlockall(): %s", pwmd_strerror(gpg_error_from_syserror()));
2089 goto do_exit;
2091 #endif
2093 rc = cache_init(free_cache_data);
2094 if (rc) {
2095 log_write("pwmd: ERR %i: %s", rc,
2096 gpg_err_code(rc) == GPG_ERR_UNKNOWN_VERSION
2097 ? _("incompatible version: 2.1.0 or later required")
2098 : pwmd_strerror(rc));
2099 goto do_exit;
2102 if (s2k_count == 0)
2103 s2k_count = config_get_ulong(NULL, "s2k_count");
2105 if (convertfile) {
2106 if (!outfile)
2107 usage(argv[0], EXIT_FAILURE);
2109 estatus = convert_v2_datafile(convertfile, cipher, keyfile, keygrip,
2110 sign_keygrip, no_passphrase, outfile,
2111 keyparam, s2k_count, iterations);
2112 config_free(global_config);
2113 xfree(rcfile);
2114 exit(!estatus);
2117 if (import) {
2118 if (!outfile)
2119 usage(argv[0], EXIT_FAILURE);
2121 if (outfile[0] == '-' && outfile[1] == 0)
2122 outfile = NULL;
2124 estatus = xml_import(import, outfile, keygrip, sign_keygrip, keyfile,
2125 no_passphrase, cipher, keyparam, s2k_count, iterations);
2126 config_free(global_config);
2127 xfree(rcfile);
2128 exit(!estatus);
2131 p = config_get_string("global", "socket_path");
2132 if (!p)
2133 p = str_asprintf("%s/socket", homedir);
2135 socketarg = expand_homedir(p);
2136 xfree(p);
2138 if (!secure)
2139 disable_list_and_dump = config_get_boolean("global",
2140 "disable_list_and_dump");
2141 else
2142 disable_list_and_dump = secure;
2144 cache_push = config_get_list("global", "cache_push");
2146 while (optind < argc) {
2147 if (strv_printf(&cache_push, "%s", argv[optind++]) == 0)
2148 errx(EXIT_FAILURE, "%s", pwmd_strerror(GPG_ERR_ENOMEM));
2151 if (strchr(socketarg, '/') == NULL) {
2152 socketdir = getcwd(buf, sizeof(buf));
2153 socketname = str_dup(socketarg);
2154 socketpath = str_asprintf("%s/%s", socketdir, socketname);
2156 else {
2157 socketname = str_dup(strrchr(socketarg, '/'));
2158 socketname++;
2159 socketarg[strlen(socketarg) - strlen(socketname) -1] = 0;
2160 socketdir = str_dup(socketarg);
2161 socketpath = str_asprintf("%s/%s", socketdir, socketname);
2164 if (chdir(datadir)) {
2165 log_write("%s: %s", datadir, pwmd_strerror(gpg_error_from_syserror()));
2166 unlink(socketpath);
2167 goto do_exit;
2171 * Set the cache entry for a file. Prompts for the password.
2173 if (cache_push) {
2174 struct crypto_s *crypto;
2175 gpg_error_t rc = init_client_crypto(&crypto);
2177 if (rc) {
2178 estatus = EXIT_FAILURE;
2179 goto do_exit;
2182 rc = set_pinentry_options(crypto->agent);
2183 if (rc) {
2184 estatus = EXIT_FAILURE;
2185 goto do_exit;
2188 for (opt = 0; cache_push[opt]; opt++) {
2189 if (!do_cache_push(cache_push[opt], crypto) && !force) {
2190 strv_free(cache_push);
2191 startup_failure();
2192 estatus = EXIT_FAILURE;
2193 cleanup_crypto(&crypto);
2194 goto do_exit;
2197 cleanup_crypto_stage1(crypto);
2200 (void)kill_scd(crypto->agent);
2201 cleanup_crypto(&crypto);
2202 strv_free(cache_push);
2203 log_write(!nofork ? _("Done. Daemonizing...") : _("Done. Waiting for connections..."));
2206 config_clear_keyss();
2209 * bind() doesn't like the full pathname of the socket or any non alphanum
2210 * characters so change to the directory where the socket is wanted then
2211 * create it then change to datadir.
2213 if (chdir(socketdir)) {
2214 log_write("%s: %s", socketdir, pwmd_strerror(gpg_error_from_syserror()));
2215 goto do_exit;
2218 xfree(socketdir);
2220 if ((sockfd = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) {
2221 log_write("socket(): %s", pwmd_strerror(gpg_error_from_syserror()));
2222 goto do_exit;
2225 addr.sun_family = AF_UNIX;
2226 snprintf(addr.sun_path, sizeof(addr.sun_path), "%s", socketname);
2228 if (bind(sockfd, (struct sockaddr *)&addr, sizeof(struct sockaddr)) == -1) {
2229 log_write("bind(): %s", pwmd_strerror(gpg_error_from_syserror()));
2231 if (errno == EADDRINUSE)
2232 log_write(_("Either there is another pwmd running or '%s' is a \n"
2233 "stale socket. Please remove it manually."), socketpath);
2235 goto do_exit;
2238 do_unlink = 1;
2240 char *t = config_get_string("global", "socket_perms");
2241 mode_t mode;
2242 mode_t mask;
2244 if (t) {
2245 mode = strtol(t, NULL, 8);
2246 mask = umask(0);
2247 xfree(t);
2249 if (chmod(socketname, mode) == -1) {
2250 log_write("%s: %s", socketname,
2251 pwmd_strerror(gpg_error_from_syserror()));
2252 close(sockfd);
2253 unlink(socketpath);
2254 umask(mask);
2255 goto do_exit;
2258 umask(mask);
2262 xfree(--socketname);
2264 if (chdir(datadir)) {
2265 log_write("%s: %s", datadir, pwmd_strerror(gpg_error_from_syserror()));
2266 close(sockfd);
2267 unlink(socketpath);
2268 goto do_exit;
2271 xfree(datadir);
2273 if (listen(sockfd, 0) == -1) {
2274 log_write("listen(): %s", pwmd_strerror(gpg_error_from_syserror()));
2275 goto do_exit;
2278 cmdline = 0;
2280 if (!nofork) {
2281 switch (fork()) {
2282 case -1:
2283 log_write("fork(): %s", pwmd_strerror(gpg_error_from_syserror()));
2284 goto do_exit;
2285 case 0:
2286 close(0);
2287 close(1);
2288 close(2);
2289 setsid();
2290 break;
2291 default:
2292 _exit(EXIT_SUCCESS);
2296 pthread_key_create(&thread_name_key, free_key);
2297 pthread_setspecific(thread_name_key, str_dup("main"));
2298 estatus = server_loop(sockfd, &socketpath);
2300 do_exit:
2301 if (socketpath && do_unlink) {
2302 unlink(socketpath);
2303 xfree(socketpath);
2306 xfree(socketarg);
2307 #ifdef WITH_GNUTLS
2308 gnutls_global_deinit();
2309 #endif
2310 pthread_cancel(rcfile_tid);
2311 pthread_join(rcfile_tid, NULL);
2312 pthread_cond_destroy(&rcfile_cond);
2313 pthread_mutex_destroy(&rcfile_mutex);
2315 if (global_config)
2316 config_free(global_config);
2318 xfree(rcfile);
2319 xfree(home_directory);
2320 xfree(homedir);
2321 xmlCleanupParser();
2322 xmlCleanupGlobals();
2324 if (estatus == EXIT_SUCCESS)
2325 log_write(_("pwmd exiting normally"));
2327 closelog();
2328 #if defined(DEBUG) && !defined(MEM_DEBUG)
2329 xdump();
2330 #endif
2331 exit(estatus);