Update copyright header to specify GPL version 2.
[pwmd.git] / src / pwmd.c
blobe49be23f27c3438bc0dab4be92adc82fd6498ddd
1 /*
2 Copyright (C) 2006-2021 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 #include <unistd.h>
25 #include <err.h>
26 #include <ctype.h>
27 #include <string.h>
28 #include <sys/socket.h>
29 #include <sys/un.h>
30 #include <signal.h>
31 #include <stdarg.h>
32 #include <string.h>
33 #include <sys/wait.h>
34 #include <fcntl.h>
35 #include <pwd.h>
36 #include <grp.h>
37 #include <pthread.h>
38 #include <sys/mman.h>
39 #include <termios.h>
40 #include <assert.h>
41 #include <syslog.h>
42 #include <netinet/in.h>
43 #include <arpa/inet.h>
44 #include <netdb.h>
45 #include <sys/time.h>
46 #include <sys/resource.h>
47 #include <setjmp.h>
48 #include <errno.h>
49 #include <poll.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 "util-misc.h"
77 #include "mem.h"
78 #include "xml.h"
79 #include "common.h"
80 #include "commands.h"
81 #include "cache.h"
82 #include "util-string.h"
83 #include "mutex.h"
84 #include "rcfile.h"
85 #include "crypto.h"
86 #include "acl.h"
87 #include "version.h"
89 static int quit;
90 static int cmdline;
91 static jmp_buf jmp;
92 static int nofork;
93 static int log_fd;
94 static unsigned assuan_level;
95 pthread_key_t thread_name_key;
96 pthread_mutex_t cn_mutex;
97 struct slist_s *cn_thread_list;
99 #ifndef HAVE_PTHREAD_CANCEL
100 #define INIT_SIGNAL(s, cb) do { \
101 int *n = xmalloc (sizeof (int)); \
102 *n = 0; \
103 pthread_setspecific (signal_thread_key, n); \
104 struct sigaction act; \
105 sigset_t sigset; \
106 sigemptyset (&sigset); \
107 sigaddset (&sigset, s); \
108 pthread_sigmask (SIG_UNBLOCK, &sigset, NULL); \
109 memset (&act, 0, sizeof(act)); \
110 act.sa_flags = SA_SIGINFO; \
111 act.sa_mask = sigset; \
112 act.sa_sigaction = cb; \
113 sigaction (s, &act, NULL); \
114 } while (0)
116 static void
117 catch_thread_signal (int sig, siginfo_t *info, void *ctx)
119 int *n = (int *) pthread_getspecific (signal_thread_key);
121 *n = 1;
123 #endif
125 static void
126 setup_logging ()
128 int n = config_get_boolean ("global", "enable_logging");
130 if (n)
132 char *p = config_get_string ("global", "log_path");
134 if (!p || (logfile && p && log_fd != -1 && strcmp(p, logfile)))
136 if (log_fd != -1)
137 close (log_fd);
139 log_fd = -1;
142 xfree (logfile);
143 logfile = NULL;
144 if (p)
145 logfile = expand_homedir (p);
146 xfree (p);
148 else
150 xfree (logfile);
151 logfile = NULL;
152 if (log_fd != -1)
153 close(log_fd);
155 log_fd = -1;
156 closelog ();
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 *
165 reload_rcfile_thread (void *arg)
167 #ifndef HAVE_PTHREAD_CANCEL
168 INIT_SIGNAL (SIGUSR2, catch_thread_signal);
169 #endif
171 #ifdef HAVE_PR_SET_NAME
172 prctl (PR_SET_NAME, "reload rcfile");
173 #endif
174 pthread_setspecific (thread_name_key, str_asprintf ("!%s", __FUNCTION__));
175 MUTEX_LOCK (&rcfile_mutex);
177 (void)arg;
179 for (;;)
181 struct slist_s *keep = NULL;
182 struct slist_s *config;
183 int b = disable_list_and_dump;
184 #ifdef WITH_GNUTLS
185 char *prio;
186 char *prio2 = NULL;
187 #endif
189 pthread_cleanup_push (release_mutex_cb, &rcfile_mutex);
190 pthread_cond_wait (&rcfile_cond, &rcfile_mutex);
191 TEST_CANCEL ();
192 keep = config_keep_save ();
193 log_write (_("reloading configuration file '%s'"), rcfile);
195 #ifdef WITH_GNUTLS
196 prio = config_get_string ("global", "tls_cipher_suite");
197 #endif
198 config = config_parse (rcfile, 1);
199 if (config)
201 config_free (global_config);
202 global_config = config;
203 setup_logging ();
206 config_keep_restore (keep);
207 disable_list_and_dump = !disable_list_and_dump ? b : 1;
209 #ifdef WITH_GNUTLS
210 /* Restart listening sockets since they may have changed. */
211 tls_start_stop (1);
212 tls_start_stop (0);
214 prio2 = config_get_string ("global", "tls_cipher_suite");
215 if ((prio2 && (!prio || strcmp (prio, prio2))) || (prio && !prio2))
216 tls_rehandshake ();
218 xfree (prio2);
219 xfree (prio);
220 #endif
221 crypto_set_keepalive ();
222 pthread_cleanup_pop (0);
225 MUTEX_UNLOCK (&rcfile_mutex);
226 return NULL;
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);
713 static void
714 free_all_clients ()
716 MUTEX_LOCK (&cn_mutex);
717 pthread_cleanup_push (release_mutex_cb, &cn_mutex);
719 while (slist_length (cn_thread_list))
721 struct client_thread_s *thd = slist_nth_data (cn_thread_list, 0);
723 free_client_cb (thd);
724 thd->eof = 1;
727 pthread_cleanup_pop (1);
730 static gpg_error_t
731 send_msg_queue (struct client_thread_s *thd)
733 MUTEX_LOCK (&thd->status_mutex);
734 gpg_error_t rc = 0;
735 char c;
736 ssize_t ret;
738 ret = read (thd->status_msg_pipe[0], &c, 1);
739 rc = gpg_error_from_syserror ();
740 if (ret == -1 && gpg_err_code (rc) != GPG_ERR_EAGAIN)
741 log_write ("%s (%i): %s", __FUNCTION__, __LINE__, pwmd_strerror (rc));
742 else
743 rc = 0;
745 thd->wrote_status = 0;
747 while (thd->msg_queue)
749 struct status_msg_s *msg = thd->msg_queue;
751 thd->msg_queue = thd->msg_queue->next;
752 MUTEX_UNLOCK (&thd->status_mutex);
753 pthread_cleanup_push (xfree, msg);
754 pthread_cleanup_push (xfree, msg->line);
755 rc = send_status (thd->cl->ctx, msg->s, msg->line);
756 pthread_cleanup_pop (1);
757 pthread_cleanup_pop (1);
758 MUTEX_LOCK (&thd->status_mutex);
759 if (rc)
760 break;
763 MUTEX_UNLOCK (&thd->status_mutex);
764 if (rc && gpg_err_code (rc) != GPG_ERR_EPIPE)
765 log_write ("%s (%i): %s", __FUNCTION__, __LINE__, pwmd_strerror (rc));
767 return rc;
770 static void *
771 client_thread (void *data)
773 struct client_thread_s *thd = data;
774 struct client_s *cl = xcalloc (1, sizeof (struct client_s));
775 struct slist_s *list;
776 gpg_error_t rc = 0;
777 #ifndef HAVE_PTHREAD_CANCEL
778 INIT_SIGNAL (SIGUSR2, catch_thread_signal);
779 #endif
781 #ifdef HAVE_PR_SET_NAME
782 prctl (PR_SET_NAME, "client");
783 #endif
784 pthread_setspecific (thread_name_key, str_dup (__FUNCTION__));
786 if (!cl)
788 log_write ("%s(%i): %s", __FILE__, __LINE__,
789 pwmd_strerror (GPG_ERR_ENOMEM));
790 return NULL;
793 MUTEX_LOCK (&cn_mutex);
794 pthread_cleanup_push (free_client_cb, thd);
795 thd->cl = cl;
796 cl->thd = thd;
797 cl->flock_fd = -1;
799 list = slist_append (cn_thread_list, thd);
800 if (list)
801 cn_thread_list = list;
802 else
804 log_write ("%s(%i): %s", __FILE__, __LINE__,
805 pwmd_strerror (GPG_ERR_ENOMEM));
806 MUTEX_UNLOCK (&cn_mutex);
807 return NULL;
810 if (fcntl (thd->status_msg_pipe[0], F_SETFL, O_NONBLOCK) == -1)
811 rc = gpg_error_from_errno (errno);
813 if (!rc)
814 if (fcntl (thd->status_msg_pipe[1], F_SETFL, O_NONBLOCK) == -1)
815 rc = gpg_error_from_errno (errno);
817 MUTEX_UNLOCK (&cn_mutex);
819 if (rc)
821 log_write ("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror (rc));
822 goto done;
825 if (new_connection (cl))
827 struct pollfd fds[2];
829 fds[0].fd = thd->fd;
830 fds[0].events = POLLIN;
831 fds[1].fd = thd->status_msg_pipe[0];
832 fds[1].events = POLLIN;
834 send_status_all (STATUS_CLIENTS, NULL);
835 rc = send_status (cl->ctx, STATUS_CACHE, NULL);
836 if (rc)
838 log_write ("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror (rc));
839 goto done;
842 for (;;)
844 int n;
845 int eof;
847 n = poll (fds, sizeof(fds)/sizeof(fds[0]), 100);
848 if (n == -1)
850 log_write ("%s", strerror (errno));
851 break;
854 #ifdef WITH_GNUTLS
855 if (thd->remote && thd->tls && thd->tls->rehandshake)
857 char *prio;
858 int ret;
859 const char *e;
861 if (thd->tls->rehandshake == 1)
863 prio = config_get_string ("global", "tls_cipher_suite");
864 if (!prio)
866 thd->tls->rehandshake = 0;
867 continue;
870 ret = gnutls_priority_set_direct (thd->tls->ses, prio, &e);
871 if (ret == GNUTLS_E_SUCCESS)
873 rc = send_status (cl->ctx, STATUS_REHANDSHAKE, NULL);
874 if (!rc)
876 rc = assuan_send_data (cl->ctx, NULL, 0);
877 if (!rc)
879 ret = gnutls_rehandshake (thd->tls->ses);
880 if (ret)
882 log_write ("%s", gnutls_strerror (ret));
883 thd->tls->rehandshake = 0;
885 else
886 thd->tls->rehandshake = 2;
890 if (rc)
891 log_write ("%s", pwmd_strerror (rc));
893 else
894 log_write ("%s: %s", gnutls_strerror (ret), e);
896 xfree (prio);
897 continue;
900 #endif
902 if (!n)
903 continue;
905 if (fds[1].revents & POLLIN)
907 #ifdef WITH_GNUTLS
908 if (!thd->remote || (thd->tls && !thd->tls->rehandshake))
909 #endif
911 rc = send_msg_queue (thd);
912 if (rc && gpg_err_code (rc) != GPG_ERR_EPIPE)
913 break;
917 #ifdef HAVE_PTHREAD_CANCEL
918 if (!(fds[0].revents & POLLIN))
919 #else
920 if (thd->fd != -1 && !(fds[0].revents & POLLIN))
921 #endif
922 continue;
924 rc = assuan_process_next (cl->ctx, &eof);
925 if (rc || eof)
927 if (gpg_err_code (rc) == GPG_ERR_EOF || eof)
928 break;
930 log_write ("assuan_process_next(): rc=%u %s", rc,
931 pwmd_strerror (rc));
932 if (rc == gpg_error (GPG_ERR_ETIMEDOUT))
933 break;
935 rc = send_error (cl->ctx, rc);
936 if (rc)
938 log_write ("assuan_process_done(): rc=%u %s", rc,
939 pwmd_strerror (rc));
940 break;
944 /* Since the msg queue pipe fd's are non-blocking, check for
945 * pending status msgs here. GPG_ERR_EPIPE can be seen when the
946 * client has already disconnected and will be converted to
947 * GPG_ERR_EOF during assuan_process_next().
949 #ifdef WITH_GNUTLS
950 if (!thd->remote || (thd->tls && !thd->tls->rehandshake))
951 #endif
953 rc = send_msg_queue (thd);
954 if (rc && gpg_err_code (rc) != GPG_ERR_EPIPE)
955 break;
960 done:
961 /* Don't do pthread_exit() here because any set pthread_cleanup_push
962 * functions would be called after a command failed but then the client
963 * exited normally which may lead to a double free. */
964 thd->eof = 1;
965 pthread_cleanup_pop (1);
966 return NULL;
969 static gpg_error_t
970 xml_import (const char *filename, const char *outfile, char **keyid,
971 char *sign_keyid, char *keyfile, const char *userid,
972 const char *algo, long expire, int no_passphrase, int symmetric)
974 xmlDocPtr doc;
975 int fd;
976 struct stat st;
977 int len;
978 xmlChar *xmlbuf = NULL;
979 gpg_error_t rc = 0;
980 struct crypto_s *crypto = NULL;
982 if (strcmp (filename, "-"))
984 rc = open_check_file (filename, &fd, &st, 0);
985 if (rc)
986 return rc;
988 xmlbuf = xmalloc (st.st_size + 1);
989 if (!xmlbuf)
991 close (fd);
992 return GPG_ERR_ENOMEM;
995 if (read (fd, xmlbuf, st.st_size) == -1)
997 rc = gpg_error_from_errno (errno);
998 close (fd);
999 xfree (xmlbuf);
1000 return rc;
1003 xmlbuf[st.st_size] = 0;
1004 close (fd);
1006 else
1008 #define BUFSIZE 8196
1009 size_t size = 0, xlen = 0;
1011 for (;;)
1013 size_t ret;
1014 xmlChar *tmp;
1016 tmp = xrealloc (xmlbuf, size+BUFSIZE+1);
1017 if (!tmp)
1019 xfree (xmlbuf);
1020 return GPG_ERR_ENOMEM;
1023 xmlbuf = tmp;
1024 size += BUFSIZE;
1025 ret = read (STDIN_FILENO, &xmlbuf[xlen], BUFSIZE);
1026 if (ret == -1)
1028 rc = gpg_error_from_syserror ();
1029 xfree (xmlbuf);
1030 return rc;
1033 xlen += ret;
1034 if (!ret || ret < BUFSIZE)
1035 break;
1038 xmlbuf[xlen] = 0;
1041 doc = xmlReadDoc (xmlbuf, NULL, "UTF-8", XML_PARSE_NOBLANKS);
1042 xfree (xmlbuf);
1043 if (!doc)
1044 return GPG_ERR_BAD_DATA;
1046 xmlNodePtr n = xmlDocGetRootElement (doc);
1047 if (n && !xmlStrEqual (n->name, (xmlChar *) "pwmd"))
1048 rc = GPG_ERR_BAD_DATA;
1050 if (!rc)
1052 rc = xml_validate_import (NULL, n ? n->children : n);
1053 if (!rc)
1055 rc = crypto_init (&crypto, NULL, filename, keyfile != NULL, keyfile);
1056 if (!rc)
1058 if (keyfile)
1060 crypto->flags |= CRYPTO_FLAG_KEYFILE;
1061 crypto->keyfile = str_dup (keyfile);
1064 xmlDocDumpMemory (doc, &crypto->plaintext, &len);
1065 if (len > 0)
1066 crypto->plaintext_size = len;
1067 else
1068 rc = GPG_ERR_ENOMEM;
1073 if (!rc)
1075 if (!symmetric && !keyid)
1077 crypto->save.userid = str_dup (userid);
1078 crypto->save.algo = algo ? str_dup (algo) : NULL;
1079 crypto->save.expire = expire;
1080 if (no_passphrase)
1081 crypto->save.flags |= GPGME_CREATE_NOPASSWD;
1083 rc = crypto_genkey (NULL, crypto);
1085 else
1087 if (keyid)
1088 crypto->save.pubkey = strv_dup (keyid);
1090 if (sign_keyid)
1091 crypto->save.sigkey = str_dup (sign_keyid);
1094 if (!rc)
1096 crypto->flags |= symmetric ? CRYPTO_FLAG_SYMMETRIC : 0;
1097 rc = crypto_encrypt (NULL, crypto);
1101 if (!rc)
1103 if (!strcmp (outfile, "-"))
1104 outfile = NULL;
1106 xfree (crypto->plaintext);
1107 crypto->plaintext = NULL;
1108 xfree (crypto->filename);
1109 crypto->filename = outfile ? str_dup (outfile) : NULL;
1110 rc = crypto_write_file (crypto, NULL, NULL);
1113 xmlFreeDoc (doc);
1114 crypto_free (crypto);
1115 return rc;
1118 static gpg_error_t
1119 do_cache_push (struct crypto_s *crypto)
1121 gpg_error_t rc;
1122 xmlDocPtr doc;
1123 struct cache_data_s *cdata;
1124 unsigned char *crc;
1125 size_t len;
1126 int fd = -1;
1128 log_write (_("Adding '%s' to the cache..."),
1129 crypto->filename);
1131 if (valid_filename (crypto->filename) == 0)
1133 log_write (_("%s: Invalid characters in filename"), crypto->filename);
1134 return GPG_ERR_INV_VALUE;
1137 rc = lock_flock (NULL, crypto->filename, LOCK_SH, &fd);
1138 if (!rc)
1139 rc = crypto_decrypt (NULL, crypto);
1140 if (rc)
1142 unlock_flock (&fd);
1143 return rc;
1146 rc = xml_parse_doc ((char *) crypto->plaintext, crypto->plaintext_size, &doc);
1147 if (rc)
1149 unlock_flock (&fd);
1150 log_write ("%s", pwmd_strerror (rc));
1151 return rc;
1154 cdata = xcalloc (1, sizeof (struct cache_data_s));
1155 if (!cdata)
1157 unlock_flock (&fd);
1158 xmlFreeDoc (doc);
1159 return GPG_ERR_ENOMEM;
1162 rc = get_checksum (crypto->filename, &crc, &len);
1163 unlock_flock (&fd);
1164 if (rc)
1166 xmlFreeDoc (doc);
1167 cache_free_data_once (cdata);
1168 return rc;
1171 cdata->crc = crc;
1172 rc = cache_encrypt (crypto);
1173 if (!rc)
1175 cdata->doc = crypto->plaintext;
1176 cdata->size = crypto->plaintext_size;
1177 crypto->plaintext = NULL;
1178 cdata->pubkey = crypto->pubkey;
1179 cdata->sigkey = crypto->sigkey;
1180 crypto->pubkey = NULL;
1181 crypto->sigkey = NULL;
1183 else
1185 xmlFreeDoc (doc);
1186 cache_free_data_once (cdata);
1187 return rc;
1190 long timeout = config_get_long (crypto->filename, "cache_timeout");
1191 rc = cache_add_file (crypto->filename, cdata, timeout);
1192 return rc;
1195 static gpg_error_t
1196 init_client (int fd, const char *addr)
1198 gpg_error_t rc = 0;
1199 struct client_thread_s *new = xcalloc (1, sizeof (struct client_thread_s));
1201 if (!new)
1203 close (fd);
1204 log_write ("%s: %s", __FUNCTION__, pwmd_strerror (ENOMEM));
1205 return GPG_ERR_ENOMEM;
1208 MUTEX_LOCK (&cn_mutex);
1209 pthread_cleanup_push (release_mutex_cb, &cn_mutex);
1210 new->conntime = time (NULL);
1212 if (pipe (new->status_msg_pipe) == -1)
1213 rc = gpg_error_from_errno (errno);
1214 else
1215 pthread_mutex_init (&new->status_mutex, NULL);
1217 if (!rc)
1219 #ifdef WITH_GNUTLS
1220 new->remote = addr ? 1 : 0;
1221 if (addr)
1222 new->peeraddr = str_dup (addr);
1223 #endif
1224 new->fd = fd;
1225 rc = create_thread (client_thread, new, &new->tid, 1);
1226 if (rc)
1228 close (new->status_msg_pipe[0]);
1229 close (new->status_msg_pipe[1]);
1230 pthread_mutex_destroy (&new->status_mutex);
1234 if (!rc)
1236 if (addr)
1237 log_write (_("new connection: tid=%p, fd=%i, addr=%s"),
1238 (pthread_t *) new->tid, fd, addr);
1239 else
1240 log_write (_("new connection: tid=%p, fd=%i"),
1241 (pthread_t *) new->tid, fd);
1244 pthread_cleanup_pop (1);
1246 if (rc)
1248 xfree (new);
1249 close (fd);
1250 log_write ("%s(%i): %s", __FILE__, __LINE__, pwmd_strerror (rc));
1252 return rc;
1255 #ifdef WITH_GNUTLS
1256 static gpg_error_t
1257 do_tls_accept (struct pollfd *fds)
1259 struct sockaddr_storage raddr;
1260 socklen_t slen = sizeof (raddr);
1261 int fd;
1262 char s[INET6_ADDRSTRLEN];
1264 if (!(fds->revents & POLLIN))
1265 return 0;
1267 memset (&raddr, 0, sizeof (raddr));
1268 fd = accept (fds->fd, (struct sockaddr *) &raddr, &slen);
1269 if (fd == -1)
1271 int e = errno;
1273 if (errno != EAGAIN && !quit)
1274 log_write ("%s: %s", __FUNCTION__,
1275 pwmd_strerror (gpg_error_from_syserror()));
1277 return gpg_error_from_errno (e);
1280 inet_ntop (raddr.ss_family, get_in_addr ((struct sockaddr *) &raddr), s,
1281 sizeof s);
1282 (void) init_client (fd, s);
1283 return 0;
1285 #endif
1287 static void *
1288 accept_thread (void *arg)
1290 int sockfd = *(int *) arg;
1291 #ifndef HAVE_PTHREAD_CANCEL
1292 INIT_SIGNAL (SIGUSR2, catch_thread_signal);
1293 #endif
1295 #ifdef HAVE_PR_SET_NAME
1296 prctl (PR_SET_NAME, "accept");
1297 #endif
1298 pthread_setspecific (thread_name_key, str_asprintf ("!%s", __FUNCTION__));
1300 for (;;)
1302 socklen_t slen = sizeof (struct sockaddr_un);
1303 struct sockaddr_un raddr;
1304 int fd, s = 0;
1305 struct pollfd fds[3];
1307 TEST_CANCEL ();
1308 memset (fds, 0, sizeof (fds));
1309 fds[s].fd = sockfd;
1310 fds[s++].events = POLLIN;
1312 #ifdef WITH_GNUTLS
1313 if (tls_fd != -1)
1315 fds[s].fd = tls_fd;
1316 fds[s++].events = POLLIN;
1318 else
1319 fds[s].fd = tls_fd;
1321 if (tls6_fd != -1)
1323 fds[s].fd = tls6_fd;
1324 fds[s++].events = POLLIN;
1326 else
1327 fds[s].fd = tls6_fd;
1328 #endif
1330 s = poll (fds, s, 500);
1331 if (s == -1)
1333 if (errno != EINTR)
1334 log_write ("%s", strerror (errno));
1335 break;
1337 else if (s == 0)
1338 continue;
1340 if (fds[0].revents & POLLIN)
1342 fd = accept (sockfd, (struct sockaddr *) &raddr, &slen);
1343 if (fd == -1)
1345 if (errno == EMFILE || errno == ENFILE)
1346 log_write ("%s: %s", __FUNCTION__,
1347 pwmd_strerror (gpg_error_from_errno (errno)));
1348 else if (errno != EAGAIN && errno != EINTR)
1350 if (!quit) // probably EBADF
1351 log_write ("%s: %s", __FUNCTION__,
1352 pwmd_strerror (gpg_error_from_errno (errno)));
1354 break;
1357 continue;
1360 (void) init_client (fd, NULL);
1363 #ifdef WITH_GNUTLS
1364 if (tls_fd != -1 && fds[1].fd == tls_fd)
1365 (void)do_tls_accept (&fds[1]);
1367 if (tls6_fd != -1 && fds[1].fd == tls6_fd)
1368 (void)do_tls_accept (&fds[1]);
1370 if (tls6_fd != -1 && fds[2].fd == tls6_fd)
1371 (void)do_tls_accept (&fds[2]);
1372 #endif
1375 /* Just in case accept() failed for some reason other than EBADF */
1376 quit = 1;
1377 return NULL;
1380 static void *
1381 cache_timer_thread (void *arg)
1383 unsigned k = 0;
1384 #ifndef HAVE_PTHREAD_CANCEL
1385 INIT_SIGNAL (SIGUSR2, catch_thread_signal);
1386 #endif
1388 (void)arg;
1390 #ifdef HAVE_PR_SET_NAME
1391 prctl (PR_SET_NAME, "timer");
1392 #endif
1393 pthread_setspecific (thread_name_key, str_asprintf ("!%s", __FUNCTION__));
1395 for (;;)
1397 struct timeval tv = { 1, 0 };
1398 unsigned keepalive = config_get_integer ("global", "keepalive_interval");
1400 TEST_CANCEL ();
1401 select (0, NULL, NULL, NULL, &tv);
1402 cache_adjust_timeout ();
1404 if (keepalive && ++k >= keepalive)
1406 send_status_all (STATUS_KEEPALIVE, NULL);
1407 k = 0;
1411 return NULL;
1414 static int
1415 signal_loop (sigset_t sigset)
1417 int done = 0;
1421 siginfo_t info;
1423 memset (&info, 0, sizeof (info));
1424 sigwaitinfo (&sigset, &info);
1425 log_write (_("caught signal %i (%s), sender: pid=%li, uid=%u"),
1426 info.si_signo, strsignal (info.si_signo),
1427 info.si_pid <= 0 ? getpid () : info.si_pid,
1428 info.si_uid <= 0 ? getuid () : info.si_uid);
1430 switch (info.si_signo)
1432 case SIGHUP:
1433 pthread_cond_signal (&rcfile_cond);
1434 break;
1435 case SIGUSR1:
1436 log_write (_("clearing file cache"));
1437 cache_clear (NULL, NULL, 1, 0);
1438 send_status_all (STATUS_CACHE, NULL);
1439 break;
1440 default:
1441 done = 1;
1442 break;
1445 while (!done);
1447 return done;
1450 static void
1451 catchsig (int sig)
1453 log_write (_ ("Caught signal %i (%s). Exiting."), sig, strsignal (sig));
1454 #ifdef HAVE_BACKTRACE
1455 BACKTRACE (__FUNCTION__);
1456 #endif
1457 longjmp (jmp, 1);
1460 static void
1461 cancel_all_clients ()
1463 unsigned i, t;
1465 MUTEX_LOCK (&cn_mutex);
1466 t = slist_length (cn_thread_list);
1467 for (i = 0; i < t; i++)
1469 struct client_thread_s *thd = slist_nth_data (cn_thread_list, i);
1471 #ifdef HAVE_PTHREAD_CANCEL
1472 pthread_cancel (thd->tid);
1473 #else
1474 pthread_kill (thd->tid, SIGUSR2);
1475 #endif
1478 while (slist_length (cn_thread_list))
1480 MUTEX_UNLOCK (&cn_mutex);
1481 usleep (50000);
1482 MUTEX_LOCK (&cn_mutex);
1485 MUTEX_UNLOCK (&cn_mutex);
1488 static int
1489 server_loop (int sockfd, char **socketpath)
1491 pthread_t cache_timeout_tid;
1492 pthread_t accept_tid;
1493 int cancel_timeout_thread = 0;
1494 int cancel_accept_thread = 0;
1495 int cancel_rcfile_thread = 0;
1496 sigset_t sigset;
1497 int n;
1498 int segv = 0;
1499 gpg_error_t rc;
1501 init_commands ();
1502 sigemptyset (&sigset);
1504 /* Termination */
1505 sigaddset (&sigset, SIGTERM);
1506 sigaddset (&sigset, SIGINT);
1508 /* Clears the file cache. */
1509 sigaddset (&sigset, SIGUSR1);
1511 /* Configuration file reloading. */
1512 sigaddset (&sigset, SIGHUP);
1514 #ifndef HAVE_PTHREAD_CANCEL
1516 The socket, cache and rcfile threads use this signal when
1517 pthread_cancel() is unavailable. Prevent the main thread from
1518 catching this signal from another process.
1520 sigaddset (&sigset, SIGUSR2);
1521 #endif
1523 /* An assertion failure. */
1524 signal (SIGABRT, catchsig);
1526 sigaddset (&sigset, SIGABRT);
1527 sigprocmask (SIG_BLOCK, &sigset, NULL);
1529 #ifndef HAVE_PTHREAD_CANCEL
1530 /* Remove this signal from the watched signals in signal_loop(). */
1531 sigdelset (&sigset, SIGUSR2);
1532 #endif
1534 /* Can show a backtrace of the stack in the log. */
1535 signal (SIGSEGV, catchsig);
1537 char *p = get_username (getuid());
1538 log_write (_("%s started for user %s"), PACKAGE_STRING PWMD_GIT_HASH, p);
1539 xfree (p);
1541 #ifdef WITH_GNUTLS
1542 if (config_get_boolean ("global", "enable_tcp"))
1543 log_write (_("Listening on %s and TCP port %i"), *socketpath,
1544 config_get_integer ("global", "tcp_port"));
1545 else
1546 log_write (_("Listening on %s"), *socketpath);
1547 #else
1548 log_write (_("Listening on %s"), *socketpath);
1549 #endif
1551 rc = create_thread (reload_rcfile_thread, NULL, &rcfile_tid, 0);
1552 if (rc)
1554 log_write ("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1555 pwmd_strerror (rc));
1556 goto done;
1559 cancel_rcfile_thread = 1;
1560 rc = create_thread (cache_timer_thread, NULL, &cache_timeout_tid, 0);
1561 if (rc)
1563 log_write ("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1564 pwmd_strerror (rc));
1565 goto done;
1568 cancel_timeout_thread = 1;
1569 rc = create_thread (accept_thread, &sockfd, &accept_tid, 0);
1570 if (rc)
1572 log_write ("%s(%i): pthread_create(): %s", __FILE__, __LINE__,
1573 pwmd_strerror (rc));
1574 goto done;
1577 cancel_accept_thread = 1;
1578 if (!setjmp (jmp))
1579 signal_loop (sigset);
1580 else
1581 segv = 1;
1583 done:
1585 * We're out of the main server loop. This happens when a signal was sent
1586 * to terminate the daemon. Cancel all clients and exit.
1588 if (cancel_accept_thread)
1590 #ifdef HAVE_PTHREAD_CANCEL
1591 n = pthread_cancel (accept_tid);
1592 #else
1593 n = pthread_kill (accept_tid, SIGUSR2);
1594 #endif
1595 if (!n)
1596 pthread_join (accept_tid, NULL);
1599 if (cancel_timeout_thread)
1601 #ifdef HAVE_PTHREAD_CANCEL
1602 n = pthread_cancel (cache_timeout_tid);
1603 #else
1604 n = pthread_kill (cache_timeout_tid, SIGUSR2);
1605 #endif
1606 if (!n)
1607 pthread_join (cache_timeout_tid, NULL);
1610 #ifdef WITH_GNUTLS
1611 tls_start_stop (1);
1612 #endif
1613 shutdown (sockfd, SHUT_RDWR);
1614 close (sockfd);
1615 unlink (*socketpath);
1616 xfree (*socketpath);
1617 *socketpath = NULL;
1618 MUTEX_LOCK (&cn_mutex);
1619 n = slist_length (cn_thread_list);
1620 MUTEX_UNLOCK (&cn_mutex);
1622 if (n && !segv)
1623 cancel_all_clients ();
1624 else
1625 free_all_clients ();
1627 if (cancel_rcfile_thread)
1629 #ifdef HAVE_PTHREAD_CANCEL
1630 pthread_cancel (rcfile_tid);
1631 #else
1632 pthread_kill (rcfile_tid, SIGUSR2);
1633 pthread_cond_signal (&rcfile_cond);
1634 #endif
1635 pthread_join (rcfile_tid, NULL);
1638 cache_deinit ();
1639 deinit_commands ();
1640 return segv ? EXIT_FAILURE : EXIT_SUCCESS;
1643 static void
1644 usage (const char *pn, int status)
1646 FILE *fp = status == EXIT_FAILURE ? stderr : stdout;
1648 fprintf (fp, _("Usage: %s [OPTIONS] [file1] [...]\n"
1649 " --homedir alternate pwmd home directory (~/.pwmd)\n"
1650 " -f, --rcfile=filename load the specified configuration file\n"
1651 " (~/.pwmd/config)\n"
1652 " --kill terminate an existing instance of pwmd\n"
1653 " -n, --no-fork run as a foreground process\n"
1654 " --disable-dump disable the LIST, XPATH and DUMP commands\n"
1655 " --ignore, --force ignore cache pushing errors during startup\n"
1656 " -I, --import=filename import a pwmd DTD formatted XML file)\n"
1657 " -k, --passphrase-file=file for use when importing\n"
1658 " -o, --outfile=filename output file when importing\n"
1659 " --keyid=fpr[,..] public key to use when encrypting\n"
1660 " --sign-keyid=fpr fingerprint of the signing key to use\n"
1661 " -s, --symmetric use conventional encryption with optional signer\n"
1662 " --userid=string name and email address to use when importing\n"
1663 " --algo=string algorithm to use when importing (engine default)\n"
1664 " --expire=seconds key expiry time when importing (3 years)\n"
1665 " --no-passphrase don't require a passphrase when importing\n"
1666 " --debug=[a:..][,g:N][,t:N] enable debugging (a:[ixedsc],g:[1-9],t:[0-N])\n"
1667 " --help this help text\n"
1668 " --version show version and compile time features\n"),
1669 pn);
1670 exit (status);
1673 static void
1674 unlink_stale_socket (const char *sock, const char *pidfile)
1676 log_write (_ ("removing stale socket %s"), sock);
1677 unlink (sock);
1678 unlink (pidfile);
1681 static int
1682 test_pidfile (const char *path, const char *sock, char *buf, size_t buflen,
1683 char **pidfile, int create, mode_t mode, int terminate)
1685 long pid;
1686 int fd;
1687 size_t len;
1689 if (!create)
1691 snprintf (buf, buflen, "%s.pid", path);
1692 *pidfile = str_dup (buf);
1693 fd = open (buf, O_RDONLY);
1695 else
1696 fd = open (*pidfile, O_CREAT|O_WRONLY|O_TRUNC, mode);
1698 if (fd == -1)
1700 if (!create && errno != ENOENT)
1702 log_write ("%s: %s", buf, pwmd_strerror (errno));
1703 xfree (*pidfile);
1704 *pidfile = NULL;
1705 return -1;
1707 else if (!create && !terminate)
1708 return 0;
1710 log_write ("%s: %s", *pidfile, strerror (errno));
1711 return -1;
1714 if (create)
1716 pid = getpid();
1717 snprintf (buf, buflen, "%li", pid);
1718 ssize_t ret = write (fd, buf, strlen (buf));
1719 if (ret == -1)
1720 log_write ("%s (%i): %s", __FUNCTION__, __LINE__,
1721 pwmd_strerror (gpg_error_from_syserror ()));
1722 close (fd);
1723 return 0;
1726 if (buflen < 8)
1728 close (fd);
1729 log_write ("%s (%i): %s", __FUNCTION__, __LINE__,
1730 pwmd_strerror (GPG_ERR_BUFFER_TOO_SHORT));
1731 return -1;
1734 len = read (fd, buf, buflen);
1735 close (fd);
1736 if (len == 0)
1738 unlink_stale_socket (path, *pidfile);
1739 return 0;
1742 if (sscanf (buf, "%li", &pid) != 1 || pid == 0)
1744 if (!terminate)
1746 unlink_stale_socket (path, *pidfile);
1747 return 0;
1751 if (kill (pid, 0) == -1)
1753 unlink_stale_socket (path, *pidfile);
1754 return 0;
1757 if (terminate)
1759 if (kill (pid, SIGTERM) == -1)
1760 log_write ("%s: %s", path, pwmd_strerror (errno));
1762 else
1763 log_write (_ ("an instance for socket %s is already running"), path);
1765 xfree (*pidfile);
1766 *pidfile = NULL;
1767 return 1;
1770 static unsigned
1771 parse_debug_level (const char *str, unsigned *debug, int *gpgme, int *tls)
1773 const char *p;
1774 unsigned level = 0;
1775 int gl = 0, tl = 0;
1777 for (p = str; p && *p; p++)
1779 if (*p == 'a') // assuan debug flags
1781 if (*++p != ':')
1782 return 1;
1784 while (*++p)
1786 switch (*p)
1788 case 'i':
1789 level |= ASSUAN_LOG_INIT;
1790 break;
1791 case 'x':
1792 level |= ASSUAN_LOG_CTX;
1793 break;
1794 case 'e':
1795 level |= ASSUAN_LOG_ENGINE;
1796 break;
1797 case 'd':
1798 level |= ASSUAN_LOG_DATA;
1799 break;
1800 case 's':
1801 level |= ASSUAN_LOG_SYSIO;
1802 break;
1803 case 'c':
1804 level |= ASSUAN_LOG_CONTROL;
1805 break;
1806 case ',':
1807 break;
1808 default:
1809 return 1;
1812 if (*p == ',')
1813 break;
1816 if (!*p)
1817 break;
1819 else if (*p == 'g' || *p == 't') // gpgme and TLS debug level
1821 int t = *p == 't';
1822 int n;
1824 if (*++p != ':')
1825 return 1;
1827 if (!isdigit (*++p))
1828 return 1;
1830 n = atoi (p);
1831 if (t)
1832 tl = n;
1833 else
1834 gl = n;
1836 if (tl < 0 || gl < 0 || gl > 9)
1837 return 1;
1839 while (isdigit (*p))
1840 p++;
1842 p--;
1843 if (*(p+1) && *(p+1) != ',')
1844 return 1;
1845 else if (*(p+1))
1846 p++;
1848 else
1849 return 1;
1852 if (tl)
1853 *tls = tl;
1855 if (gl)
1856 *gpgme = gl;
1858 *debug = level;
1859 return 0;
1863 main (int argc, char *argv[])
1865 int opt;
1866 struct sockaddr_un addr;
1867 char buf[PATH_MAX];
1868 char *socketpath = NULL, *socketdir, *socketname = NULL;
1869 char *socketarg = NULL;
1870 char *datadir = NULL;
1871 char *pidfile = NULL;
1872 mode_t mode = 0600;
1873 int x;
1874 char *p;
1875 char **cache_push = NULL;
1876 char *import = NULL, *keyid = NULL, *sign_keyid = NULL;
1877 char *userid = NULL;
1878 char *algo = NULL;
1879 long expire = 0;
1880 int no_passphrase = 0;
1881 int estatus = EXIT_FAILURE;
1882 int sockfd;
1883 char *outfile = NULL;
1884 int do_unlink = 0;
1885 int secure = 0;
1886 int show_version = 0;
1887 int force = 0;
1888 gpg_error_t rc;
1889 char *keyfile = NULL;
1890 int exists;
1891 int optindex;
1892 int terminate = 0;
1893 int sym = 0;
1894 int gpgme_level = -1;
1895 int tls_level = -1;
1896 int backlog = 0;
1897 /* Must maintain the same order as longopts[] */
1898 enum
1900 OPT_VERSION, OPT_HELP, OPT_HOMEDIR, OPT_NO_FORK, OPT_DISABLE_DUMP,
1901 OPT_FORCE, OPT_RCFILE, OPT_PASSPHRASE_FILE, OPT_IMPORT, OPT_OUTFILE,
1902 OPT_KEYID, OPT_SIGN_KEYID, OPT_SYMMETRIC, OPT_USERID, OPT_ALGO, OPT_EXPIRE,
1903 OPT_NOPASSPHRASE, OPT_KILL, OPT_DEBUG
1905 const char *optstring = "nf:C:k:I:o:s";
1906 const struct option longopts[] = {
1907 {"version", no_argument, 0, 0},
1908 {"help", no_argument, 0, 0},
1909 {"homedir", required_argument, 0, 0},
1910 {"no-fork", no_argument, 0, 'n'},
1911 {"disable_dump", no_argument, 0, 0},
1912 {"force", no_argument, 0, 0},
1913 {"rcfile", required_argument, 0, 'f'},
1914 {"passphrase-file", required_argument, 0, 'k'},
1915 {"import", required_argument, 0, 'I'},
1916 {"outfile", required_argument, 0, 'o'},
1917 {"keyid", required_argument, 0, 0},
1918 {"sign-keyid", required_argument, 0, 0},
1919 {"symmetric", no_argument, 0, 's'},
1920 {"userid", required_argument, 0, 0},
1921 {"algo", required_argument, 0, 0},
1922 {"expire", required_argument, 0, 0},
1923 {"no-passphrase", no_argument, 0, 0},
1924 {"kill", no_argument, 0, 0},
1925 {"debug", required_argument, 0, 0},
1926 {0, 0, 0, 0}
1929 log_fd = -1;
1930 cmdline = 1;
1931 expire = time (NULL) + DEFAULT_EXPIRE;
1933 #ifndef DEBUG
1934 #ifdef HAVE_SETRLIMIT
1935 struct rlimit rl;
1937 rl.rlim_cur = rl.rlim_max = 0;
1939 if (setrlimit (RLIMIT_CORE, &rl) != 0)
1940 err (EXIT_FAILURE, "setrlimit()");
1941 #endif
1943 #ifdef HAVE_PR_SET_DUMPABLE
1944 prctl (PR_SET_DUMPABLE, 0);
1945 #endif
1946 #endif
1948 #ifdef ENABLE_NLS
1949 setlocale (LC_ALL, "");
1950 bindtextdomain ("pwmd", LOCALEDIR);
1951 textdomain ("pwmd");
1952 #endif
1954 while ((opt = getopt_long (argc, argv, optstring, longopts, &optindex))
1955 != -1)
1957 switch (opt)
1959 case 'I':
1960 import = optarg;
1961 break;
1962 case 'k':
1963 keyfile = optarg;
1964 break;
1965 case 'o':
1966 outfile = optarg;
1967 break;
1968 case 'n':
1969 nofork = 1;
1970 break;
1971 case 'f':
1972 rcfile = str_dup (optarg);
1973 break;
1974 case 's':
1975 sym = 1;
1976 break;
1977 default:
1978 usage (argv[0], EXIT_FAILURE);
1979 break;
1980 case 0:
1981 switch (optindex)
1983 case OPT_DEBUG:
1984 if (parse_debug_level (optarg, &assuan_level, &gpgme_level,
1985 &tls_level))
1986 usage (argv[0], EXIT_FAILURE);
1987 break;
1988 case OPT_SYMMETRIC:
1989 sym = 1;
1990 break;
1991 case OPT_VERSION:
1992 show_version = 1;
1993 break;
1994 case OPT_HELP:
1995 usage (argv[0], EXIT_SUCCESS);
1996 break;
1997 case OPT_HOMEDIR:
1998 homedir = str_dup (optarg);
1999 break;
2000 case OPT_NO_FORK:
2001 nofork = 1;
2002 break;
2003 case OPT_DISABLE_DUMP:
2004 secure = 1;
2005 break;
2006 case OPT_FORCE:
2007 force = 1;
2008 break;
2009 case OPT_RCFILE:
2010 rcfile = str_dup (optarg);
2011 break;
2012 case OPT_PASSPHRASE_FILE:
2013 keyfile = optarg;
2014 break;
2015 case OPT_IMPORT:
2016 import = optarg;
2017 break;
2018 case OPT_OUTFILE:
2019 outfile = optarg;
2020 break;
2021 case OPT_KEYID:
2022 keyid = optarg;
2023 break;
2024 case OPT_SIGN_KEYID:
2025 sign_keyid = optarg;
2026 break;
2027 case OPT_USERID:
2028 userid = optarg;
2029 break;
2030 case OPT_ALGO:
2031 algo = optarg;
2032 break;
2033 case OPT_EXPIRE:
2034 errno = rc = 0;
2035 expire = strtoul (optarg, &p, 10);
2037 if (!errno && p && *p)
2038 rc = GPG_ERR_INV_VALUE;
2039 else if (expire == ULONG_MAX)
2040 rc = GPG_ERR_INV_VALUE;
2041 else if (errno)
2042 rc = gpg_error_from_syserror ();
2044 if (rc)
2045 usage (argv[0], EXIT_FAILURE);
2046 break;
2047 case OPT_NOPASSPHRASE:
2048 no_passphrase = 1;
2049 break;
2050 case OPT_KILL:
2051 terminate = 1;
2052 break;
2053 default:
2054 usage (argv[0], EXIT_FAILURE);
2059 if (show_version)
2061 printf (_("%s\n\n"
2062 "Copyright (C) 2006-2021\n"
2063 "%s\n"
2064 "Released under the terms of the GPL v2.\n\n"
2065 "Compile time features:\n%s"), PACKAGE_STRING PWMD_GIT_HASH,
2066 PACKAGE_BUGREPORT,
2067 #ifdef PWMD_HOMEDIR
2068 "+PWMD_HOMEDIR=" PWMD_HOMEDIR "\n"
2069 #endif
2070 #ifdef WITH_GNUTLS
2071 "+WITH_GNUTLS\n"
2072 #else
2073 "-WITH_GNUTLS\n"
2074 #endif
2075 #ifdef WITH_LIBACL
2076 "+WITH_LIBACL\n"
2077 #else
2078 "-WITH_LIBACL\n"
2079 #endif
2080 #ifdef DEBUG
2081 "+DEBUG\n"
2082 #else
2083 "-DEBUG\n"
2084 #endif
2085 #ifdef MEM_DEBUG
2086 "+MEM_DEBUG\n"
2087 #else
2088 "-MEM_DEBUG\n"
2089 #endif
2090 #ifdef MUTEX_DEBUG
2091 "+MUTEX_DEBUG\n"
2092 #else
2093 "-MUTEX_DEBUG\n"
2094 #endif
2096 exit (EXIT_SUCCESS);
2099 if (gpgme_level != -1)
2101 char s[2] = { gpgme_level + '0', 0 };
2103 if (getenv ("GPGME_DEBUG"))
2104 log_write (_ ("Overriding GPGME_DEBUG environment with level %u!"),
2105 gpgme_level);
2107 gpgme_set_global_flag ("debug", s);
2110 if (setup_crypto ())
2111 exit (EXIT_FAILURE);
2113 #ifdef WITH_GNUTLS
2114 tls_level = tls_level == -1 ? 1 : tls_level;
2115 gnutls_global_set_log_level (tls_level);
2116 tls_fd = -1;
2117 tls6_fd = -1;
2118 #endif
2119 rc = xml_init ();
2120 if (rc)
2121 errx (EXIT_FAILURE, "%s", "xml_init() failed");
2123 if (!homedir)
2124 #ifdef PWMD_HOMEDIR
2125 homedir = str_dup(PWMD_HOMEDIR);
2126 #else
2127 homedir = str_asprintf ("%s/.pwmd", get_home_dir());
2128 #endif
2130 if (mkdir (homedir, 0700) == -1 && errno != EEXIST)
2131 err (EXIT_FAILURE, "%s", homedir);
2133 if (!rcfile)
2134 rcfile = str_asprintf ("%s/config", homedir);
2136 pthread_key_create (&last_error_key, free_key);
2137 #ifndef HAVE_PTHREAD_CANCEL
2138 pthread_key_create (&signal_thread_key, free_key);
2139 #endif
2141 pthread_mutexattr_t attr;
2142 pthread_mutexattr_init (&attr);
2143 pthread_mutexattr_settype (&attr, PTHREAD_MUTEX_RECURSIVE);
2144 pthread_mutex_init (&rcfile_mutex, &attr);
2145 global_config = config_parse (rcfile, 0);
2146 if (!global_config)
2148 pthread_mutexattr_destroy (&attr);
2149 pthread_mutex_destroy (&rcfile_mutex);
2150 exit (EXIT_FAILURE);
2153 p = config_get_string ("global", "gpg_homedir");
2154 if (!p)
2155 datadir = str_asprintf ("%s/.gnupg", homedir);
2156 else
2157 datadir = expand_homedir (p);
2159 xfree (p);
2160 if (mkdir (datadir, 0700) == -1 && errno != EEXIST)
2161 err (EXIT_FAILURE, "%s", datadir);
2163 rc = gpgme_set_engine_info (GPGME_PROTOCOL_OpenPGP, NULL, datadir);
2164 if (rc)
2165 errx (EXIT_FAILURE, "%s: %s", datadir, pwmd_strerror (rc));
2166 xfree (datadir);
2168 snprintf (buf, sizeof (buf), "%s/data", homedir);
2169 if (mkdir (buf, 0700) == -1 && errno != EEXIST)
2170 err (EXIT_FAILURE, "%s", buf);
2172 datadir = str_dup (buf);
2173 pthread_cond_init (&rcfile_cond, NULL);
2174 pthread_mutex_init (&cn_mutex, &attr);
2175 pthread_mutexattr_destroy (&attr);
2177 setup_logging ();
2179 x = config_get_int_param (global_config, "global", "priority", &exists);
2180 if (exists && x != atoi(INVALID_PRIORITY))
2182 errno = 0;
2183 if (setpriority (PRIO_PROCESS, 0, x) == -1)
2185 log_write ("setpriority(): %s",
2186 pwmd_strerror (gpg_error_from_errno (errno)));
2187 goto do_exit;
2190 #ifdef HAVE_MLOCKALL
2191 if (disable_mlock == 0 && mlockall (MCL_CURRENT | MCL_FUTURE) == -1)
2193 log_write ("mlockall(): %s",
2194 pwmd_strerror (gpg_error_from_errno (errno)));
2195 goto do_exit;
2197 #endif
2199 rc = cache_init ();
2200 if (rc)
2202 log_write ("pwmd: ERR %i: %s", rc, pwmd_strerror (rc));
2203 exit (EXIT_FAILURE);
2206 if (import)
2208 char **keyids = NULL;
2210 if (!outfile || !*outfile || argc != optind)
2211 usage (argv[0], EXIT_FAILURE);
2213 if (keyid)
2214 keyids = str_split (keyid, ",", 0);
2215 else if (!userid && !sym)
2216 usage (argv[0], EXIT_FAILURE);
2218 rc = xml_import (import, outfile, keyids, sign_keyid, keyfile, userid,
2219 algo, expire, no_passphrase, sym);
2220 strv_free (keyids);
2221 if (rc)
2223 if (gpg_err_source (rc) == GPG_ERR_SOURCE_UNKNOWN)
2224 rc = gpg_error (rc);
2226 log_write ("%s: %u: %s", import, rc, pwmd_strerror (rc));
2229 config_free (global_config);
2230 xfree (rcfile);
2231 exit (rc ? EXIT_FAILURE : EXIT_SUCCESS);
2234 p = config_get_string ("global", "socket_path");
2235 if (!p)
2236 p = str_asprintf ("%s/socket", homedir);
2238 socketarg = expand_homedir (p);
2239 xfree (p);
2241 if (!secure)
2242 disable_list_and_dump = config_get_boolean ("global",
2243 "disable_list_and_dump");
2244 else
2245 disable_list_and_dump = secure;
2247 cache_push = config_get_list ("global", "cache_push");
2249 while (optind < argc)
2251 if (strv_printf (&cache_push, "%s", argv[optind++]) == 0)
2252 errx (EXIT_FAILURE, "%s", pwmd_strerror (GPG_ERR_ENOMEM));
2255 if (!strchr (socketarg, '/'))
2257 socketdir = getcwd (buf, sizeof (buf));
2258 socketname = str_dup (socketarg);
2259 socketpath = str_asprintf ("%s/%s", socketdir, socketname);
2261 else
2263 socketname = str_dup (strrchr (socketarg, '/')+1);
2264 socketarg[strlen (socketarg) - strlen (socketname) - 1] = 0;
2265 socketdir = str_dup (socketarg);
2266 socketpath = str_asprintf ("%s/%s", socketdir, socketname);
2269 if (chdir (datadir))
2271 log_write ("%s: %s", datadir,
2272 pwmd_strerror (gpg_error_from_errno (errno)));
2273 unlink (socketpath);
2274 goto do_exit;
2277 x = test_pidfile (socketpath, socketname, buf, sizeof(buf), &pidfile, 0,
2278 mode, terminate);
2279 if (!terminate && x)
2280 goto do_exit;
2281 else if (terminate)
2283 estatus = x != 1 ? EXIT_FAILURE : EXIT_SUCCESS;
2284 goto do_exit;
2288 * bind() doesn't like the full pathname of the socket or any non alphanum
2289 * characters so change to the directory where the socket is wanted then
2290 * create it then change to datadir.
2292 if (chdir (socketdir))
2294 log_write ("%s: %s", socketdir,
2295 pwmd_strerror (gpg_error_from_errno (errno)));
2296 goto do_exit;
2299 xfree (socketdir);
2301 if ((sockfd = socket (PF_UNIX, SOCK_STREAM, 0)) == -1)
2303 log_write ("socket(): %s", pwmd_strerror (gpg_error_from_errno (errno)));
2304 goto do_exit;
2307 addr.sun_family = AF_UNIX;
2308 snprintf (addr.sun_path, sizeof (addr.sun_path), "%s", socketname);
2309 do_unlink = 1;
2310 if (bind (sockfd, (struct sockaddr *) &addr, sizeof (struct sockaddr)) ==
2313 log_write ("bind(): %s", pwmd_strerror (gpg_error_from_errno (errno)));
2315 if (errno == EADDRINUSE)
2317 do_unlink = 0;
2318 log_write (_("Either there is another pwmd running or '%s' is a \n"
2319 "stale socket. Please remove it manually."), socketpath);
2322 goto do_exit;
2326 char *t = config_get_string ("global", "socket_perms");
2327 mode_t mask;
2329 if (t)
2331 mode = strtol (t, NULL, 8);
2332 mask = umask (0);
2333 xfree (t);
2335 if (chmod (socketname, mode) == -1)
2337 log_write ("%s: %s", socketname,
2338 pwmd_strerror (gpg_error_from_errno (errno)));
2339 close (sockfd);
2340 umask (mask);
2341 goto do_exit;
2344 umask (mask);
2348 if (chdir (datadir))
2350 log_write ("%s: %s", datadir,
2351 pwmd_strerror (gpg_error_from_errno (errno)));
2352 close (sockfd);
2353 goto do_exit;
2356 xfree (datadir);
2357 #ifdef WITH_GNUTLS
2358 if (config_get_boolean ("global", "enable_tcp"))
2360 if (!tls_start_stop (0))
2362 close (sockfd);
2363 goto do_exit;
2366 #endif
2369 * Set the cache entry for a file. Prompts for the password.
2371 if (cache_push)
2373 for (opt = 0; cache_push[opt]; opt++)
2375 struct crypto_s *crypto = NULL;
2376 char *pw_file = config_get_string (cache_push[opt],
2377 "passphrase_file");
2378 rc = crypto_init (&crypto, NULL, cache_push[opt], pw_file != NULL,
2379 pw_file);
2381 if (!rc)
2383 crypto->flags |= pw_file ? CRYPTO_FLAG_KEYFILE : 0;
2384 crypto->keyfile = pw_file;
2386 else
2387 xfree (pw_file);
2389 if (rc)
2391 estatus = EXIT_FAILURE;
2392 goto do_exit;
2395 rc = do_cache_push (crypto);
2396 if (rc && !force)
2398 log_write ("ERR %u: %s", rc, pwmd_strerror(rc));
2399 strv_free (cache_push);
2400 log_write (_ ("Failed to add a file to the cache. Use --force to force startup. Exiting."));
2401 cache_clear (NULL, NULL, 1, 0);
2402 estatus = EXIT_FAILURE;
2403 crypto_free (crypto);
2404 (void)cache_kill_scd ();
2405 goto do_exit;
2407 else if (rc)
2408 log_write ("%s: %s", crypto->filename, pwmd_strerror(rc));
2409 else
2410 log_write (_("Successfully added '%s' to the cache."),
2411 crypto->filename);
2413 crypto_free (crypto);
2416 (void)cache_kill_scd ();
2417 strv_free (cache_push);
2418 log_write (!nofork ? _("Done. Daemonizing...") :
2419 _("Done. Waiting for connections..."));
2422 backlog = config_get_integer ("global", "backlog");
2423 if (listen (sockfd, backlog) == -1)
2425 log_write ("listen(): %s", pwmd_strerror (gpg_error_from_errno (errno)));
2426 goto do_exit;
2429 /* A client should set these with the OPTION command. */
2430 unsetenv ("DISPLAY");
2431 unsetenv ("GPG_TTY");
2432 unsetenv ("TERM");
2434 if (!nofork)
2436 switch (fork ())
2438 case -1:
2439 log_write ("fork(): %s",
2440 pwmd_strerror (gpg_error_from_errno (errno)));
2441 goto do_exit;
2442 case 0:
2443 close (0);
2444 close (1);
2445 close (2);
2446 setsid ();
2447 break;
2448 default:
2449 _exit (EXIT_SUCCESS);
2453 (void)test_pidfile (socketpath, socketname, buf, sizeof(buf), &pidfile, 1,
2454 mode, 0);
2455 xfree (socketname);
2456 cmdline = 0;
2457 pthread_key_create (&thread_name_key, free_key);
2458 pthread_setspecific (thread_name_key, str_asprintf ("!%s", __FUNCTION__));
2459 estatus = server_loop (sockfd, &socketpath);
2461 do_exit:
2462 if (socketpath && do_unlink)
2464 unlink (socketpath);
2465 xfree (socketpath);
2468 xfree (socketarg);
2469 #ifdef WITH_GNUTLS
2470 gnutls_global_deinit ();
2471 tls_deinit_params ();
2472 #endif
2473 pthread_cond_destroy (&rcfile_cond);
2474 pthread_mutex_destroy (&rcfile_mutex);
2475 pthread_key_delete (last_error_key);
2476 #ifndef HAVE_PTHREAD_CANCEL
2477 pthread_key_delete (signal_thread_key);
2478 #endif
2480 if (global_config)
2481 config_free (global_config);
2483 free_invoking_users (invoking_users);
2484 xfree (rcfile);
2485 xfree (home_directory);
2486 xfree (homedir);
2487 xml_deinit ();
2489 if (pidfile)
2490 unlink (pidfile);
2491 xfree (pidfile);
2493 if (estatus == EXIT_SUCCESS && !terminate)
2494 log_write (_("pwmd exiting normally"));
2496 pthread_key_delete (thread_name_key);
2497 closelog ();
2499 if (log_fd != -1)
2500 close (log_fd);
2502 xfree (logfile);
2503 exit (estatus);
2506 gpg_error_t lock_flock (assuan_context_t ctx, const char *filename,
2507 int type, int *fd)
2509 gpg_error_t rc = 0;
2511 #ifdef HAVE_FLOCK
2512 rc = open_check_file (filename, fd, NULL, 1);
2513 if (rc)
2514 return rc;
2516 TRY_FLOCK (ctx, *fd, type, rc);
2517 if (rc)
2519 close (*fd);
2520 *fd = -1;
2522 #endif
2524 return rc;
2527 void unlock_flock (int *fd)
2529 #ifdef HAVE_FLOCK
2530 if (*fd != -1)
2531 close (*fd);
2533 *fd = -1;
2534 #endif