Fix a few 'gcc -fanalyzer' warnings.
[pwmd.git] / src / pwmd.c
bloba48aa56c9fef8a6e638c7aa3de01a16334395297
1 /*
2 Copyright (C) 2006-2023 Ben Kibbey <bjk@luxsci.net>
4 This file is part of pwmd.
6 Pwmd is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License version 2 as
8 published by the Free Software Foundation.
10 Pwmd is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
18 #ifdef HAVE_CONFIG_H
19 #include <config.h>
20 #endif
22 #include <stdio.h>
23 #include <stdlib.h>
24 #ifdef HAVE_UNISTD_H
25 #include <unistd.h>
26 #endif
27 #include <err.h>
28 #include <ctype.h>
29 #include <string.h>
30 #ifdef HAVE_SYS_SOCKET_H
31 #include <sys/socket.h>
32 #endif
33 #include <sys/un.h>
34 #include <signal.h>
35 #include <stdarg.h>
36 #include <sys/wait.h>
37 #ifdef HAVE_FCNTL_H
38 #include <fcntl.h>
39 #endif
40 #include <pwd.h>
41 #include <grp.h>
42 #include <pthread.h>
43 #include <sys/mman.h>
44 #ifdef HAVE_TERMIOS_H
45 #include <termios.h>
46 #endif
47 #include <assert.h>
48 #ifdef HAVE_SYSLOG_H
49 #include <syslog.h>
50 #endif
51 #ifdef HAVE_NETINET_IN_H
52 #include <netinet/in.h>
53 #endif
54 #ifdef HAVE_ARPA_INET_H
55 #include <arpa/inet.h>
56 #endif
57 #ifdef HAVE_NETDB_H
58 #include <netdb.h>
59 #endif
60 #ifdef HAVE_SYS_TIME_H
61 #include <sys/time.h>
62 #endif
63 #include <sys/resource.h>
64 #include <setjmp.h>
65 #include <errno.h>
66 #include <poll.h>
68 #ifdef TM_IN_SYS_TIME
69 #include <sys/time.h>
70 #else
71 #include <time.h>
72 #endif
74 #ifdef HAVE_LIMITS_H
75 #include <limits.h>
76 #endif
78 #ifdef HAVE_GETOPT_LONG
79 #ifdef HAVE_GETOPT_H
80 #include <getopt.h>
81 #endif
82 #else
83 #include "getopt_long.h"
84 #endif
86 #ifdef HAVE_PR_SET_NAME
87 #include <sys/prctl.h>
88 #endif
90 #include "pwmd-error.h"
91 #include <gcrypt.h>
93 #include "util-misc.h"
94 #include "mem.h"
95 #include "xml.h"
96 #include "common.h"
97 #include "commands.h"
98 #include "cache.h"
99 #include "util-string.h"
100 #include "mutex.h"
101 #include "rcfile.h"
102 #include "crypto.h"
103 #include "acl.h"
104 #include "version.h"
106 static int quit;
107 static int cmdline;
108 static jmp_buf jmp;
109 static int nofork;
110 static int log_fd;
111 static unsigned assuan_level;
112 pthread_key_t thread_name_key;
113 pthread_mutex_t cn_mutex;
114 struct slist_s *cn_thread_list;
115 static int reload_rcfile_fds[2];
117 #ifndef HAVE_PTHREAD_CANCEL
118 pthread_key_t signal_thread_key;
120 #define INIT_SIGNAL(s, cb) do { \
121 int *n = xmalloc (sizeof (int)); \
122 *n = 0; \
123 pthread_setspecific (signal_thread_key, n); \
124 struct sigaction act; \
125 sigset_t sigset; \
126 sigemptyset (&sigset); \
127 sigaddset (&sigset, s); \
128 pthread_sigmask (SIG_UNBLOCK, &sigset, NULL); \
129 memset (&act, 0, sizeof(act)); \
130 act.sa_flags = SA_SIGINFO; \
131 act.sa_mask = sigset; \
132 act.sa_sigaction = cb; \
133 sigaction (s, &act, NULL); \
134 } while (0)
136 static void
137 catch_thread_signal (int sig, siginfo_t *info, void *ctx)
139 int *n = (int *) pthread_getspecific (signal_thread_key);
141 *n = 1;
143 #endif
145 static void
146 setup_logging ()
148 int n = config_get_boolean ("global", "enable_logging");
150 if (n)
152 char *p = config_get_string ("global", "log_path");
154 if (!p || (logfile && p && log_fd != -1 && strcmp(p, logfile)))
156 if (log_fd != -1)
157 close (log_fd);
159 log_fd = -1;
162 xfree (logfile);
163 logfile = NULL;
164 if (p)
165 logfile = expand_homedir (p);
166 xfree (p);
168 else
170 xfree (logfile);
171 logfile = NULL;
172 if (log_fd != -1)
173 close(log_fd);
175 log_fd = -1;
176 closelog ();
179 log_syslog = config_get_boolean ("global", "syslog");
180 if (log_syslog == 1)
181 openlog ("pwmd", LOG_NDELAY | LOG_PID, LOG_DAEMON);
184 static void
185 reload_rcfile ()
187 MUTEX_LOCK (&rcfile_mutex);
188 struct slist_s *keep = NULL;
189 struct slist_s *config;
190 int b = disable_list_and_dump;
191 #ifdef WITH_GNUTLS
192 char *prio;
193 char *prio2 = NULL;
194 #endif
196 keep = config_keep_save ();
197 log_write (_("reloading configuration file '%s'"), rcfile);
199 #ifdef WITH_GNUTLS
200 prio = config_get_string ("global", "tls_cipher_suite");
201 #endif
202 config = config_parse (rcfile, 1);
203 if (config)
205 config_free (global_config);
206 global_config = config;
207 setup_logging ();
210 config_keep_restore (keep);
211 disable_list_and_dump = !disable_list_and_dump ? b : 1;
213 #ifdef WITH_GNUTLS
214 /* Restart listening sockets since they may have changed. */
215 tls_start_stop (1);
216 tls_start_stop (0);
218 prio2 = config_get_string ("global", "tls_cipher_suite");
219 if ((prio2 && (!prio || strcmp (prio, prio2))) || (prio && !prio2))
220 tls_rehandshake ();
222 xfree (prio2);
223 xfree (prio);
224 #endif
225 crypto_set_keepalive ();
226 MUTEX_UNLOCK (&rcfile_mutex);
229 #define PROCESS_DONE(client,rc) (client && client->bulk_p) ? rc : \
230 assuan_process_done (client ? client->ctx : NULL, rc)
231 gpg_error_t
232 send_error (assuan_context_t ctx, gpg_error_t e)
234 struct client_s *client = assuan_get_pointer (ctx);
236 if (gpg_err_source (e) == GPG_ERR_SOURCE_UNKNOWN)
237 e = gpg_error (e);
239 if (client)
240 client->last_rc = e;
242 if (!e)
243 return PROCESS_DONE (client, 0);
245 if (!ctx)
247 log_write ("ERR %i: %s", e, pwmd_strerror (e));
248 return e;
251 if (client && client->xml_error)
253 log_write ("%s", client->xml_error->message);
254 xfree (client->last_error);
255 client->last_error = NULL;
256 if (client->xml_error->message)
257 client->last_error = str_dup (client->xml_error->message);
259 e = PROCESS_DONE (client, assuan_set_error (ctx, e,
260 client->xml_error->message
261 ? client->xml_error->message
262 : NULL));
263 xmlResetLastError ();
264 xmlResetError (client->xml_error);
265 xfree (client->xml_error);
266 client->xml_error = NULL;
267 return e;
270 return PROCESS_DONE (client, assuan_set_error (ctx, e, pwmd_strerror (e)));
273 void
274 log_write (const char *fmt, ...)
276 char *args;
277 va_list ap;
278 time_t now;
279 char buf[255];
280 pthread_t tid = pthread_self ();
281 static pthread_mutex_t m = PTHREAD_MUTEX_INITIALIZER;
283 if ((!logfile && !nofork && !log_syslog && !cmdline) || !fmt)
284 return;
286 MUTEX_LOCK (&m);
287 pthread_cleanup_push (release_mutex_cb, &m);
289 if (!cmdline && logfile && log_fd == -1)
291 log_fd = open (logfile, O_WRONLY | O_CREAT | O_APPEND, 0600);
292 if (log_fd == -1)
293 warn ("%s", logfile);
296 va_start (ap, fmt);
298 if (str_vasprintf (&args, fmt, ap) != -1)
300 pthread_cleanup_push (xfree, args);
301 if (cmdline)
303 fprintf (stderr, "pwmd: %s\n", args);
304 fflush (stderr);
306 else
308 char *name = pthread_getspecific (thread_name_key);
309 char *line;
311 if (name)
313 if (*name == '!')
314 snprintf (buf, sizeof (buf), "%s: ", name+1);
315 else
316 snprintf (buf, sizeof (buf), "%s(%p): ", name,
317 (pthread_t *)tid);
319 else
320 snprintf (buf, sizeof (buf), "%p: ", (pthread_t *)tid);
322 name = buf;
323 if (!cmdline && log_syslog && !nofork)
324 syslog (LOG_INFO, "%s%s", name, args);
326 time (&now);
327 struct tm *tm = localtime (&now);
328 char tbuf[21];
329 strftime (tbuf, sizeof (tbuf), "%b %d %Y %H:%M:%S ", tm);
330 tbuf[sizeof (tbuf) - 1] = 0;
332 if (args[strlen (args) - 1] == '\n')
333 args[strlen (args) - 1] = 0;
335 line = str_asprintf ("%s %i %s%s\n", tbuf, getpid (), name, args);
336 if (line)
338 pthread_cleanup_push (xfree, line);
339 if (logfile && log_fd != -1)
341 ssize_t ret = write (log_fd, line, strlen (line));
342 (void)ret;
343 fsync (log_fd);
346 if (nofork)
348 fprintf (stdout, "%s", line);
349 fflush (stdout);
352 pthread_cleanup_pop (1);
355 pthread_cleanup_pop (1);
358 va_end (ap);
360 if (log_fd != -1 && log_keepopen <= 0)
362 close(log_fd);
363 log_fd = -1;
366 pthread_cleanup_pop (1);
369 static gpg_error_t
370 setup_crypto ()
372 gpg_error_t rc;
374 if (!gpgrt_check_version (REQUIRE_LIBGPGERROR_VERSION))
376 fprintf (stderr, _("gpgrt_check_version(): Incompatible libgpg-error. "
377 "Wanted %s, got %s.\n"), REQUIRE_LIBGPGERROR_VERSION,
378 gpgrt_check_version (NULL));
379 return GPG_ERR_UNKNOWN_VERSION;
382 gpgrt_init ();
383 gpgrt_set_alloc_func (xrealloc_gpgrt);
385 if (!assuan_check_version (REQUIRE_LIBASSUAN_VERSION))
387 fprintf (stderr, _("assuan_check_version(): Incompatible libassuan. "
388 "Wanted %s, got %s.\n"), REQUIRE_LIBASSUAN_VERSION,
389 assuan_check_version (NULL));
390 return GPG_ERR_UNKNOWN_VERSION;
393 if (!gcry_check_version (REQUIRE_LIBGCRYPT_VERSION))
395 fprintf (stderr, _("gcry_check_version(): Incompatible libgcrypt. "
396 "Wanted %s, got %s.\n"), REQUIRE_LIBGCRYPT_VERSION,
397 gcry_check_version (NULL));
398 return GPG_ERR_UNKNOWN_VERSION;
401 gcry_set_allocation_handler (xmalloc, xmalloc, NULL, xrealloc, xfree);
403 if (!gpgme_check_version (REQUIRE_LIBGPGME_VERSION))
405 fprintf (stderr, _("gpgme_check_version(): Incompatible libgpgme. "
406 "Wanted %s, got %s.\n"), REQUIRE_LIBGPGME_VERSION,
407 gpgme_check_version (NULL));
408 return GPG_ERR_UNKNOWN_VERSION;
411 rc = gpgme_engine_check_version (GPGME_PROTOCOL_OPENPGP);
412 if (rc)
414 fprintf (stderr, _("gpgme_engine_check_version(GPGME_PROTOCOL_OPENPGP): %s"), gpgme_strerror (rc));
415 return GPG_ERR_UNKNOWN_VERSION;
418 //gpgme_set_global_flag ("require-gnupg", REQUIRE_GNUPG_VERSION);
419 #ifdef ENABLE_NLS
420 gpgme_set_locale (NULL, LC_CTYPE, setlocale (LC_CTYPE, NULL));
421 gpgme_set_locale (NULL, LC_MESSAGES, setlocale (LC_MESSAGES, NULL));
422 #endif
424 #ifdef WITH_GNUTLS
425 if (gnutls_global_init ())
427 fprintf(stderr, _("gnutls_global_init() failed.\n"));
428 return GPG_ERR_UNKNOWN_VERSION;
431 if (!gnutls_check_version (REQUIRE_LIBGNUTLS_VERSION))
433 fprintf (stderr, _("gnutls_check_version(): Incompatible libgnutls. "
434 "Wanted %s, got %s.\n"), REQUIRE_LIBGNUTLS_VERSION,
435 gnutls_check_version (NULL));
436 return GPG_ERR_UNKNOWN_VERSION;
439 gnutls_global_set_log_function (tls_log);
440 gnutls_global_set_audit_log_function (tls_audit_log);
441 #endif
442 return 0;
445 static void
446 xml_error_cb (void *data, xmlErrorPtr e)
448 struct client_s *client = data;
451 * Keep the first reported error as the one to show in the error
452 * description. Reset in send_error().
454 if (client->xml_error)
455 return;
457 client->xml_error = xcalloc (1, sizeof(xmlError));
458 xmlCopyError (e, client->xml_error);
461 static pid_t
462 hook_waitpid (assuan_context_t ctx, pid_t pid, int action,
463 int *status, int options)
465 (void)ctx;
466 (void)action;
467 return waitpid (pid, status, options);
470 static ssize_t
471 hook_read (assuan_context_t ctx, assuan_fd_t fd, void *data, size_t len)
473 TEST_CANCEL ();
474 #ifdef WITH_GNUTLS
475 struct client_s *client = assuan_get_pointer (ctx);
477 if (client->thd->remote)
478 return tls_read_hook (ctx, (int) fd, data, len);
479 #else
480 (void)ctx;
481 #endif
482 return read ((int) fd, data, len);
485 static ssize_t
486 hook_write (assuan_context_t ctx, assuan_fd_t fd,
487 const void *data, size_t len)
489 TEST_CANCEL ();
490 #ifdef WITH_GNUTLS
491 struct client_s *client = assuan_get_pointer (ctx);
493 if (client->thd->remote)
494 return tls_write_hook (ctx, (int) fd, data, len);
495 #else
496 (void)ctx;
497 #endif
498 return write ((int) fd, data, len);
502 assuan_log_cb (assuan_context_t ctx, void *data, unsigned cat,
503 const char *msg)
505 struct client_s *client = data;
506 const char *str = NULL;
508 (void)client;
509 (void)ctx;
511 if (!(assuan_level & cat))
512 return 0;
514 if (!msg)
515 return 1;
517 switch (cat)
519 case ASSUAN_LOG_INIT:
520 str = "ASSUAN[INIT]";
521 break;
522 case ASSUAN_LOG_CTX:
523 str = "ASSUAN[CTX]";
524 break;
525 case ASSUAN_LOG_ENGINE:
526 str = "ASSUAN[ENGINE]";
527 break;
528 case ASSUAN_LOG_DATA:
529 str = "ASSUAN[DATA]";
530 break;
531 case ASSUAN_LOG_SYSIO:
532 str = "ASSUAN[SYSIO]";
533 break;
534 case ASSUAN_LOG_CONTROL:
535 str = "ASSUAN[CONTROL]";
536 break;
537 default:
538 str = "ASSUAN[UNKNOWN]";
539 break;
542 log_write ("%s: %s", str, msg);
543 return 1;
546 static int
547 new_connection (struct client_s *cl)
549 gpg_error_t rc;
550 static struct assuan_malloc_hooks mhooks = { xmalloc, xrealloc, xfree };
551 static struct assuan_system_hooks shooks = {
552 ASSUAN_SYSTEM_HOOKS_VERSION,
553 __assuan_usleep,
554 __assuan_pipe,
555 __assuan_close,
556 hook_read,
557 hook_write,
558 //FIXME
559 NULL, //recvmsg
560 NULL, //sendmsg both are used for FD passing
561 __assuan_spawn,
562 hook_waitpid,
563 __assuan_socketpair,
564 __assuan_socket,
565 __assuan_connect
568 #ifdef WITH_GNUTLS
569 if (cl->thd->remote)
571 char *prio = config_get_string ("global", "tls_cipher_suite");
573 cl->thd->timeout = config_get_integer ("global", "tls_timeout");
574 if (fcntl (cl->thd->fd, F_SETFL, O_NONBLOCK) == -1)
575 return 0;
577 cl->thd->tls = tls_init_client (cl->thd->fd, cl->thd->timeout, prio);
578 xfree (prio);
579 if (!cl->thd->tls)
580 return 0;
582 #endif
584 rc = assuan_new_ext (&cl->ctx, GPG_ERR_SOURCE_DEFAULT, &mhooks,
585 assuan_log_cb, cl);
586 if (rc)
587 goto fail;
589 assuan_ctx_set_system_hooks (cl->ctx, &shooks);
590 rc = assuan_init_socket_server (cl->ctx, cl->thd->fd,
591 ASSUAN_SOCKET_SERVER_ACCEPTED);
592 if (rc)
593 goto fail;
595 assuan_set_pointer (cl->ctx, cl);
596 assuan_set_hello_line (cl->ctx, PACKAGE_STRING PWMD_GIT_HASH);
597 rc = register_commands (cl->ctx);
598 if (rc)
599 goto fail;
601 rc = assuan_accept (cl->ctx);
602 if (rc)
603 goto fail;
605 rc = validate_peer (cl);
606 /* May not be implemented on all platforms. */
607 if (rc && gpg_err_code (rc) != GPG_ERR_ASS_GENERAL)
608 goto fail;
610 MUTEX_LOCK (&cn_mutex);
611 cl->thd->state = CLIENT_STATE_INIT;
612 MUTEX_UNLOCK (&cn_mutex);
613 cl->lock_timeout = config_get_integer ("global", "lock_timeout");
614 xmlSetStructuredErrorFunc (cl, xml_error_cb);
615 return 1;
617 fail:
618 log_write ("%s", pwmd_strerror (rc));
619 return 0;
623 * This is called after a client is cancelled or disconnects. Set with
624 * pthread_cleanup_push().
626 static void
627 free_client_cb (void *arg)
629 struct client_thread_s *cn = arg;
630 struct client_s *cl = cn->cl;
631 char *tmp = NULL;
633 #ifndef HAVE_PTHREAD_CANCEL
634 tmp = pthread_getspecific (signal_thread_key);
635 xfree (tmp);
636 pthread_setspecific (signal_thread_key, NULL);
637 #endif
639 MUTEX_LOCK (&cn_mutex);
640 cn_thread_list = slist_remove (cn_thread_list, cn);
641 MUTEX_UNLOCK (&cn_mutex);
643 if (cl)
645 unlock_flock (&cl->flock_fd);
646 reset_client (cl);
647 if (cl->xml_error)
648 xmlResetError (cl->xml_error);
650 xfree (cl->xml_error);
652 #ifdef WITH_GNUTLS
653 if (cn->tls)
655 gnutls_deinit (cn->tls->ses);
656 xfree (cn->tls->fp);
657 xfree (cn->tls);
659 #endif
661 if (cl->ctx)
662 assuan_release (cl->ctx);
663 else if (cl->thd && cl->thd->fd != -1)
664 close (cl->thd->fd);
666 if (cl->crypto)
667 crypto_free (cl->crypto);
669 cl->crypto = NULL;
670 xfree (cl);
672 else
674 if (cn->fd != -1)
675 close (cn->fd);
678 while (cn->msg_queue)
680 struct status_msg_s *msg = cn->msg_queue;
682 cn->msg_queue = msg->next;
683 xfree (msg->line);
684 xfree (msg);
687 if (cn->status_msg_pipe[0] != -1)
688 close (cn->status_msg_pipe[0]);
690 if (cn->status_msg_pipe[1] != -1)
691 close (cn->status_msg_pipe[1]);
693 pthread_mutex_destroy (&cn->status_mutex);
694 log_write (_("exiting, fd=%i"), cn->fd);
695 send_status_all (STATUS_CLIENTS, NULL);
697 xfree (cn->name);
698 #ifdef WITH_GNUTLS
699 xfree (cn->peeraddr);
700 #endif
702 if (cn->eof) // Not pthread_exit() or pthread_cancel().
704 tmp = pthread_getspecific (thread_name_key);
705 xfree (tmp);
706 pthread_setspecific (thread_name_key, NULL);
709 (void)cache_kill_scd ();
710 xfree (cn->cmdname);
711 xfree (cn);
714 static void
715 free_all_clients ()
717 MUTEX_LOCK (&cn_mutex);
718 pthread_cleanup_push (release_mutex_cb, &cn_mutex);
720 while (slist_length (cn_thread_list))
722 struct client_thread_s *thd = slist_nth_data (cn_thread_list, 0);
724 free_client_cb (thd);
725 thd->eof = 1;
728 pthread_cleanup_pop (1);
731 static gpg_error_t
732 send_msg_queue (struct client_thread_s *thd)
734 MUTEX_LOCK (&thd->status_mutex);
735 gpg_error_t rc = 0;
736 char c;
737 ssize_t ret;
739 ret = read (thd->status_msg_pipe[0], &c, 1);
740 rc = gpg_error_from_syserror ();
741 if (ret == -1 && gpg_err_code (rc) != GPG_ERR_EAGAIN)
742 log_write ("%s (%i): %s", __FUNCTION__, __LINE__, pwmd_strerror (rc));
743 else
744 rc = 0;
746 thd->wrote_status = 0;
748 while (thd->msg_queue)
750 struct status_msg_s *msg = thd->msg_queue;
752 thd->msg_queue = thd->msg_queue->next;
753 MUTEX_UNLOCK (&thd->status_mutex);
754 pthread_cleanup_push (xfree, msg);
755 pthread_cleanup_push (xfree, msg->line);
756 rc = send_status (thd->cl->ctx, msg->s, msg->line);
757 pthread_cleanup_pop (1);
758 pthread_cleanup_pop (1);
759 MUTEX_LOCK (&thd->status_mutex);
760 if (rc)
761 break;
764 MUTEX_UNLOCK (&thd->status_mutex);
765 if (rc && gpg_err_code (rc) != GPG_ERR_EPIPE)
766 log_write ("%s (%i): %s", __FUNCTION__, __LINE__, pwmd_strerror (rc));
768 return rc;
771 static void *
772 client_thread (void *data)
774 struct client_thread_s *thd = data;
775 struct client_s *cl = xcalloc (1, sizeof (struct client_s));
776 struct slist_s *list;
777 gpg_error_t rc = 0;
778 #ifndef HAVE_PTHREAD_CANCEL
779 INIT_SIGNAL (SIGUSR2, catch_thread_signal);
780 #endif
782 #ifdef HAVE_PR_SET_NAME
783 prctl (PR_SET_NAME, "client");
784 #endif
785 pthread_setspecific (thread_name_key, str_dup (__FUNCTION__));
787 if (!cl)
789 log_write ("%s(%i): %s", __FILE__, __LINE__,
790 pwmd_strerror (GPG_ERR_ENOMEM));
791 return NULL;
794 MUTEX_LOCK (&cn_mutex);
795 pthread_cleanup_push (free_client_cb, thd);
796 thd->cl = cl;
797 cl->thd = thd;
798 cl->flock_fd = -1;
800 list = slist_append (cn_thread_list, thd);
801 if (list)
802 cn_thread_list = list;
803 else
805 log_write ("%s(%i): %s", __FILE__, __LINE__,
806 pwmd_strerror (GPG_ERR_ENOMEM));
807 MUTEX_UNLOCK (&cn_mutex);
808 return NULL;
811 if (fcntl (thd->status_msg_pipe[0], F_SETFL, O_NONBLOCK) == -1)
812 rc = gpg_error_from_errno (errno);
814 if (!rc)
815 if (fcntl (thd->status_msg_pipe[1], F_SETFL, O_NONBLOCK) == -1)
816 rc = gpg_error_from_errno (errno);
818 MUTEX_UNLOCK (&cn_mutex);
820 if (rc)
822 log_write ("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror (rc));
823 goto done;
826 if (new_connection (cl))
828 struct pollfd fds[2];
830 fds[0].fd = thd->fd;
831 fds[0].events = POLLIN;
832 fds[1].fd = thd->status_msg_pipe[0];
833 fds[1].events = POLLIN;
835 send_status_all (STATUS_CLIENTS, NULL);
836 rc = send_status (cl->ctx, STATUS_CACHE, NULL);
837 if (rc)
839 log_write ("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror (rc));
840 goto done;
843 for (;;)
845 int n;
846 int eof;
848 n = poll (fds, sizeof(fds)/sizeof(fds[0]), 100);
849 if (n == -1)
851 log_write ("%s", strerror (errno));
852 break;
855 #ifdef WITH_GNUTLS
856 if (thd->remote && thd->tls && thd->tls->rehandshake)
858 char *prio;
859 int ret;
860 const char *e;
862 if (thd->tls->rehandshake == 1)
864 prio = config_get_string ("global", "tls_cipher_suite");
865 if (!prio)
867 thd->tls->rehandshake = 0;
868 continue;
871 ret = gnutls_priority_set_direct (thd->tls->ses, prio, &e);
872 if (ret == GNUTLS_E_SUCCESS)
874 rc = send_status (cl->ctx, STATUS_REHANDSHAKE, NULL);
875 if (!rc)
877 rc = assuan_send_data (cl->ctx, NULL, 0);
878 if (!rc)
880 ret = gnutls_rehandshake (thd->tls->ses);
881 if (ret)
883 log_write ("%s", gnutls_strerror (ret));
884 thd->tls->rehandshake = 0;
886 else
887 thd->tls->rehandshake = 2;
891 if (rc)
892 log_write ("%s", pwmd_strerror (rc));
894 else
895 log_write ("%s: %s", gnutls_strerror (ret), e);
897 xfree (prio);
898 continue;
901 #endif
903 if (!n)
904 continue;
906 if (fds[1].revents & POLLIN)
908 #ifdef WITH_GNUTLS
909 if (!thd->remote || (thd->tls && !thd->tls->rehandshake))
910 #endif
912 rc = send_msg_queue (thd);
913 if (rc && gpg_err_code (rc) != GPG_ERR_EPIPE)
914 break;
918 #ifdef HAVE_PTHREAD_CANCEL
919 if (!(fds[0].revents & POLLIN))
920 #else
921 if (thd->fd != -1 && !(fds[0].revents & POLLIN))
922 #endif
923 continue;
925 rc = assuan_process_next (cl->ctx, &eof);
926 if (rc || eof)
928 if (gpg_err_code (rc) == GPG_ERR_EOF || eof)
929 break;
931 log_write ("assuan_process_next(): rc=%u %s", rc,
932 pwmd_strerror (rc));
933 if (rc == gpg_error (GPG_ERR_ETIMEDOUT))
934 break;
936 rc = send_error (cl->ctx, rc);
937 if (rc)
939 log_write ("assuan_process_done(): rc=%u %s", rc,
940 pwmd_strerror (rc));
941 break;
945 /* Since the msg queue pipe fd's are non-blocking, check for
946 * pending status msgs here. GPG_ERR_EPIPE can be seen when the
947 * client has already disconnected and will be converted to
948 * GPG_ERR_EOF during assuan_process_next().
950 #ifdef WITH_GNUTLS
951 if (!thd->remote || (thd->tls && !thd->tls->rehandshake))
952 #endif
954 rc = send_msg_queue (thd);
955 if (rc && gpg_err_code (rc) != GPG_ERR_EPIPE)
956 break;
961 done:
962 /* Don't do pthread_exit() here because any set pthread_cleanup_push
963 * functions would be called after a command failed but then the client
964 * exited normally which may lead to a double free. */
965 thd->eof = 1;
966 pthread_cleanup_pop (1);
967 return NULL;
970 static gpg_error_t
971 xml_import (const char *filename, const char *outfile, char **keyid,
972 char *sign_keyid, char *keyfile, const char *userid,
973 const char *algo, long expire, int no_passphrase, int symmetric)
975 xmlDocPtr doc;
976 int fd;
977 struct stat st;
978 int len;
979 xmlChar *xmlbuf = NULL;
980 gpg_error_t rc = 0;
981 struct crypto_s *crypto = NULL;
983 if (strcmp (filename, "-"))
985 rc = open_check_file (filename, &fd, &st, 0);
986 if (rc)
987 return rc;
989 xmlbuf = xmalloc (st.st_size + 1);
990 if (!xmlbuf)
992 close (fd);
993 return GPG_ERR_ENOMEM;
996 if (read (fd, xmlbuf, st.st_size) == -1)
998 rc = gpg_error_from_errno (errno);
999 close (fd);
1000 xfree (xmlbuf);
1001 return rc;
1004 xmlbuf[st.st_size] = 0;
1005 close (fd);
1007 else
1009 #define BUFSIZE 8196
1010 size_t size = 0, xlen = 0;
1012 for (;;)
1014 size_t ret;
1015 xmlChar *tmp;
1017 tmp = xrealloc (xmlbuf, size+BUFSIZE+1);
1018 if (!tmp)
1020 xfree (xmlbuf);
1021 return GPG_ERR_ENOMEM;
1024 xmlbuf = tmp;
1025 size += BUFSIZE;
1026 ret = read (STDIN_FILENO, &xmlbuf[xlen], BUFSIZE);
1027 if (ret == -1)
1029 rc = gpg_error_from_syserror ();
1030 xfree (xmlbuf);
1031 return rc;
1034 xlen += ret;
1035 if (!ret || ret < BUFSIZE)
1036 break;
1039 xmlbuf[xlen] = 0;
1042 doc = xmlReadDoc (xmlbuf, NULL, "UTF-8", XML_PARSE_NOBLANKS);
1043 xfree (xmlbuf);
1044 if (!doc)
1045 return GPG_ERR_BAD_DATA;
1047 xmlNodePtr n = xmlDocGetRootElement (doc);
1048 if (n && !xmlStrEqual (n->name, (xmlChar *) "pwmd"))
1049 rc = GPG_ERR_BAD_DATA;
1051 if (!rc)
1053 rc = xml_validate_import (NULL, n ? n->children : n);
1054 if (!rc)
1056 rc = crypto_init (&crypto, NULL, filename, keyfile != NULL, keyfile);
1057 if (!rc)
1059 if (keyfile)
1061 crypto->flags |= CRYPTO_FLAG_KEYFILE;
1062 crypto->keyfile = str_dup (keyfile);
1065 xmlDocDumpMemory (doc, &crypto->plaintext, &len);
1066 if (len > 0)
1067 crypto->plaintext_size = len;
1068 else
1069 rc = GPG_ERR_ENOMEM;
1074 if (!rc)
1076 if (!symmetric && !keyid)
1078 crypto->save.userid = str_dup (userid);
1079 crypto->save.algo = algo ? str_dup (algo) : NULL;
1080 crypto->save.expire = expire;
1081 if (no_passphrase)
1082 crypto->save.flags |= GPGME_CREATE_NOPASSWD;
1084 rc = crypto_genkey (NULL, crypto);
1086 else
1088 if (keyid)
1089 crypto->save.pubkey = strv_dup (keyid);
1091 if (sign_keyid)
1092 crypto->save.sigkey = str_dup (sign_keyid);
1095 if (!rc)
1097 crypto->flags |= symmetric ? CRYPTO_FLAG_SYMMETRIC : 0;
1098 rc = crypto_encrypt (NULL, crypto);
1102 if (!rc)
1104 if (!strcmp (outfile, "-"))
1105 outfile = NULL;
1107 xfree (crypto->plaintext);
1108 crypto->plaintext = NULL;
1109 xfree (crypto->filename);
1110 crypto->filename = outfile ? str_dup (outfile) : NULL;
1111 rc = crypto_write_file (crypto, NULL, NULL);
1114 xmlFreeDoc (doc);
1115 crypto_free (crypto);
1116 return rc;
1119 static gpg_error_t
1120 do_cache_push (struct crypto_s *crypto)
1122 gpg_error_t rc;
1123 xmlDocPtr doc;
1124 struct cache_data_s *cdata;
1125 unsigned char *crc;
1126 size_t len;
1127 int fd = -1;
1129 log_write (_("Adding '%s' to the cache..."),
1130 crypto->filename);
1132 if (valid_filename (crypto->filename) == 0)
1134 log_write (_("%s: Invalid characters in filename"), crypto->filename);
1135 return GPG_ERR_INV_VALUE;
1138 rc = lock_flock (NULL, crypto->filename, LOCK_SH, &fd);
1139 if (!rc)
1140 rc = crypto_decrypt (NULL, crypto);
1141 if (rc)
1143 unlock_flock (&fd);
1144 return rc;
1147 rc = xml_parse_doc ((char *) crypto->plaintext, crypto->plaintext_size, &doc);
1148 if (rc)
1150 unlock_flock (&fd);
1151 log_write ("%s", pwmd_strerror (rc));
1152 return rc;
1155 cdata = xcalloc (1, sizeof (struct cache_data_s));
1156 if (!cdata)
1158 unlock_flock (&fd);
1159 xmlFreeDoc (doc);
1160 return GPG_ERR_ENOMEM;
1163 rc = get_checksum (crypto->filename, &crc, &len);
1164 unlock_flock (&fd);
1165 if (rc)
1167 xmlFreeDoc (doc);
1168 cache_free_data_once (cdata);
1169 return rc;
1172 cdata->crc = crc;
1173 rc = cache_encrypt (crypto);
1174 if (!rc)
1176 cdata->doc = crypto->plaintext;
1177 cdata->size = crypto->plaintext_size;
1178 crypto->plaintext = NULL;
1179 cdata->pubkey = crypto->pubkey;
1180 cdata->sigkey = crypto->sigkey;
1181 crypto->pubkey = NULL;
1182 crypto->sigkey = NULL;
1184 else
1186 xmlFreeDoc (doc);
1187 cache_free_data_once (cdata);
1188 return rc;
1191 long timeout = config_get_long (crypto->filename, "cache_timeout");
1192 rc = cache_add_file (crypto->filename, cdata, timeout, 0);
1193 return rc;
1196 static gpg_error_t
1197 init_client (int fd, const char *addr)
1199 gpg_error_t rc = 0;
1200 struct client_thread_s *new = xcalloc (1, sizeof (struct client_thread_s));
1202 if (!new)
1204 close (fd);
1205 log_write ("%s: %s", __FUNCTION__, pwmd_strerror (ENOMEM));
1206 return GPG_ERR_ENOMEM;
1209 MUTEX_LOCK (&cn_mutex);
1210 pthread_cleanup_push (release_mutex_cb, &cn_mutex);
1211 new->conntime = time (NULL);
1213 if (pipe (new->status_msg_pipe) == -1)
1214 rc = gpg_error_from_errno (errno);
1215 else
1216 pthread_mutex_init (&new->status_mutex, NULL);
1218 if (!rc)
1220 #ifdef WITH_GNUTLS
1221 new->remote = addr ? 1 : 0;
1222 if (addr)
1223 new->peeraddr = str_dup (addr);
1224 #endif
1225 new->fd = fd;
1226 rc = create_thread (client_thread, new, &new->tid, 1);
1227 if (rc)
1229 close (new->status_msg_pipe[0]);
1230 close (new->status_msg_pipe[1]);
1231 pthread_mutex_destroy (&new->status_mutex);
1235 if (!rc)
1237 if (addr)
1238 log_write (_("new connection: tid=%p, fd=%i, addr=%s"),
1239 (pthread_t *) new->tid, fd, addr);
1240 else
1241 log_write (_("new connection: tid=%p, fd=%i"),
1242 (pthread_t *) new->tid, fd);
1245 pthread_cleanup_pop (1);
1247 if (rc)
1249 xfree (new);
1250 close (fd);
1251 log_write ("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror (rc));
1253 return rc;
1256 #ifdef WITH_GNUTLS
1257 static gpg_error_t
1258 do_tls_accept (struct pollfd *fds)
1260 struct sockaddr_storage raddr;
1261 socklen_t slen = sizeof (raddr);
1262 int fd;
1263 char s[INET6_ADDRSTRLEN];
1265 if (!(fds->revents & POLLIN))
1266 return 0;
1268 memset (&raddr, 0, sizeof (raddr));
1269 fd = accept (fds->fd, (struct sockaddr *) &raddr, &slen);
1270 if (fd == -1)
1272 int e = errno;
1274 if (errno != EAGAIN && !quit)
1275 log_write ("%s: %s", __FUNCTION__,
1276 pwmd_strerror (gpg_error_from_syserror()));
1278 return gpg_error_from_errno (e);
1281 inet_ntop (raddr.ss_family, get_in_addr ((struct sockaddr *) &raddr), s,
1282 sizeof s);
1283 (void) init_client (fd, s);
1284 return 0;
1286 #endif
1288 static void *
1289 accept_thread (void *arg)
1291 int sockfd = *(int *) arg;
1292 #ifndef HAVE_PTHREAD_CANCEL
1293 INIT_SIGNAL (SIGUSR2, catch_thread_signal);
1294 #endif
1296 #ifdef HAVE_PR_SET_NAME
1297 prctl (PR_SET_NAME, "accept");
1298 #endif
1299 pthread_setspecific (thread_name_key, str_asprintf ("!%s", __FUNCTION__));
1301 #define N_FDS 4
1302 for (;;)
1304 socklen_t slen = sizeof (struct sockaddr_un);
1305 struct sockaddr_un raddr;
1306 int fd, s = 0;
1307 struct pollfd fds[N_FDS];
1309 TEST_CANCEL ();
1310 memset (fds, 0, sizeof (fds));
1311 fds[s].fd = sockfd;
1312 fds[s++].events = POLLIN;
1314 fds[s].fd = reload_rcfile_fds[0];
1315 fds[s++].events = POLLIN;
1317 #ifdef WITH_GNUTLS
1318 if (tls_fd != -1)
1320 fds[s].fd = tls_fd;
1321 fds[s++].events = POLLIN;
1323 else
1324 fds[s].fd = tls_fd;
1326 if (tls6_fd != -1)
1328 fds[s].fd = tls6_fd;
1329 fds[s++].events = POLLIN;
1331 else
1332 fds[s].fd = tls6_fd;
1333 #endif
1335 s = poll (fds, s, -1);
1336 if (s == -1)
1338 if (errno != EINTR)
1339 log_write ("%s", strerror (errno));
1340 break;
1342 else if (s == 0)
1343 continue;
1345 if (fds[0].revents & POLLIN)
1347 fd = accept (sockfd, (struct sockaddr *) &raddr, &slen);
1348 if (fd == -1)
1350 if (errno == EMFILE || errno == ENFILE)
1351 log_write ("%s: %s", __FUNCTION__,
1352 pwmd_strerror (gpg_error_from_errno (errno)));
1353 else if (errno != EAGAIN && errno != EINTR)
1355 if (!quit) // probably EBADF
1356 log_write ("%s: %s", __FUNCTION__,
1357 pwmd_strerror (gpg_error_from_errno (errno)));
1359 break;
1362 continue;
1365 (void) init_client (fd, NULL);
1368 for (int n = 1; n < N_FDS; n++)
1370 if (fds[n].fd == -1)
1371 continue;
1373 if (fds[n].fd == reload_rcfile_fds[0] && (fds[n].revents & POLLIN))
1375 char c;
1376 int r = read (reload_rcfile_fds[0], &c, 1);
1378 if (r != -1)
1379 reload_rcfile ();
1382 #ifdef WITH_GNUTLS
1383 if (fds[n].fd == tls_fd && (fds[n].revents & POLLIN))
1384 (void)do_tls_accept (&fds[n]);
1386 if (fds[n].fd == tls6_fd && (fds[n].revents & POLLIN))
1387 (void)do_tls_accept (&fds[n]);
1388 #endif
1392 /* Just in case accept() failed for some reason other than EBADF */
1393 quit = 1;
1394 return NULL;
1397 static void *
1398 cache_timer_thread (void *arg)
1400 unsigned k = 0;
1401 #ifndef HAVE_PTHREAD_CANCEL
1402 INIT_SIGNAL (SIGUSR2, catch_thread_signal);
1403 #endif
1405 (void)arg;
1407 #ifdef HAVE_PR_SET_NAME
1408 prctl (PR_SET_NAME, "timer");
1409 #endif
1410 pthread_setspecific (thread_name_key, str_asprintf ("!%s", __FUNCTION__));
1412 for (;;)
1414 struct timeval tv = { 1, 0 };
1415 unsigned keepalive = config_get_integer ("global", "keepalive_interval");
1417 TEST_CANCEL ();
1418 select (0, NULL, NULL, NULL, &tv);
1419 cache_adjust_timeout ();
1421 if (keepalive && ++k >= keepalive)
1423 send_status_all (STATUS_KEEPALIVE, NULL);
1424 k = 0;
1428 return NULL;
1431 static int
1432 signal_loop (sigset_t sigset)
1434 int done = 0;
1438 #ifdef HAVE_SIGWAITINFO
1439 siginfo_t info;
1441 memset (&info, 0, sizeof (info));
1442 sigwaitinfo (&sigset, &info);
1443 log_write (_("caught signal %i (%s), sender: pid=%li, uid=%u"),
1444 info.si_signo, strsignal (info.si_signo),
1445 info.si_pid <= 0 ? getpid () : info.si_pid,
1446 info.si_uid <= 0 ? getuid () : info.si_uid);
1448 switch (info.si_signo)
1449 #else
1450 int sig;
1452 sigwait (&sigset, &sig);
1453 log_write (_("caught signal %i (%s)"), sig, strsignal (sig));
1455 switch (sig)
1456 #endif
1458 case SIGHUP:
1460 char c = 0xff;
1461 int r = write (reload_rcfile_fds[1], &c, 1);
1463 if (r == -1)
1464 log_write ("%s: %s: %i: %s", __FILE__, __FUNCTION__, __LINE__,
1465 pwmd_strerror (gpg_err_code_from_syserror ()));
1467 break;
1468 case SIGUSR1:
1469 log_write (_("clearing file cache"));
1470 cache_clear (NULL, NULL, 1, 0);
1471 send_status_all (STATUS_CACHE, NULL);
1472 break;
1473 default:
1474 done = 1;
1475 break;
1478 while (!done);
1480 return done;
1483 static void
1484 catchsig (int sig, siginfo_t *info, void *data)
1486 static int done;
1488 (void)sig;
1489 (void)info;
1490 (void)data;
1492 if (done)
1493 return;
1495 #ifdef HAVE_BACKTRACE
1496 BACKTRACE (__FUNCTION__);
1497 #endif
1498 done = 1;
1499 longjmp (jmp, 1);
1502 static void
1503 cancel_all_clients ()
1505 unsigned i, t;
1507 MUTEX_LOCK (&cn_mutex);
1508 t = slist_length (cn_thread_list);
1509 for (i = 0; i < t; i++)
1511 struct client_thread_s *thd = slist_nth_data (cn_thread_list, i);
1513 #ifdef HAVE_PTHREAD_CANCEL
1514 pthread_cancel (thd->tid);
1515 #else
1516 pthread_kill (thd->tid, SIGUSR2);
1517 #endif
1520 while (slist_length (cn_thread_list))
1522 MUTEX_UNLOCK (&cn_mutex);
1523 usleep (50000);
1524 MUTEX_LOCK (&cn_mutex);
1527 MUTEX_UNLOCK (&cn_mutex);
1530 static int
1531 server_loop (int sockfd, char **socketpath)
1533 struct sigaction sa = { 0 };
1534 pthread_t cache_timeout_tid;
1535 pthread_t accept_tid;
1536 int cancel_timeout_thread = 0;
1537 int cancel_accept_thread = 0;
1538 sigset_t sigset;
1539 int n;
1540 int segv = 0;
1541 gpg_error_t rc;
1543 init_commands ();
1544 sigemptyset (&sigset);
1546 /* Termination */
1547 sigaddset (&sigset, SIGTERM);
1548 sigaddset (&sigset, SIGINT);
1550 /* Clears the file cache. */
1551 sigaddset (&sigset, SIGUSR1);
1553 /* Configuration file reloading. */
1554 sigaddset (&sigset, SIGHUP);
1556 #ifndef HAVE_PTHREAD_CANCEL
1558 The socket, cache and rcfile threads use this signal when
1559 pthread_cancel() is unavailable. Prevent the main thread from
1560 catching this signal from another process.
1562 sigaddset (&sigset, SIGUSR2);
1563 #endif
1565 sa.sa_sigaction = &catchsig;
1566 sa.sa_flags = SA_SIGINFO;
1568 /* An assertion failure. */
1569 if (sigaction (SIGABRT, &sa, NULL) == -1)
1571 log_write ("%s(%i): sigaction(): %s", __FILE__, __LINE__,
1572 pwmd_strerror (errno));
1573 goto done;
1576 memset (&sa, 0, sizeof (sa));
1577 sa.sa_sigaction = &catchsig;
1578 sa.sa_flags = SA_SIGINFO;
1580 /* Can show a backtrace of the stack in the log. */
1581 if (sigaction (SIGSEGV, &sa, NULL) == -1)
1583 log_write ("%s(%i): sigaction(): %s", __FILE__, __LINE__,
1584 pwmd_strerror (errno));
1585 goto done;
1588 sigaddset (&sigset, SIGABRT);
1589 sigprocmask (SIG_BLOCK, &sigset, NULL);
1591 #ifndef HAVE_PTHREAD_CANCEL
1592 /* Remove this signal from the watched signals in signal_loop(). */
1593 sigdelset (&sigset, SIGUSR2);
1594 #endif
1596 char *p = get_username (getuid());
1597 log_write (_("%s started for user %s"), PACKAGE_STRING PWMD_GIT_HASH, p);
1598 xfree (p);
1600 #ifdef WITH_GNUTLS
1601 if (config_get_boolean ("global", "enable_tcp"))
1602 log_write (_("Listening on %s and TCP port %i"), *socketpath,
1603 config_get_integer ("global", "tcp_port"));
1604 else
1605 log_write (_("Listening on %s"), *socketpath);
1606 #else
1607 log_write (_("Listening on %s"), *socketpath);
1608 #endif
1610 rc = create_thread (cache_timer_thread, NULL, &cache_timeout_tid, 0);
1611 if (rc)
1613 log_write ("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1614 pwmd_strerror (rc));
1615 goto done;
1618 if (pipe (reload_rcfile_fds) == -1)
1620 log_write ("%s(%i): pipe(): %s", __FILE__, __LINE__,
1621 pwmd_strerror (gpg_err_code_from_syserror ()));
1622 goto done;
1625 cancel_timeout_thread = 1;
1626 rc = create_thread (accept_thread, &sockfd, &accept_tid, 0);
1627 if (rc)
1629 log_write ("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1630 pwmd_strerror (rc));
1631 goto done;
1634 cancel_accept_thread = 1;
1635 if (!setjmp (jmp))
1636 signal_loop (sigset);
1637 else
1638 segv = 1;
1640 done:
1642 * We're out of the main server loop. This happens when a signal was sent
1643 * to terminate the daemon. Cancel all clients and exit.
1645 if (cancel_accept_thread)
1647 #ifdef HAVE_PTHREAD_CANCEL
1648 n = pthread_cancel (accept_tid);
1649 #else
1650 n = pthread_kill (accept_tid, SIGUSR2);
1651 #endif
1652 if (!n)
1653 pthread_join (accept_tid, NULL);
1656 if (cancel_timeout_thread)
1658 #ifdef HAVE_PTHREAD_CANCEL
1659 n = pthread_cancel (cache_timeout_tid);
1660 #else
1661 n = pthread_kill (cache_timeout_tid, SIGUSR2);
1662 #endif
1663 if (!n)
1664 pthread_join (cache_timeout_tid, NULL);
1667 #ifdef WITH_GNUTLS
1668 tls_start_stop (1);
1669 #endif
1670 shutdown (sockfd, SHUT_RDWR);
1671 close (sockfd);
1672 unlink (*socketpath);
1673 xfree (*socketpath);
1674 *socketpath = NULL;
1675 MUTEX_LOCK (&cn_mutex);
1676 n = slist_length (cn_thread_list);
1677 MUTEX_UNLOCK (&cn_mutex);
1679 if (n && !segv)
1680 cancel_all_clients ();
1681 else
1682 free_all_clients ();
1684 cache_deinit ();
1685 deinit_commands ();
1686 return segv ? EXIT_FAILURE : EXIT_SUCCESS;
1689 static void
1690 usage (const char *pn, int status)
1692 FILE *fp = status == EXIT_FAILURE ? stderr : stdout;
1694 fprintf (fp, _("Usage: %s [OPTIONS] [file1] [...]\n"
1695 " --homedir alternate pwmd home directory (~/.pwmd)\n"
1696 " -f, --rcfile=filename load the specified configuration file\n"
1697 " (~/.pwmd/config)\n"
1698 " --kill terminate an existing instance of pwmd\n"
1699 " -n, --no-fork run as a foreground process\n"
1700 " --disable-dump disable the LIST, XPATH and DUMP commands\n"
1701 " --ignore, --force ignore cache pushing errors during startup\n"
1702 " -I, --import=filename import a pwmd DTD formatted XML file)\n"
1703 " -k, --passphrase-file=file for use when importing\n"
1704 " -o, --outfile=filename output file when importing\n"
1705 " --keyid=fpr[,..] public key to use when encrypting\n"
1706 " --sign-keyid=fpr fingerprint of the signing key to use\n"
1707 " -s, --symmetric use conventional encryption with optional signer\n"
1708 " --userid=string name and email address to use when importing\n"
1709 " --algo=string algorithm to use when importing (engine default)\n"
1710 " --expire=seconds key expiry time when importing (3 years)\n"
1711 " --no-passphrase don't require a passphrase when importing\n"
1712 " --debug=[a:..][,g:N][,t:N] enable debugging (a:[ixedsc],g:[1-9],t:[0-N])\n"
1713 " --help this help text\n"
1714 " --version show version and compile time features\n"),
1715 pn);
1716 exit (status);
1719 static void
1720 unlink_stale_socket (const char *sock, const char *pidfile)
1722 log_write (_ ("removing stale socket %s"), sock);
1723 unlink (sock);
1724 unlink (pidfile);
1727 static int
1728 test_pidfile (const char *path, const char *sock, char *buf, size_t buflen,
1729 char **pidfile, int create, mode_t mode, int terminate)
1731 long pid;
1732 int fd;
1733 size_t len;
1735 if (!create)
1737 snprintf (buf, buflen, "%s.pid", path);
1738 *pidfile = str_dup (buf);
1739 fd = open (buf, O_RDONLY);
1741 else
1742 fd = open (*pidfile, O_CREAT|O_WRONLY|O_TRUNC, mode);
1744 if (fd == -1)
1746 if (!create && errno != ENOENT)
1748 log_write ("%s: %s", buf, pwmd_strerror (errno));
1749 xfree (*pidfile);
1750 *pidfile = NULL;
1751 return -1;
1753 else if (!create && !terminate)
1754 return 0;
1756 log_write ("%s: %s", *pidfile, strerror (errno));
1757 return -1;
1760 if (create)
1762 pid = getpid();
1763 snprintf (buf, buflen, "%li", pid);
1764 ssize_t ret = write (fd, buf, strlen (buf));
1765 if (ret == -1)
1766 log_write ("%s (%i): %s", __FUNCTION__, __LINE__,
1767 pwmd_strerror (gpg_error_from_syserror ()));
1768 close (fd);
1769 return 0;
1772 if (buflen < 8)
1774 close (fd);
1775 log_write ("%s (%i): %s", __FUNCTION__, __LINE__,
1776 pwmd_strerror (GPG_ERR_BUFFER_TOO_SHORT));
1777 return -1;
1780 len = read (fd, buf, buflen);
1781 close (fd);
1782 if (len == 0)
1784 unlink_stale_socket (path, *pidfile);
1785 return 0;
1788 if (sscanf (buf, "%li", &pid) != 1 || pid == 0)
1790 if (!terminate)
1792 unlink_stale_socket (path, *pidfile);
1793 return 0;
1797 if (kill (pid, 0) == -1)
1799 unlink_stale_socket (path, *pidfile);
1800 return 0;
1803 if (terminate)
1805 if (kill (pid, SIGTERM) == -1)
1806 log_write ("%s: %s", path, pwmd_strerror (errno));
1808 else
1809 log_write (_ ("an instance for socket %s is already running"), path);
1811 xfree (*pidfile);
1812 *pidfile = NULL;
1813 return 1;
1816 static unsigned
1817 parse_debug_level (const char *str, unsigned *debug, int *gpgme, int *tls)
1819 const char *p;
1820 unsigned level = 0;
1821 int gl = 0, tl = 0;
1823 for (p = str; p && *p; p++)
1825 if (*p == 'a') // assuan debug flags
1827 if (*++p != ':')
1828 return 1;
1830 while (*++p)
1832 switch (*p)
1834 case 'i':
1835 level |= ASSUAN_LOG_INIT;
1836 break;
1837 case 'x':
1838 level |= ASSUAN_LOG_CTX;
1839 break;
1840 case 'e':
1841 level |= ASSUAN_LOG_ENGINE;
1842 break;
1843 case 'd':
1844 level |= ASSUAN_LOG_DATA;
1845 break;
1846 case 's':
1847 level |= ASSUAN_LOG_SYSIO;
1848 break;
1849 case 'c':
1850 level |= ASSUAN_LOG_CONTROL;
1851 break;
1852 case ',':
1853 break;
1854 default:
1855 return 1;
1858 if (*p == ',')
1859 break;
1862 if (!*p)
1863 break;
1865 else if (*p == 'g' || *p == 't') // gpgme and TLS debug level
1867 int t = *p == 't';
1868 int n;
1870 if (*++p != ':')
1871 return 1;
1873 if (!isdigit (*++p))
1874 return 1;
1876 n = atoi (p);
1877 if (t)
1878 tl = n;
1879 else
1880 gl = n;
1882 if (tl < 0 || gl < 0 || gl > 9)
1883 return 1;
1885 while (isdigit (*p))
1886 p++;
1888 p--;
1889 if (*(p+1) && *(p+1) != ',')
1890 return 1;
1891 else if (*(p+1))
1892 p++;
1894 else
1895 return 1;
1898 if (tl)
1899 *tls = tl;
1901 if (gl)
1902 *gpgme = gl;
1904 *debug = level;
1905 return 0;
1909 main (int argc, char *argv[])
1911 int opt;
1912 struct sockaddr_un addr;
1913 char buf[PATH_MAX];
1914 char *socketpath = NULL, *socketdir, *socketname = NULL;
1915 char *socketarg = NULL;
1916 char *datadir = NULL;
1917 char *pidfile = NULL;
1918 mode_t mode = 0600;
1919 int x;
1920 char *p;
1921 char **cache_push = NULL;
1922 char *import = NULL, *keyid = NULL, *sign_keyid = NULL;
1923 char *userid = NULL;
1924 char *algo = NULL;
1925 long expire = 0;
1926 int no_passphrase = 0;
1927 int estatus = EXIT_FAILURE;
1928 int sockfd;
1929 char *outfile = NULL;
1930 int do_unlink = 0;
1931 int secure = 0;
1932 int show_version = 0;
1933 int force = 0;
1934 gpg_error_t rc;
1935 char *keyfile = NULL;
1936 int exists;
1937 int optindex;
1938 int terminate = 0;
1939 int sym = 0;
1940 int gpgme_level = -1;
1941 int tls_level = -1;
1942 int backlog = 0;
1943 /* Must maintain the same order as longopts[] */
1944 enum
1946 OPT_VERSION, OPT_HELP, OPT_HOMEDIR, OPT_NO_FORK, OPT_DISABLE_DUMP,
1947 OPT_FORCE, OPT_RCFILE, OPT_PASSPHRASE_FILE, OPT_IMPORT, OPT_OUTFILE,
1948 OPT_KEYID, OPT_SIGN_KEYID, OPT_SYMMETRIC, OPT_USERID, OPT_ALGO, OPT_EXPIRE,
1949 OPT_NOPASSPHRASE, OPT_KILL, OPT_DEBUG
1951 const char *optstring = "nf:C:k:I:o:s";
1952 const struct option longopts[] = {
1953 {"version", no_argument, 0, 0},
1954 {"help", no_argument, 0, 0},
1955 {"homedir", required_argument, 0, 0},
1956 {"no-fork", no_argument, 0, 'n'},
1957 {"disable_dump", no_argument, 0, 0},
1958 {"force", no_argument, 0, 0},
1959 {"rcfile", required_argument, 0, 'f'},
1960 {"passphrase-file", required_argument, 0, 'k'},
1961 {"import", required_argument, 0, 'I'},
1962 {"outfile", required_argument, 0, 'o'},
1963 {"keyid", required_argument, 0, 0},
1964 {"sign-keyid", required_argument, 0, 0},
1965 {"symmetric", no_argument, 0, 's'},
1966 {"userid", required_argument, 0, 0},
1967 {"algo", required_argument, 0, 0},
1968 {"expire", required_argument, 0, 0},
1969 {"no-passphrase", no_argument, 0, 0},
1970 {"kill", no_argument, 0, 0},
1971 {"debug", required_argument, 0, 0},
1972 {0, 0, 0, 0}
1975 log_fd = -1;
1976 cmdline = 1;
1977 expire = time (NULL) + DEFAULT_EXPIRE;
1979 #ifndef DEBUG
1980 #ifdef HAVE_SETRLIMIT
1981 struct rlimit rl;
1983 rl.rlim_cur = rl.rlim_max = 0;
1985 if (setrlimit (RLIMIT_CORE, &rl) != 0)
1986 err (EXIT_FAILURE, "setrlimit()");
1987 #endif
1989 #ifdef HAVE_PR_SET_DUMPABLE
1990 prctl (PR_SET_DUMPABLE, 0);
1991 #endif
1992 #endif
1994 #ifdef ENABLE_NLS
1995 setlocale (LC_ALL, "");
1996 bindtextdomain ("pwmd", LOCALEDIR);
1997 textdomain ("pwmd");
1998 #endif
2000 while ((opt = getopt_long (argc, argv, optstring, longopts, &optindex))
2001 != -1)
2003 switch (opt)
2005 case 'I':
2006 import = optarg;
2007 break;
2008 case 'k':
2009 keyfile = optarg;
2010 break;
2011 case 'o':
2012 outfile = optarg;
2013 break;
2014 case 'n':
2015 nofork = 1;
2016 break;
2017 case 'f':
2018 rcfile = str_dup (optarg);
2019 break;
2020 case 's':
2021 sym = 1;
2022 break;
2023 default:
2024 usage (argv[0], EXIT_FAILURE);
2025 break;
2026 case 0:
2027 switch (optindex)
2029 case OPT_DEBUG:
2030 if (parse_debug_level (optarg, &assuan_level, &gpgme_level,
2031 &tls_level))
2032 usage (argv[0], EXIT_FAILURE);
2033 break;
2034 case OPT_SYMMETRIC:
2035 sym = 1;
2036 break;
2037 case OPT_VERSION:
2038 show_version = 1;
2039 break;
2040 case OPT_HELP:
2041 usage (argv[0], EXIT_SUCCESS);
2042 break;
2043 case OPT_HOMEDIR:
2044 homedir = str_dup (optarg);
2045 break;
2046 case OPT_NO_FORK:
2047 nofork = 1;
2048 break;
2049 case OPT_DISABLE_DUMP:
2050 secure = 1;
2051 break;
2052 case OPT_FORCE:
2053 force = 1;
2054 break;
2055 case OPT_RCFILE:
2056 rcfile = str_dup (optarg);
2057 break;
2058 case OPT_PASSPHRASE_FILE:
2059 keyfile = optarg;
2060 break;
2061 case OPT_IMPORT:
2062 import = optarg;
2063 break;
2064 case OPT_OUTFILE:
2065 outfile = optarg;
2066 break;
2067 case OPT_KEYID:
2068 keyid = optarg;
2069 break;
2070 case OPT_SIGN_KEYID:
2071 sign_keyid = optarg;
2072 break;
2073 case OPT_USERID:
2074 userid = optarg;
2075 break;
2076 case OPT_ALGO:
2077 algo = optarg;
2078 break;
2079 case OPT_EXPIRE:
2080 errno = rc = 0;
2081 expire = strtoul (optarg, &p, 10);
2083 if (!errno && p && *p)
2084 rc = GPG_ERR_INV_VALUE;
2085 else if (expire == ULONG_MAX)
2086 rc = GPG_ERR_INV_VALUE;
2087 else if (errno)
2088 rc = gpg_error_from_syserror ();
2090 if (rc)
2091 usage (argv[0], EXIT_FAILURE);
2092 break;
2093 case OPT_NOPASSPHRASE:
2094 no_passphrase = 1;
2095 break;
2096 case OPT_KILL:
2097 terminate = 1;
2098 break;
2099 default:
2100 usage (argv[0], EXIT_FAILURE);
2105 if (show_version)
2107 printf (_("%s\n\n"
2108 "Copyright (C) 2006-2023\n"
2109 "%s\n"
2110 "Released under the terms of the GPL v2.\n\n"
2111 "Compile time features:\n%s"), PACKAGE_STRING PWMD_GIT_HASH,
2112 PACKAGE_BUGREPORT,
2113 #ifdef PWMD_HOMEDIR
2114 "+PWMD_HOMEDIR=" PWMD_HOMEDIR "\n"
2115 #endif
2116 #ifdef WITH_GNUTLS
2117 "+WITH_GNUTLS\n"
2118 #else
2119 "-WITH_GNUTLS\n"
2120 #endif
2121 #ifdef WITH_LIBACL
2122 "+WITH_LIBACL\n"
2123 #else
2124 "-WITH_LIBACL\n"
2125 #endif
2126 #ifdef DEBUG
2127 "+DEBUG\n"
2128 #else
2129 "-DEBUG\n"
2130 #endif
2131 #ifdef MEM_DEBUG
2132 "+MEM_DEBUG\n"
2133 #else
2134 "-MEM_DEBUG\n"
2135 #endif
2136 #ifdef MUTEX_DEBUG
2137 "+MUTEX_DEBUG\n"
2138 #else
2139 "-MUTEX_DEBUG\n"
2140 #endif
2142 exit (EXIT_SUCCESS);
2145 if (gpgme_level != -1)
2147 char s[2] = { gpgme_level + '0', 0 };
2149 if (getenv ("GPGME_DEBUG"))
2150 log_write (_ ("Overriding GPGME_DEBUG environment with level %u!"),
2151 gpgme_level);
2153 gpgme_set_global_flag ("debug", s);
2156 if (setup_crypto ())
2157 exit (EXIT_FAILURE);
2159 #ifdef WITH_GNUTLS
2160 tls_level = tls_level == -1 ? 1 : tls_level;
2161 gnutls_global_set_log_level (tls_level);
2162 tls_fd = -1;
2163 tls6_fd = -1;
2164 #endif
2165 rc = xml_init ();
2166 if (rc)
2167 errx (EXIT_FAILURE, "%s", "xml_init() failed");
2169 if (!homedir)
2170 #ifdef PWMD_HOMEDIR
2171 homedir = str_dup(PWMD_HOMEDIR);
2172 #else
2173 homedir = str_asprintf ("%s/.pwmd", get_home_dir());
2174 #endif
2176 if (mkdir (homedir, 0700) == -1 && errno != EEXIST)
2177 err (EXIT_FAILURE, "%s", homedir);
2179 if (!rcfile)
2180 rcfile = str_asprintf ("%s/config", homedir);
2182 pthread_key_create (&last_error_key, free_key);
2183 #ifndef HAVE_PTHREAD_CANCEL
2184 pthread_key_create (&signal_thread_key, free_key);
2185 #endif
2187 pthread_mutexattr_t attr;
2188 pthread_mutexattr_init (&attr);
2189 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
2190 pthread_mutex_init (&rcfile_mutex, &attr);
2191 global_config = config_parse (rcfile, 0);
2192 if (!global_config)
2194 pthread_mutexattr_destroy (&attr);
2195 pthread_mutex_destroy (&rcfile_mutex);
2196 exit (EXIT_FAILURE);
2199 p = config_get_string ("global", "gpg_homedir");
2200 if (!p)
2201 datadir = str_asprintf ("%s/.gnupg", homedir);
2202 else
2203 datadir = expand_homedir (p);
2205 xfree (p);
2206 if (mkdir (datadir, 0700) == -1 && errno != EEXIST)
2207 err (EXIT_FAILURE, "%s", datadir);
2209 rc = gpgme_set_engine_info (GPGME_PROTOCOL_OpenPGP, NULL, datadir);
2210 if (rc)
2211 errx (EXIT_FAILURE, "%s: %s", datadir, pwmd_strerror (rc));
2212 xfree (datadir);
2214 snprintf (buf, sizeof (buf), "%s/data", homedir);
2215 if (mkdir (buf, 0700) == -1 && errno != EEXIST)
2216 err (EXIT_FAILURE, "%s", buf);
2218 datadir = str_dup (buf);
2219 pthread_cond_init (&rcfile_cond, NULL);
2220 pthread_mutex_init (&cn_mutex, &attr);
2221 pthread_mutexattr_destroy (&attr);
2223 setup_logging ();
2225 x = config_get_int_param (global_config, "global", "priority", &exists);
2226 if (exists && x != atoi(INVALID_PRIORITY))
2228 errno = 0;
2229 if (setpriority (PRIO_PROCESS, 0, x) == -1)
2231 log_write ("setpriority(): %s",
2232 pwmd_strerror (gpg_error_from_errno (errno)));
2233 goto do_exit;
2236 #ifdef HAVE_MLOCKALL
2237 if (disable_mlock == 0 && mlockall (MCL_CURRENT | MCL_FUTURE) == -1)
2239 log_write ("mlockall(): %s",
2240 pwmd_strerror (gpg_error_from_errno (errno)));
2241 goto do_exit;
2243 #endif
2245 rc = cache_init ();
2246 if (rc)
2248 log_write ("pwmd: ERR %i: %s", rc, pwmd_strerror (rc));
2249 exit (EXIT_FAILURE);
2252 if (import)
2254 char **keyids = NULL;
2256 if (!outfile || !*outfile || argc != optind)
2257 usage (argv[0], EXIT_FAILURE);
2259 if (keyid)
2260 keyids = str_split (keyid, ",", 0);
2261 else if (!userid && !sym)
2262 usage (argv[0], EXIT_FAILURE);
2264 rc = xml_import (import, outfile, keyids, sign_keyid, keyfile, userid,
2265 algo, expire, no_passphrase, sym);
2266 strv_free (keyids);
2267 if (rc)
2269 if (gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
2270 rc = gpg_error (rc);
2272 log_write ("%s: %u: %s", import, rc, pwmd_strerror (rc));
2275 config_free (global_config);
2276 xfree (rcfile);
2277 exit (rc ? EXIT_FAILURE : EXIT_SUCCESS);
2280 p = config_get_string ("global", "socket_path");
2281 if (!p)
2282 p = str_asprintf ("%s/socket", homedir);
2284 socketarg = expand_homedir (p);
2285 xfree (p);
2287 if (!secure)
2288 disable_list_and_dump = config_get_boolean ("global",
2289 "disable_list_and_dump");
2290 else
2291 disable_list_and_dump = secure;
2293 cache_push = config_get_list ("global", "cache_push");
2295 while (optind < argc)
2297 if (strv_printf (&cache_push, "%s", argv[optind++]) == 0)
2298 errx (EXIT_FAILURE, "%s", pwmd_strerror (GPG_ERR_ENOMEM));
2301 if (!strchr (socketarg, '/'))
2303 socketdir = getcwd (buf, sizeof (buf));
2304 socketname = str_dup (socketarg);
2305 socketpath = str_asprintf ("%s/%s", socketdir, socketname);
2307 else
2309 socketname = str_dup (strrchr (socketarg, '/')+1);
2310 socketarg[strlen (socketarg) - strlen (socketname) - 1] = 0;
2311 socketdir = str_dup (socketarg);
2312 socketpath = str_asprintf ("%s/%s", socketdir, socketname);
2315 if (chdir (datadir))
2317 log_write ("%s: %s", datadir,
2318 pwmd_strerror (gpg_error_from_errno (errno)));
2319 unlink (socketpath);
2320 goto do_exit;
2323 x = test_pidfile (socketpath, socketname, buf, sizeof(buf), &pidfile, 0,
2324 mode, terminate);
2325 if (!terminate && x)
2326 goto do_exit;
2327 else if (terminate)
2329 estatus = x != 1 ? EXIT_FAILURE : EXIT_SUCCESS;
2330 goto do_exit;
2334 * bind() doesn't like the full pathname of the socket or any non alphanum
2335 * characters so change to the directory where the socket is wanted then
2336 * create it then change to datadir.
2338 if (chdir (socketdir))
2340 log_write ("%s: %s", socketdir,
2341 pwmd_strerror (gpg_error_from_errno (errno)));
2342 goto do_exit;
2345 xfree (socketdir);
2347 if ((sockfd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1)
2349 log_write ("socket(): %s", pwmd_strerror (gpg_error_from_errno (errno)));
2350 goto do_exit;
2353 addr.sun_family = AF_UNIX;
2354 snprintf (addr.sun_path, sizeof (addr.sun_path), "%s", socketname);
2355 do_unlink = 1;
2356 if (bind (sockfd, (struct sockaddr *) &addr, sizeof (struct sockaddr)) ==
2359 log_write ("bind(): %s", pwmd_strerror (gpg_error_from_errno (errno)));
2361 if (errno == EADDRINUSE)
2363 do_unlink = 0;
2364 log_write (_("Either there is another pwmd running or '%s' is a \n"
2365 "stale socket. Please remove it manually."), socketpath);
2368 goto do_exit;
2372 char *t = config_get_string ("global", "socket_perms");
2373 mode_t mask;
2375 if (t)
2377 mode = strtol (t, NULL, 8);
2378 mask = umask (0);
2379 xfree (t);
2381 if (chmod (socketname, mode) == -1)
2383 log_write ("%s: %s", socketname,
2384 pwmd_strerror (gpg_error_from_errno (errno)));
2385 close (sockfd);
2386 umask (mask);
2387 goto do_exit;
2390 umask (mask);
2394 if (chdir (datadir))
2396 log_write ("%s: %s", datadir,
2397 pwmd_strerror (gpg_error_from_errno (errno)));
2398 close (sockfd);
2399 goto do_exit;
2402 xfree (datadir);
2403 #ifdef WITH_GNUTLS
2404 if (config_get_boolean ("global", "enable_tcp"))
2406 if (!tls_start_stop (0))
2408 close (sockfd);
2409 goto do_exit;
2412 #endif
2415 * Set the cache entry for a file. Prompts for the password.
2417 if (cache_push)
2419 for (opt = 0; cache_push[opt]; opt++)
2421 struct crypto_s *crypto = NULL;
2422 char *pw_file = config_get_string (cache_push[opt],
2423 "passphrase_file");
2424 rc = crypto_init (&crypto, NULL, cache_push[opt], pw_file != NULL,
2425 pw_file);
2427 if (!rc)
2429 crypto->flags |= pw_file ? CRYPTO_FLAG_KEYFILE : 0;
2430 crypto->keyfile = pw_file;
2432 else
2433 xfree (pw_file);
2435 if (rc)
2437 estatus = EXIT_FAILURE;
2438 goto do_exit;
2441 rc = do_cache_push (crypto);
2442 if (rc && !force)
2444 log_write ("ERR %u: %s", rc, pwmd_strerror(rc));
2445 strv_free (cache_push);
2446 log_write (_ ("Failed to add a file to the cache. Use --force to force startup. Exiting."));
2447 cache_clear (NULL, NULL, 1, 0);
2448 estatus = EXIT_FAILURE;
2449 crypto_free (crypto);
2450 (void)cache_kill_scd ();
2451 goto do_exit;
2453 else if (rc)
2454 log_write ("%s: %s", crypto->filename, pwmd_strerror(rc));
2455 else
2456 log_write (_("Successfully added '%s' to the cache."),
2457 crypto->filename);
2459 crypto_free (crypto);
2462 (void)cache_kill_scd ();
2463 strv_free (cache_push);
2464 log_write (!nofork ? _("Done. Daemonizing...") :
2465 _("Done. Waiting for connections..."));
2468 backlog = config_get_integer ("global", "backlog");
2469 if (listen (sockfd, backlog) == -1)
2471 log_write ("listen(): %s", pwmd_strerror (gpg_error_from_errno (errno)));
2472 goto do_exit;
2475 /* A client should set these with the OPTION command. */
2476 unsetenv ("DISPLAY");
2477 unsetenv ("GPG_TTY");
2478 unsetenv ("TERM");
2480 if (!nofork)
2482 switch (fork ())
2484 case -1:
2485 log_write ("fork(): %s",
2486 pwmd_strerror (gpg_error_from_errno (errno)));
2487 goto do_exit;
2488 case 0:
2489 close (0);
2490 close (1);
2491 close (2);
2492 setsid ();
2493 break;
2494 default:
2495 _exit (EXIT_SUCCESS);
2499 (void)test_pidfile (socketpath, socketname, buf, sizeof(buf), &pidfile, 1,
2500 mode, 0);
2501 xfree (socketname);
2502 cmdline = 0;
2503 pthread_key_create (&thread_name_key, free_key);
2504 pthread_setspecific (thread_name_key, str_asprintf ("!%s", __FUNCTION__));
2505 estatus = server_loop (sockfd, &socketpath);
2507 do_exit:
2508 if (socketpath && do_unlink)
2510 unlink (socketpath);
2511 xfree (socketpath);
2514 xfree (socketarg);
2515 #ifdef WITH_GNUTLS
2516 gnutls_global_deinit ();
2517 tls_deinit_params ();
2518 #endif
2519 pthread_cond_destroy (&rcfile_cond);
2520 pthread_mutex_destroy (&rcfile_mutex);
2521 pthread_key_delete (last_error_key);
2522 #ifndef HAVE_PTHREAD_CANCEL
2523 pthread_key_delete (signal_thread_key);
2524 #endif
2526 if (global_config)
2527 config_free (global_config);
2529 free_invoking_users (invoking_users);
2530 xfree (rcfile);
2531 xfree (home_directory);
2532 xfree (homedir);
2533 xml_deinit ();
2535 if (pidfile)
2536 unlink (pidfile);
2537 xfree (pidfile);
2539 if (estatus == EXIT_SUCCESS && !terminate)
2540 log_write (_("pwmd exiting normally"));
2542 pthread_key_delete (thread_name_key);
2543 closelog ();
2545 if (log_fd != -1)
2546 close (log_fd);
2548 xfree (logfile);
2549 exit (estatus);
2552 gpg_error_t lock_flock (assuan_context_t ctx, const char *filename,
2553 int type, int *fd)
2555 gpg_error_t rc = 0;
2557 #ifdef HAVE_FLOCK
2558 rc = open_check_file (filename, fd, NULL, 1);
2559 if (rc)
2560 return rc;
2562 TRY_FLOCK (ctx, *fd, type, rc);
2563 if (rc)
2565 close (*fd);
2566 *fd = -1;
2568 #endif
2570 return rc;
2573 void unlock_flock (int *fd)
2575 #ifdef HAVE_FLOCK
2576 if (*fd != -1)
2577 close (*fd);
2579 *fd = -1;
2580 #endif