2 Copyright (C) 2006-2019 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 as published by
8 the Free Software Foundation, either version 2 of the License, or
9 (at your option) any later version.
11 Pwmd is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
29 #include <sys/socket.h>
43 #include <netinet/in.h>
44 #include <arpa/inet.h>
47 #include <sys/resource.h>
62 #ifdef HAVE_GETOPT_LONG
67 #include "getopt_long.h"
70 #ifdef HAVE_PR_SET_NAME
71 #include <sys/prctl.h>
74 #include "pwmd-error.h"
77 #include "util-misc.h"
83 #include "util-string.h"
95 static unsigned assuan_level
;
97 #ifndef HAVE_PTHREAD_CANCEL
98 #define INIT_SIGNAL(s, cb) do { \
99 int *n = xmalloc (sizeof (int)); \
101 pthread_setspecific (signal_thread_key, n); \
102 struct sigaction act; \
104 sigemptyset (&sigset); \
105 sigaddset (&sigset, s); \
106 pthread_sigmask (SIG_UNBLOCK, &sigset, NULL); \
107 memset (&act, 0, sizeof(act)); \
108 act.sa_flags = SA_SIGINFO; \
109 act.sa_mask = sigset; \
110 act.sa_sigaction = cb; \
111 sigaction (s, &act, NULL); \
115 catch_thread_signal (int sig
, siginfo_t
*info
, void *ctx
)
117 int *n
= (int *) pthread_getspecific (signal_thread_key
);
126 int n
= config_get_boolean ("global", "enable_logging");
130 char *p
= config_get_string ("global", "log_path");
132 if (!p
|| (logfile
&& p
&& log_fd
!= -1 && strcmp(p
, logfile
)))
143 logfile
= expand_homedir (p
);
157 log_syslog
= config_get_boolean ("global", "syslog");
159 openlog ("pwmd", LOG_NDELAY
| LOG_PID
, LOG_DAEMON
);
163 reload_rcfile_thread (void *arg
)
165 #ifndef HAVE_PTHREAD_CANCEL
166 INIT_SIGNAL (SIGUSR2
, catch_thread_signal
);
169 #ifdef HAVE_PR_SET_NAME
170 prctl (PR_SET_NAME
, "reload rcfile");
172 pthread_setspecific (thread_name_key
, str_asprintf ("!%s", __FUNCTION__
));
173 MUTEX_LOCK (&rcfile_mutex
);
179 struct slist_s
*keep
= NULL
;
180 struct slist_s
*config
;
181 int b
= disable_list_and_dump
;
187 pthread_cleanup_push (release_mutex_cb
, &rcfile_mutex
);
188 pthread_cond_wait (&rcfile_cond
, &rcfile_mutex
);
190 keep
= config_keep_save ();
191 log_write (_("reloading configuration file '%s'"), rcfile
);
194 prio
= config_get_string ("global", "tls_cipher_suite");
196 config
= config_parse (rcfile
, 1);
199 config_free (global_config
);
200 global_config
= config
;
204 config_keep_restore (keep
);
205 disable_list_and_dump
= !disable_list_and_dump
? b
: 1;
208 /* Restart listening sockets since they may have changed. */
212 prio2
= config_get_string ("global", "tls_cipher_suite");
213 if ((prio2
&& (!prio
|| strcmp (prio
, prio2
))) || (prio
&& !prio2
))
219 crypto_set_keepalive ();
220 pthread_cleanup_pop (0);
223 MUTEX_UNLOCK (&rcfile_mutex
);
227 #define PROCESS_DONE(client,rc) client->bulk_p ? rc : assuan_process_done (client->ctx,rc)
229 send_error (assuan_context_t ctx
, gpg_error_t e
)
231 struct client_s
*client
= assuan_get_pointer (ctx
);
233 if (gpg_err_source (e
) == GPG_ERR_SOURCE_UNKNOWN
)
240 return PROCESS_DONE (client
, 0);
244 log_write ("ERR %i: %s", e
, pwmd_strerror (e
));
248 if (client
&& client
->xml_error
)
250 log_write ("%s", client
->xml_error
->message
);
251 xfree (client
->last_error
);
252 client
->last_error
= NULL
;
253 if (client
->xml_error
->message
)
254 client
->last_error
= str_dup (client
->xml_error
->message
);
256 e
= PROCESS_DONE (client
, assuan_set_error (ctx
, e
,
257 client
->xml_error
->message
258 ? client
->xml_error
->message
260 xmlResetLastError ();
261 xmlResetError (client
->xml_error
);
262 xfree (client
->xml_error
);
263 client
->xml_error
= NULL
;
267 return PROCESS_DONE (client
, assuan_set_error (ctx
, e
, pwmd_strerror (e
)));
271 log_write (const char *fmt
, ...)
277 pthread_t tid
= pthread_self ();
278 static pthread_mutex_t m
= PTHREAD_MUTEX_INITIALIZER
;
280 if ((!logfile
&& !isatty (STDERR_FILENO
) && !log_syslog
) || !fmt
)
284 pthread_cleanup_push (release_mutex_cb
, &m
);
286 if (!cmdline
&& logfile
&& log_fd
== -1)
288 log_fd
= open (logfile
, O_WRONLY
| O_CREAT
| O_APPEND
, 0600);
290 warn ("%s", logfile
);
295 if (str_vasprintf (&args
, fmt
, ap
) != -1)
297 pthread_cleanup_push (xfree
, args
);
300 fprintf (stderr
, "pwmd: %s\n", args
);
305 char *name
= pthread_getspecific (thread_name_key
);
311 snprintf (buf
, sizeof (buf
), "%s: ", name
+1);
313 snprintf (buf
, sizeof (buf
), "%s(%p): ", name
,
317 snprintf (buf
, sizeof (buf
), "%p: ", (pthread_t
*)tid
);
320 if (!cmdline
&& log_syslog
&& !nofork
)
321 syslog (LOG_INFO
, "%s%s", name
, args
);
324 struct tm
*tm
= localtime (&now
);
326 strftime (tbuf
, sizeof (tbuf
), "%b %d %Y %H:%M:%S ", tm
);
327 tbuf
[sizeof (tbuf
) - 1] = 0;
329 if (args
[strlen (args
) - 1] == '\n')
330 args
[strlen (args
) - 1] = 0;
332 line
= str_asprintf ("%s %i %s%s\n", tbuf
, getpid (), name
, args
);
335 pthread_cleanup_push (xfree
, line
);
336 if (logfile
&& log_fd
!= -1)
338 ssize_t ret
= write (log_fd
, line
, strlen (line
));
345 fprintf (stdout
, "%s", line
);
349 pthread_cleanup_pop (1);
352 pthread_cleanup_pop (1);
357 if (log_fd
!= -1 && log_keepopen
<= 0)
363 pthread_cleanup_pop (1);
371 if (!gpgrt_check_version (REQUIRE_LIBGPGERROR_VERSION
))
373 fprintf (stderr
, _("gpgrt_check_version(): Incompatible libgpg-error. "
374 "Wanted %s, got %s.\n"), REQUIRE_LIBGPGERROR_VERSION
,
375 gpgrt_check_version (NULL
));
376 return GPG_ERR_UNKNOWN_VERSION
;
380 gpgrt_set_alloc_func (xrealloc_gpgrt
);
382 if (!assuan_check_version (REQUIRE_LIBASSUAN_VERSION
))
384 fprintf (stderr
, _("assuan_check_version(): Incompatible libassuan. "
385 "Wanted %s, got %s.\n"), REQUIRE_LIBASSUAN_VERSION
,
386 assuan_check_version (NULL
));
387 return GPG_ERR_UNKNOWN_VERSION
;
390 if (!gcry_check_version (REQUIRE_LIBGCRYPT_VERSION
))
392 fprintf (stderr
, _("gcry_check_version(): Incompatible libgcrypt. "
393 "Wanted %s, got %s.\n"), REQUIRE_LIBGCRYPT_VERSION
,
394 gcry_check_version (NULL
));
395 return GPG_ERR_UNKNOWN_VERSION
;
398 gcry_set_allocation_handler (xmalloc
, xmalloc
, NULL
, xrealloc
, xfree
);
400 if (!gpgme_check_version (REQUIRE_LIBGPGME_VERSION
))
402 fprintf (stderr
, _("gpgme_check_version(): Incompatible libgpgme. "
403 "Wanted %s, got %s.\n"), REQUIRE_LIBGPGME_VERSION
,
404 gpgme_check_version (NULL
));
405 return GPG_ERR_UNKNOWN_VERSION
;
408 rc
= gpgme_engine_check_version (GPGME_PROTOCOL_OPENPGP
);
411 fprintf (stderr
, _("gpgme_engine_check_version(GPGME_PROTOCOL_OPENPGP): %s"), gpgme_strerror (rc
));
412 return GPG_ERR_UNKNOWN_VERSION
;
415 //gpgme_set_global_flag ("require-gnupg", REQUIRE_GNUPG_VERSION);
417 gpgme_set_locale (NULL
, LC_CTYPE
, setlocale (LC_CTYPE
, NULL
));
418 gpgme_set_locale (NULL
, LC_MESSAGES
, setlocale (LC_MESSAGES
, NULL
));
422 if (gnutls_global_init ())
424 fprintf(stderr
, _("gnutls_global_init() failed.\n"));
425 return GPG_ERR_UNKNOWN_VERSION
;
428 if (!gnutls_check_version (REQUIRE_LIBGNUTLS_VERSION
))
430 fprintf (stderr
, _("gnutls_check_version(): Incompatible libgnutls. "
431 "Wanted %s, got %s.\n"), REQUIRE_LIBGNUTLS_VERSION
,
432 gnutls_check_version (NULL
));
433 return GPG_ERR_UNKNOWN_VERSION
;
436 gnutls_global_set_log_function (tls_log
);
437 gnutls_global_set_audit_log_function (tls_audit_log
);
443 xml_error_cb (void *data
, xmlErrorPtr e
)
445 struct client_s
*client
= data
;
448 * Keep the first reported error as the one to show in the error
449 * description. Reset in send_error().
451 if (client
->xml_error
)
454 client
->xml_error
= xcalloc (1, sizeof(xmlError
));
455 xmlCopyError (e
, client
->xml_error
);
459 hook_waitpid (assuan_context_t ctx
, pid_t pid
, int action
,
460 int *status
, int options
)
464 return waitpid (pid
, status
, options
);
468 hook_read (assuan_context_t ctx
, assuan_fd_t fd
, void *data
, size_t len
)
472 struct client_s
*client
= assuan_get_pointer (ctx
);
474 if (client
->thd
->remote
)
475 return tls_read_hook (ctx
, (int) fd
, data
, len
);
479 return read ((int) fd
, data
, len
);
483 hook_write (assuan_context_t ctx
, assuan_fd_t fd
,
484 const void *data
, size_t len
)
488 struct client_s
*client
= assuan_get_pointer (ctx
);
490 if (client
->thd
->remote
)
491 return tls_write_hook (ctx
, (int) fd
, data
, len
);
495 return write ((int) fd
, data
, len
);
499 assuan_log_cb (assuan_context_t ctx
, void *data
, unsigned cat
,
502 struct client_s
*client
= data
;
503 const char *str
= NULL
;
508 if (!(assuan_level
& cat
))
516 case ASSUAN_LOG_INIT
:
517 str
= "ASSUAN[INIT]";
522 case ASSUAN_LOG_ENGINE
:
523 str
= "ASSUAN[ENGINE]";
525 case ASSUAN_LOG_DATA
:
526 str
= "ASSUAN[DATA]";
528 case ASSUAN_LOG_SYSIO
:
529 str
= "ASSUAN[SYSIO]";
531 case ASSUAN_LOG_CONTROL
:
532 str
= "ASSUAN[CONTROL]";
535 str
= "ASSUAN[UNKNOWN]";
539 log_write ("%s: %s", str
, msg
);
544 new_connection (struct client_s
*cl
)
547 static struct assuan_malloc_hooks mhooks
= { xmalloc
, xrealloc
, xfree
};
548 static struct assuan_system_hooks shooks
= {
549 ASSUAN_SYSTEM_HOOKS_VERSION
,
557 NULL
, //sendmsg both are used for FD passing
568 char *prio
= config_get_string ("global", "tls_cipher_suite");
570 cl
->thd
->timeout
= config_get_integer ("global", "tls_timeout");
571 if (fcntl (cl
->thd
->fd
, F_SETFL
, O_NONBLOCK
) == -1)
574 cl
->thd
->tls
= tls_init_client (cl
->thd
->fd
, cl
->thd
->timeout
, prio
);
581 rc
= assuan_new_ext (&cl
->ctx
, GPG_ERR_SOURCE_DEFAULT
, &mhooks
,
586 assuan_ctx_set_system_hooks (cl
->ctx
, &shooks
);
587 rc
= assuan_init_socket_server (cl
->ctx
, cl
->thd
->fd
,
588 ASSUAN_SOCKET_SERVER_ACCEPTED
);
592 assuan_set_pointer (cl
->ctx
, cl
);
593 assuan_set_hello_line (cl
->ctx
, PACKAGE_STRING PWMD_GIT_HASH
);
594 rc
= register_commands (cl
->ctx
);
598 rc
= assuan_accept (cl
->ctx
);
602 rc
= validate_peer (cl
);
603 /* May not be implemented on all platforms. */
604 if (rc
&& gpg_err_code (rc
) != GPG_ERR_ASS_GENERAL
)
607 MUTEX_LOCK (&cn_mutex
);
608 cl
->thd
->state
= CLIENT_STATE_INIT
;
609 MUTEX_UNLOCK (&cn_mutex
);
610 cl
->lock_timeout
= config_get_integer ("global", "lock_timeout");
611 xmlSetStructuredErrorFunc (cl
, xml_error_cb
);
615 log_write ("%s", pwmd_strerror (rc
));
620 * This is called after a client is cancelled or disconnects. Set with
621 * pthread_cleanup_push().
624 free_client_cb (void *arg
)
626 struct client_thread_s
*cn
= arg
;
627 struct client_s
*cl
= cn
->cl
;
630 #ifndef HAVE_PTHREAD_CANCEL
631 tmp
= pthread_getspecific (signal_thread_key
);
633 pthread_setspecific (signal_thread_key
, NULL
);
636 MUTEX_LOCK (&cn_mutex
);
637 cn_thread_list
= slist_remove (cn_thread_list
, cn
);
638 MUTEX_UNLOCK (&cn_mutex
);
642 unlock_flock (&cl
->flock_fd
);
645 xmlResetError (cl
->xml_error
);
647 xfree (cl
->xml_error
);
652 gnutls_deinit (cn
->tls
->ses
);
659 assuan_release (cl
->ctx
);
660 else if (cl
->thd
&& cl
->thd
->fd
!= -1)
664 crypto_free (cl
->crypto
);
675 while (cn
->msg_queue
)
677 struct status_msg_s
*msg
= cn
->msg_queue
;
679 cn
->msg_queue
= msg
->next
;
684 if (cn
->status_msg_pipe
[0] != -1)
685 close (cn
->status_msg_pipe
[0]);
687 if (cn
->status_msg_pipe
[1] != -1)
688 close (cn
->status_msg_pipe
[1]);
690 pthread_mutex_destroy (&cn
->status_mutex
);
691 log_write (_("exiting, fd=%i"), cn
->fd
);
692 send_status_all (STATUS_CLIENTS
, NULL
);
696 xfree (cn
->peeraddr
);
699 if (cn
->eof
) // Not pthread_exit() or pthread_cancel().
701 tmp
= pthread_getspecific (thread_name_key
);
703 pthread_setspecific (thread_name_key
, NULL
);
706 (void)cache_kill_scd ();
713 MUTEX_LOCK (&cn_mutex
);
714 pthread_cleanup_push (release_mutex_cb
, &cn_mutex
);
716 while (slist_length (cn_thread_list
))
718 struct client_thread_s
*thd
= slist_nth_data (cn_thread_list
, 0);
720 free_client_cb (thd
);
724 pthread_cleanup_pop (1);
728 send_msg_queue (struct client_thread_s
*thd
)
730 MUTEX_LOCK (&thd
->status_mutex
);
735 ret
= read (thd
->status_msg_pipe
[0], &c
, 1);
736 rc
= gpg_error_from_syserror ();
737 if (ret
== -1 && gpg_err_code (rc
) != GPG_ERR_EAGAIN
)
738 log_write ("%s (%i): %s", __FUNCTION__
, __LINE__
, pwmd_strerror (rc
));
742 thd
->wrote_status
= 0;
744 while (thd
->msg_queue
)
746 struct status_msg_s
*msg
= thd
->msg_queue
;
748 thd
->msg_queue
= thd
->msg_queue
->next
;
749 MUTEX_UNLOCK (&thd
->status_mutex
);
750 pthread_cleanup_push (xfree
, msg
);
751 pthread_cleanup_push (xfree
, msg
->line
);
752 rc
= send_status (thd
->cl
->ctx
, msg
->s
, msg
->line
);
753 pthread_cleanup_pop (1);
754 pthread_cleanup_pop (1);
755 MUTEX_LOCK (&thd
->status_mutex
);
760 MUTEX_UNLOCK (&thd
->status_mutex
);
761 if (rc
&& gpg_err_code (rc
) != GPG_ERR_EPIPE
)
762 log_write ("%s (%i): %s", __FUNCTION__
, __LINE__
, pwmd_strerror (rc
));
768 client_thread (void *data
)
770 struct client_thread_s
*thd
= data
;
771 struct client_s
*cl
= xcalloc (1, sizeof (struct client_s
));
772 struct slist_s
*list
;
774 #ifndef HAVE_PTHREAD_CANCEL
775 INIT_SIGNAL (SIGUSR2
, catch_thread_signal
);
778 #ifdef HAVE_PR_SET_NAME
779 prctl (PR_SET_NAME
, "client");
781 pthread_setspecific (thread_name_key
, str_dup (__FUNCTION__
));
785 log_write ("%s(%i): %s", __FILE__
, __LINE__
,
786 pwmd_strerror (GPG_ERR_ENOMEM
));
790 MUTEX_LOCK (&cn_mutex
);
791 pthread_cleanup_push (free_client_cb
, thd
);
796 list
= slist_append (cn_thread_list
, thd
);
798 cn_thread_list
= list
;
801 log_write ("%s(%i): %s", __FILE__
, __LINE__
,
802 pwmd_strerror (GPG_ERR_ENOMEM
));
803 MUTEX_UNLOCK (&cn_mutex
);
807 if (fcntl (thd
->status_msg_pipe
[0], F_SETFL
, O_NONBLOCK
) == -1)
808 rc
= gpg_error_from_errno (errno
);
811 if (fcntl (thd
->status_msg_pipe
[1], F_SETFL
, O_NONBLOCK
) == -1)
812 rc
= gpg_error_from_errno (errno
);
814 MUTEX_UNLOCK (&cn_mutex
);
818 log_write ("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror (rc
));
822 if (new_connection (cl
))
824 struct pollfd fds
[2];
827 fds
[0].events
= POLLIN
;
828 fds
[1].fd
= thd
->status_msg_pipe
[0];
829 fds
[1].events
= POLLIN
;
831 send_status_all (STATUS_CLIENTS
, NULL
);
832 rc
= send_status (cl
->ctx
, STATUS_CACHE
, NULL
);
835 log_write ("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror (rc
));
844 n
= poll (fds
, sizeof(fds
)/sizeof(fds
[0]), 100);
847 log_write ("%s", strerror (errno
));
852 if (thd
->remote
&& thd
->tls
&& thd
->tls
->rehandshake
)
858 if (thd
->tls
->rehandshake
== 1)
860 prio
= config_get_string ("global", "tls_cipher_suite");
863 thd
->tls
->rehandshake
= 0;
867 ret
= gnutls_priority_set_direct (thd
->tls
->ses
, prio
, &e
);
868 if (ret
== GNUTLS_E_SUCCESS
)
870 rc
= send_status (cl
->ctx
, STATUS_REHANDSHAKE
, NULL
);
873 rc
= assuan_send_data (cl
->ctx
, NULL
, 0);
876 ret
= gnutls_rehandshake (thd
->tls
->ses
);
879 log_write ("%s", gnutls_strerror (ret
));
880 thd
->tls
->rehandshake
= 0;
883 thd
->tls
->rehandshake
= 2;
888 log_write ("%s", pwmd_strerror (rc
));
891 log_write ("%s: %s", gnutls_strerror (ret
), e
);
902 if (fds
[1].revents
& POLLIN
)
905 if (!thd
->remote
|| (thd
->tls
&& !thd
->tls
->rehandshake
))
908 rc
= send_msg_queue (thd
);
909 if (rc
&& gpg_err_code (rc
) != GPG_ERR_EPIPE
)
914 #ifdef HAVE_PTHREAD_CANCEL
915 if (!(fds
[0].revents
& POLLIN
))
917 if (thd
->fd
!= -1 && !(fds
[0].revents
& POLLIN
))
921 rc
= assuan_process_next (cl
->ctx
, &eof
);
924 if (gpg_err_code (rc
) == GPG_ERR_EOF
|| eof
)
927 log_write ("assuan_process_next(): rc=%u %s", rc
,
929 if (rc
== gpg_error (GPG_ERR_ETIMEDOUT
))
932 rc
= send_error (cl
->ctx
, rc
);
935 log_write ("assuan_process_done(): rc=%u %s", rc
,
941 /* Since the msg queue pipe fd's are non-blocking, check for
942 * pending status msgs here. GPG_ERR_EPIPE can be seen when the
943 * client has already disconnected and will be converted to
944 * GPG_ERR_EOF during assuan_process_next().
947 if (!thd
->remote
|| (thd
->tls
&& !thd
->tls
->rehandshake
))
950 rc
= send_msg_queue (thd
);
951 if (rc
&& gpg_err_code (rc
) != GPG_ERR_EPIPE
)
958 /* Don't do pthread_exit() here because any set pthread_cleanup_push
959 * functions would be called after a command failed but then the client
960 * exited normally which may lead to a double free. */
962 pthread_cleanup_pop (1);
967 xml_import (const char *filename
, const char *outfile
, char **keyid
,
968 char *sign_keyid
, char *keyfile
, const char *userid
,
969 const char *algo
, long expire
, int no_passphrase
, int symmetric
)
975 xmlChar
*xmlbuf
= NULL
;
977 struct crypto_s
*crypto
= NULL
;
979 if (strcmp (filename
, "-"))
981 rc
= open_check_file (filename
, &fd
, &st
, 0);
985 xmlbuf
= xmalloc (st
.st_size
+ 1);
989 return GPG_ERR_ENOMEM
;
992 if (read (fd
, xmlbuf
, st
.st_size
) == -1)
994 rc
= gpg_error_from_errno (errno
);
1000 xmlbuf
[st
.st_size
] = 0;
1005 #define BUFSIZE 8196
1006 size_t size
= 0, xlen
= 0;
1013 tmp
= xrealloc (xmlbuf
, size
+BUFSIZE
+1);
1017 return GPG_ERR_ENOMEM
;
1022 ret
= read (STDIN_FILENO
, &xmlbuf
[xlen
], BUFSIZE
);
1025 rc
= gpg_error_from_syserror ();
1031 if (!ret
|| ret
< BUFSIZE
)
1038 doc
= xmlReadDoc (xmlbuf
, NULL
, "UTF-8", XML_PARSE_NOBLANKS
);
1041 return GPG_ERR_BAD_DATA
;
1043 xmlNodePtr n
= xmlDocGetRootElement (doc
);
1044 if (n
&& !xmlStrEqual (n
->name
, (xmlChar
*) "pwmd"))
1045 rc
= GPG_ERR_BAD_DATA
;
1049 rc
= xml_validate_import (NULL
, n
? n
->children
: n
);
1052 rc
= crypto_init (&crypto
, NULL
, filename
, keyfile
!= NULL
, keyfile
);
1057 crypto
->flags
|= CRYPTO_FLAG_KEYFILE
;
1058 crypto
->keyfile
= str_dup (keyfile
);
1061 xmlDocDumpMemory (doc
, &crypto
->plaintext
, &len
);
1063 crypto
->plaintext_size
= len
;
1065 rc
= GPG_ERR_ENOMEM
;
1072 if (!symmetric
&& !keyid
)
1074 crypto
->save
.userid
= str_dup (userid
);
1075 crypto
->save
.algo
= algo
? str_dup (algo
) : NULL
;
1076 crypto
->save
.expire
= expire
;
1078 crypto
->save
.flags
|= GPGME_CREATE_NOPASSWD
;
1080 rc
= crypto_genkey (NULL
, crypto
);
1085 crypto
->save
.pubkey
= strv_dup (keyid
);
1088 crypto
->save
.sigkey
= str_dup (sign_keyid
);
1093 crypto
->flags
|= symmetric
? CRYPTO_FLAG_SYMMETRIC
: 0;
1094 rc
= crypto_encrypt (NULL
, crypto
);
1100 if (!strcmp (outfile
, "-"))
1103 xfree (crypto
->plaintext
);
1104 crypto
->plaintext
= NULL
;
1105 xfree (crypto
->filename
);
1106 crypto
->filename
= outfile
? str_dup (outfile
) : NULL
;
1107 rc
= crypto_write_file (crypto
, NULL
, NULL
);
1111 crypto_free (crypto
);
1116 do_cache_push (struct crypto_s
*crypto
)
1120 struct cache_data_s
*cdata
;
1125 log_write (_("Adding '%s' to the cache..."),
1128 if (valid_filename (crypto
->filename
) == 0)
1130 log_write (_("%s: Invalid characters in filename"), crypto
->filename
);
1131 return GPG_ERR_INV_VALUE
;
1134 rc
= lock_flock (NULL
, crypto
->filename
, LOCK_SH
, &fd
);
1136 rc
= crypto_decrypt (NULL
, crypto
);
1143 rc
= xml_parse_doc ((char *) crypto
->plaintext
, crypto
->plaintext_size
, &doc
);
1147 log_write ("%s", pwmd_strerror (rc
));
1151 cdata
= xcalloc (1, sizeof (struct cache_data_s
));
1156 return GPG_ERR_ENOMEM
;
1159 rc
= get_checksum (crypto
->filename
, &crc
, &len
);
1164 cache_free_data_once (cdata
);
1169 rc
= cache_encrypt (crypto
);
1172 cdata
->doc
= crypto
->plaintext
;
1173 cdata
->size
= crypto
->plaintext_size
;
1174 crypto
->plaintext
= NULL
;
1175 cdata
->pubkey
= crypto
->pubkey
;
1176 cdata
->sigkey
= crypto
->sigkey
;
1177 crypto
->pubkey
= NULL
;
1178 crypto
->sigkey
= NULL
;
1183 cache_free_data_once (cdata
);
1187 long timeout
= config_get_long (crypto
->filename
, "cache_timeout");
1188 rc
= cache_add_file (crypto
->filename
, cdata
, timeout
);
1193 init_client (int fd
, const char *addr
)
1196 struct client_thread_s
*new = xcalloc (1, sizeof (struct client_thread_s
));
1201 log_write ("%s: %s", __FUNCTION__
, pwmd_strerror (ENOMEM
));
1202 return GPG_ERR_ENOMEM
;
1205 MUTEX_LOCK (&cn_mutex
);
1206 pthread_cleanup_push (release_mutex_cb
, &cn_mutex
);
1207 new->conntime
= time (NULL
);
1209 if (pipe (new->status_msg_pipe
) == -1)
1210 rc
= gpg_error_from_errno (errno
);
1212 pthread_mutex_init (&new->status_mutex
, NULL
);
1217 new->remote
= addr
? 1 : 0;
1219 new->peeraddr
= str_dup (addr
);
1222 rc
= create_thread (client_thread
, new, &new->tid
, 1);
1225 close (new->status_msg_pipe
[0]);
1226 close (new->status_msg_pipe
[1]);
1227 pthread_mutex_destroy (&new->status_mutex
);
1234 log_write (_("new connection: tid=%p, fd=%i, addr=%s"),
1235 (pthread_t
*) new->tid
, fd
, addr
);
1237 log_write (_("new connection: tid=%p, fd=%i"),
1238 (pthread_t
*) new->tid
, fd
);
1241 pthread_cleanup_pop (1);
1247 log_write ("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror (rc
));
1254 do_tls_accept (struct pollfd
*fds
)
1256 struct sockaddr_storage raddr
;
1257 socklen_t slen
= sizeof (raddr
);
1259 char s
[INET6_ADDRSTRLEN
];
1261 if (!(fds
->revents
& POLLIN
))
1264 memset (&raddr
, 0, sizeof (raddr
));
1265 fd
= accept (fds
->fd
, (struct sockaddr
*) &raddr
, &slen
);
1270 if (errno
!= EAGAIN
&& !quit
)
1271 log_write ("%s: %s", __FUNCTION__
,
1272 pwmd_strerror (gpg_error_from_syserror()));
1274 return gpg_error_from_errno (e
);
1277 inet_ntop (raddr
.ss_family
, get_in_addr ((struct sockaddr
*) &raddr
), s
,
1279 (void) init_client (fd
, s
);
1285 accept_thread (void *arg
)
1287 int sockfd
= *(int *) arg
;
1288 #ifndef HAVE_PTHREAD_CANCEL
1289 INIT_SIGNAL (SIGUSR2
, catch_thread_signal
);
1292 #ifdef HAVE_PR_SET_NAME
1293 prctl (PR_SET_NAME
, "accept");
1295 pthread_setspecific (thread_name_key
, str_asprintf ("!%s", __FUNCTION__
));
1299 socklen_t slen
= sizeof (struct sockaddr_un
);
1300 struct sockaddr_un raddr
;
1302 struct pollfd fds
[3];
1305 memset (fds
, 0, sizeof (fds
));
1307 fds
[s
++].events
= POLLIN
;
1313 fds
[s
++].events
= POLLIN
;
1320 fds
[s
].fd
= tls6_fd
;
1321 fds
[s
++].events
= POLLIN
;
1324 fds
[s
].fd
= tls6_fd
;
1327 s
= poll (fds
, s
, 500);
1331 log_write ("%s", strerror (errno
));
1337 if (fds
[0].revents
& POLLIN
)
1339 fd
= accept (sockfd
, (struct sockaddr
*) &raddr
, &slen
);
1342 if (errno
== EMFILE
|| errno
== ENFILE
)
1343 log_write ("%s: %s", __FUNCTION__
,
1344 pwmd_strerror (gpg_error_from_errno (errno
)));
1345 else if (errno
!= EAGAIN
&& errno
!= EINTR
)
1347 if (!quit
) // probably EBADF
1348 log_write ("%s: %s", __FUNCTION__
,
1349 pwmd_strerror (gpg_error_from_errno (errno
)));
1357 (void) init_client (fd
, NULL
);
1361 if (tls_fd
!= -1 && fds
[1].fd
== tls_fd
)
1362 (void)do_tls_accept (&fds
[1]);
1364 if (tls6_fd
!= -1 && fds
[1].fd
== tls6_fd
)
1365 (void)do_tls_accept (&fds
[1]);
1367 if (tls6_fd
!= -1 && fds
[2].fd
== tls6_fd
)
1368 (void)do_tls_accept (&fds
[2]);
1372 /* Just in case accept() failed for some reason other than EBADF */
1378 cache_timer_thread (void *arg
)
1381 #ifndef HAVE_PTHREAD_CANCEL
1382 INIT_SIGNAL (SIGUSR2
, catch_thread_signal
);
1387 #ifdef HAVE_PR_SET_NAME
1388 prctl (PR_SET_NAME
, "timer");
1390 pthread_setspecific (thread_name_key
, str_asprintf ("!%s", __FUNCTION__
));
1394 struct timeval tv
= { 1, 0 };
1395 unsigned keepalive
= config_get_integer ("global", "keepalive_interval");
1398 select (0, NULL
, NULL
, NULL
, &tv
);
1399 cache_adjust_timeout ();
1401 if (keepalive
&& ++k
>= keepalive
)
1403 send_status_all (STATUS_KEEPALIVE
, NULL
);
1412 signal_loop (sigset_t sigset
)
1420 sigwait (&sigset
, &sig
);
1421 log_write (_("caught signal %i (%s)"), sig
, strsignal (sig
));
1426 pthread_cond_signal (&rcfile_cond
);
1429 log_write (_("clearing file cache"));
1430 cache_clear (NULL
, NULL
, 1, 0);
1431 send_status_all (STATUS_CACHE
, NULL
);
1446 log_write (_ ("Caught signal %i (%s). Exiting."), sig
, strsignal (sig
));
1447 #ifdef HAVE_BACKTRACE
1448 BACKTRACE (__FUNCTION__
);
1454 cancel_all_clients ()
1458 MUTEX_LOCK (&cn_mutex
);
1459 t
= slist_length (cn_thread_list
);
1460 for (i
= 0; i
< t
; i
++)
1462 struct client_thread_s
*thd
= slist_nth_data (cn_thread_list
, i
);
1464 #ifdef HAVE_PTHREAD_CANCEL
1465 pthread_cancel (thd
->tid
);
1467 pthread_kill (thd
->tid
, SIGUSR2
);
1471 while (slist_length (cn_thread_list
))
1473 MUTEX_UNLOCK (&cn_mutex
);
1475 MUTEX_LOCK (&cn_mutex
);
1478 MUTEX_UNLOCK (&cn_mutex
);
1482 server_loop (int sockfd
, char **socketpath
)
1484 pthread_t cache_timeout_tid
;
1485 pthread_t accept_tid
;
1486 int cancel_timeout_thread
= 0;
1487 int cancel_accept_thread
= 0;
1488 int cancel_rcfile_thread
= 0;
1495 sigemptyset (&sigset
);
1498 sigaddset (&sigset
, SIGTERM
);
1499 sigaddset (&sigset
, SIGINT
);
1501 /* Clears the file cache. */
1502 sigaddset (&sigset
, SIGUSR1
);
1504 /* Configuration file reloading. */
1505 sigaddset (&sigset
, SIGHUP
);
1507 #ifndef HAVE_PTHREAD_CANCEL
1509 The socket, cache and rcfile threads use this signal when
1510 pthread_cancel() is unavailable. Prevent the main thread from
1511 catching this signal from another process.
1513 sigaddset (&sigset
, SIGUSR2
);
1516 /* An assertion failure. */
1517 signal (SIGABRT
, catchsig
);
1519 sigaddset (&sigset
, SIGABRT
);
1520 sigprocmask (SIG_BLOCK
, &sigset
, NULL
);
1522 #ifndef HAVE_PTHREAD_CANCEL
1523 /* Remove this signal from the watched signals in signal_loop(). */
1524 sigdelset (&sigset
, SIGUSR2
);
1527 /* Can show a backtrace of the stack in the log. */
1528 signal (SIGSEGV
, catchsig
);
1530 char *p
= get_username (getuid());
1531 log_write (_("%s started for user %s"), PACKAGE_STRING PWMD_GIT_HASH
, p
);
1535 if (config_get_boolean ("global", "enable_tcp"))
1536 log_write (_("Listening on %s and TCP port %i"), *socketpath
,
1537 config_get_integer ("global", "tcp_port"));
1539 log_write (_("Listening on %s"), *socketpath
);
1541 log_write (_("Listening on %s"), *socketpath
);
1544 rc
= create_thread (reload_rcfile_thread
, NULL
, &rcfile_tid
, 0);
1547 log_write ("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1548 pwmd_strerror (rc
));
1552 cancel_rcfile_thread
= 1;
1553 rc
= create_thread (cache_timer_thread
, NULL
, &cache_timeout_tid
, 0);
1556 log_write ("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1557 pwmd_strerror (rc
));
1561 cancel_timeout_thread
= 1;
1562 rc
= create_thread (accept_thread
, &sockfd
, &accept_tid
, 0);
1565 log_write ("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1566 pwmd_strerror (rc
));
1570 cancel_accept_thread
= 1;
1572 signal_loop (sigset
);
1578 * We're out of the main server loop. This happens when a signal was sent
1579 * to terminate the daemon. Cancel all clients and exit.
1581 if (cancel_accept_thread
)
1583 #ifdef HAVE_PTHREAD_CANCEL
1584 n
= pthread_cancel (accept_tid
);
1586 n
= pthread_kill (accept_tid
, SIGUSR2
);
1589 pthread_join (accept_tid
, NULL
);
1592 if (cancel_timeout_thread
)
1594 #ifdef HAVE_PTHREAD_CANCEL
1595 n
= pthread_cancel (cache_timeout_tid
);
1597 n
= pthread_kill (cache_timeout_tid
, SIGUSR2
);
1600 pthread_join (cache_timeout_tid
, NULL
);
1606 shutdown (sockfd
, SHUT_RDWR
);
1608 unlink (*socketpath
);
1609 xfree (*socketpath
);
1611 MUTEX_LOCK (&cn_mutex
);
1612 n
= slist_length (cn_thread_list
);
1613 MUTEX_UNLOCK (&cn_mutex
);
1616 cancel_all_clients ();
1618 free_all_clients ();
1620 if (cancel_rcfile_thread
)
1622 #ifdef HAVE_PTHREAD_CANCEL
1623 pthread_cancel (rcfile_tid
);
1625 pthread_kill (rcfile_tid
, SIGUSR2
);
1626 pthread_cond_signal (&rcfile_cond
);
1628 pthread_join (rcfile_tid
, NULL
);
1633 return segv
? EXIT_FAILURE
: EXIT_SUCCESS
;
1637 usage (const char *pn
, int status
)
1639 FILE *fp
= status
== EXIT_FAILURE
? stderr
: stdout
;
1641 fprintf (fp
, _("Usage: %s [OPTIONS] [file1] [...]\n"
1642 " --homedir alternate pwmd home directory (~/.pwmd)\n"
1643 " -f, --rcfile=filename load the specfied configuration file\n"
1644 " (~/.pwmd/config)\n"
1645 " --kill terminate an existing instance of pwmd\n"
1646 " -n, --no-fork run as a foreground process\n"
1647 " --disable-dump disable the LIST, XPATH and DUMP commands\n"
1648 " --ignore, --force ignore cache pushing errors during startup\n"
1649 " -I, --import=filename import a pwmd DTD formatted XML file)\n"
1650 " -k, --passphrase-file=file for use when importing\n"
1651 " -o, --outfile=filename output file when importing\n"
1652 " --keyid=fpr[,..] public key to use when encrypting\n"
1653 " --sign-keyid=fpr fingerprint of the signing key to use\n"
1654 " -s, --symmetric use conventional encryption with optional signer\n"
1655 " --userid=string name and email address to use when importing\n"
1656 " --algo=string algorithm to use when importing (engine default)\n"
1657 " --expire=seconds key expiry time when importing (3 years)\n"
1658 " --no-passphrase don't require a passphrase when importing\n"
1659 " --debug=[a:..][,g:N][,t:N] enable debugging (a:[ixedsc],g:[1-9],t:[0-N])\n"
1660 " --help this help text\n"
1661 " --version show version and compile time features\n"),
1667 unlink_stale_socket (const char *sock
, const char *pidfile
)
1669 log_write (_ ("removing stale socket %s"), sock
);
1675 test_pidfile (const char *path
, const char *sock
, char *buf
, size_t buflen
,
1676 char **pidfile
, int create
, mode_t mode
, int terminate
)
1684 snprintf (buf
, buflen
, "%s/%s.pid", homedir
, sock
);
1685 *pidfile
= str_dup (buf
);
1686 fd
= open (buf
, O_RDONLY
);
1689 fd
= open (*pidfile
, O_CREAT
|O_WRONLY
|O_TRUNC
, mode
);
1693 if (!create
&& errno
!= ENOENT
)
1695 log_write ("%s: %s", buf
, pwmd_strerror (errno
));
1700 else if (!create
&& !terminate
)
1703 log_write ("%s: %s", *pidfile
, strerror (errno
));
1709 snprintf (buf
, buflen
, "%i", getpid ());
1710 ssize_t ret
= write (fd
, buf
, strlen (buf
));
1712 log_write ("%s (%i): %s", __FUNCTION__
, __LINE__
,
1713 pwmd_strerror (gpg_error_from_syserror ()));
1718 len
= read (fd
, buf
, buflen
);
1722 unlink_stale_socket (path
, *pidfile
);
1726 if (sscanf (buf
, "%5i", &pid
) != 1 || pid
== 0)
1730 unlink_stale_socket (path
, *pidfile
);
1735 if (kill (pid
, 0) == -1)
1737 unlink_stale_socket (path
, *pidfile
);
1743 if (kill (pid
, SIGTERM
) == -1)
1744 log_write ("%s: %s", path
, pwmd_strerror (errno
));
1747 log_write (_ ("an instance for socket %s is already running"), path
);
1755 parse_debug_level (const char *str
, unsigned *debug
, int *gpgme
, int *tls
)
1761 for (p
= str
; p
&& *p
; p
++)
1763 if (*p
== 'a') // assuan debug flags
1773 level
|= ASSUAN_LOG_INIT
;
1776 level
|= ASSUAN_LOG_CTX
;
1779 level
|= ASSUAN_LOG_ENGINE
;
1782 level
|= ASSUAN_LOG_DATA
;
1785 level
|= ASSUAN_LOG_SYSIO
;
1788 level
|= ASSUAN_LOG_CONTROL
;
1803 else if (*p
== 'g' || *p
== 't') // gpgme and TLS debug level
1811 if (!isdigit (*++p
))
1820 if (tl
< 0 || gl
< 0 || gl
> 9)
1823 while (isdigit (*p
))
1827 if (*(p
+1) && *(p
+1) != ',')
1847 main (int argc
, char *argv
[])
1850 struct sockaddr_un addr
;
1852 char *socketpath
= NULL
, *socketdir
, *socketname
= NULL
;
1853 char *socketarg
= NULL
;
1854 char *datadir
= NULL
;
1855 char *pidfile
= NULL
;
1859 char **cache_push
= NULL
;
1860 char *import
= NULL
, *keyid
= NULL
, *sign_keyid
= NULL
;
1861 char *userid
= NULL
;
1864 int no_passphrase
= 0;
1865 int estatus
= EXIT_FAILURE
;
1867 char *outfile
= NULL
;
1870 int show_version
= 0;
1873 char *keyfile
= NULL
;
1878 int gpgme_level
= -1;
1881 /* Must maintain the same order as longopts[] */
1884 OPT_VERSION
, OPT_HELP
, OPT_HOMEDIR
, OPT_NO_FORK
, OPT_DISABLE_DUMP
,
1885 OPT_FORCE
, OPT_RCFILE
, OPT_PASSPHRASE_FILE
, OPT_IMPORT
, OPT_OUTFILE
,
1886 OPT_KEYID
, OPT_SIGN_KEYID
, OPT_SYMMETRIC
, OPT_USERID
, OPT_ALGO
, OPT_EXPIRE
,
1887 OPT_NOPASSPHRASE
, OPT_KILL
, OPT_DEBUG
1889 const char *optstring
= "nf:C:k:I:o:s";
1890 const struct option longopts
[] = {
1891 {"version", no_argument
, 0, 0},
1892 {"help", no_argument
, 0, 0},
1893 {"homedir", required_argument
, 0, 0},
1894 {"no-fork", no_argument
, 0, 'n'},
1895 {"disable_dump", no_argument
, 0, 0},
1896 {"force", no_argument
, 0, 0},
1897 {"rcfile", required_argument
, 0, 'f'},
1898 {"passphrase-file", required_argument
, 0, 'k'},
1899 {"import", required_argument
, 0, 'I'},
1900 {"outfile", required_argument
, 0, 'o'},
1901 {"keyid", required_argument
, 0, 0},
1902 {"sign-keyid", required_argument
, 0, 0},
1903 {"symmetric", no_argument
, 0, 's'},
1904 {"userid", required_argument
, 0, 0},
1905 {"algo", required_argument
, 0, 0},
1906 {"expire", required_argument
, 0, 0},
1907 {"no-passphrase", no_argument
, 0, 0},
1908 {"kill", no_argument
, 0, 0},
1909 {"debug", required_argument
, 0, 0},
1915 expire
= time (NULL
) + DEFAULT_EXPIRE
;
1918 #ifdef HAVE_SETRLIMIT
1921 rl
.rlim_cur
= rl
.rlim_max
= 0;
1923 if (setrlimit (RLIMIT_CORE
, &rl
) != 0)
1924 err (EXIT_FAILURE
, "setrlimit()");
1927 #ifdef HAVE_PR_SET_DUMPABLE
1928 prctl (PR_SET_DUMPABLE
, 0);
1933 setlocale (LC_ALL
, "");
1934 bindtextdomain ("pwmd", LOCALEDIR
);
1935 textdomain ("pwmd");
1938 while ((opt
= getopt_long (argc
, argv
, optstring
, longopts
, &optindex
))
1956 rcfile
= str_dup (optarg
);
1962 usage (argv
[0], EXIT_FAILURE
);
1968 if (parse_debug_level (optarg
, &assuan_level
, &gpgme_level
,
1970 usage (argv
[0], EXIT_FAILURE
);
1979 usage (argv
[0], EXIT_SUCCESS
);
1982 homedir
= str_dup (optarg
);
1987 case OPT_DISABLE_DUMP
:
1994 rcfile
= str_dup (optarg
);
1996 case OPT_PASSPHRASE_FILE
:
2008 case OPT_SIGN_KEYID
:
2009 sign_keyid
= optarg
;
2019 expire
= strtoul (optarg
, &p
, 10);
2021 if (!errno
&& p
&& *p
)
2022 rc
= GPG_ERR_INV_VALUE
;
2023 else if (expire
== ULONG_MAX
)
2024 rc
= GPG_ERR_INV_VALUE
;
2026 rc
= gpg_error_from_syserror ();
2029 usage (argv
[0], EXIT_FAILURE
);
2031 case OPT_NOPASSPHRASE
:
2038 usage (argv
[0], EXIT_FAILURE
);
2046 "Copyright (C) 2006-2019\n"
2048 "Released under the terms of the GPL v2.\n\n"
2049 "Compile time features:\n%s"), PACKAGE_STRING PWMD_GIT_HASH
,
2052 "+PWMD_HOMEDIR=" PWMD_HOMEDIR
"\n"
2080 exit (EXIT_SUCCESS
);
2083 if (gpgme_level
!= -1)
2085 char s
[2] = { gpgme_level
+ '0', 0 };
2087 if (getenv ("GPGME_DEBUG"))
2088 log_write (_ ("Overriding GPGME_DEBUG environment with level %u!"),
2091 gpgme_set_global_flag ("debug", s
);
2094 if (setup_crypto ())
2095 exit (EXIT_FAILURE
);
2098 tls_level
= tls_level
== -1 ? 1 : tls_level
;
2099 gnutls_global_set_log_level (tls_level
);
2103 xmlMemSetup (xfree
, xmalloc
, xrealloc
, str_dup
);
2111 homedir
= str_dup(PWMD_HOMEDIR
);
2113 homedir
= str_asprintf ("%s/.pwmd", get_home_dir());
2116 if (mkdir (homedir
, 0700) == -1 && errno
!= EEXIST
)
2117 err (EXIT_FAILURE
, "%s", homedir
);
2120 rcfile
= str_asprintf ("%s/config", homedir
);
2122 pthread_key_create (&last_error_key
, free_key
);
2123 #ifndef HAVE_PTHREAD_CANCEL
2124 pthread_key_create (&signal_thread_key
, free_key
);
2127 pthread_mutexattr_t attr
;
2128 pthread_mutexattr_init (&attr
);
2129 pthread_mutexattr_settype (&attr
, PTHREAD_MUTEX_RECURSIVE
);
2130 pthread_mutex_init (&rcfile_mutex
, &attr
);
2131 global_config
= config_parse (rcfile
, 0);
2134 pthread_mutexattr_destroy (&attr
);
2135 pthread_mutex_destroy (&rcfile_mutex
);
2136 exit (EXIT_FAILURE
);
2139 p
= config_get_string ("global", "gpg_homedir");
2141 datadir
= str_asprintf ("%s/.gnupg", homedir
);
2143 datadir
= expand_homedir (p
);
2146 if (mkdir (datadir
, 0700) == -1 && errno
!= EEXIST
)
2147 err (EXIT_FAILURE
, "%s", datadir
);
2149 rc
= gpgme_set_engine_info (GPGME_PROTOCOL_OpenPGP
, NULL
, datadir
);
2151 errx (EXIT_FAILURE
, "%s: %s", datadir
, pwmd_strerror (rc
));
2154 snprintf (buf
, sizeof (buf
), "%s/data", homedir
);
2155 if (mkdir (buf
, 0700) == -1 && errno
!= EEXIST
)
2156 err (EXIT_FAILURE
, "%s", buf
);
2158 datadir
= str_dup (buf
);
2159 pthread_cond_init (&rcfile_cond
, NULL
);
2160 pthread_mutex_init (&cn_mutex
, &attr
);
2161 pthread_mutexattr_destroy (&attr
);
2165 x
= config_get_int_param (global_config
, "global", "priority", &exists
);
2166 if (exists
&& x
!= atoi(INVALID_PRIORITY
))
2169 if (setpriority (PRIO_PROCESS
, 0, x
) == -1)
2171 log_write ("setpriority(): %s",
2172 pwmd_strerror (gpg_error_from_errno (errno
)));
2176 #ifdef HAVE_MLOCKALL
2177 if (disable_mlock
== 0 && mlockall (MCL_CURRENT
| MCL_FUTURE
) == -1)
2179 log_write ("mlockall(): %s",
2180 pwmd_strerror (gpg_error_from_errno (errno
)));
2188 log_write ("pwmd: ERR %i: %s", rc
, pwmd_strerror (rc
));
2189 exit (EXIT_FAILURE
);
2194 char **keyids
= NULL
;
2196 if (!outfile
|| !*outfile
|| argc
!= optind
)
2197 usage (argv
[0], EXIT_FAILURE
);
2200 keyids
= str_split (keyid
, ",", 0);
2201 else if (!userid
&& !sym
)
2202 usage (argv
[0], EXIT_FAILURE
);
2204 rc
= xml_import (import
, outfile
, keyids
, sign_keyid
, keyfile
, userid
,
2205 algo
, expire
, no_passphrase
, sym
);
2209 if (gpg_err_source (rc
) == GPG_ERR_SOURCE_UNKNOWN
)
2210 rc
= gpg_error (rc
);
2212 log_write ("%s: %u: %s", import
, rc
, pwmd_strerror (rc
));
2215 config_free (global_config
);
2217 exit (rc
? EXIT_FAILURE
: EXIT_SUCCESS
);
2220 p
= config_get_string ("global", "socket_path");
2222 p
= str_asprintf ("%s/socket", homedir
);
2224 socketarg
= expand_homedir (p
);
2228 disable_list_and_dump
= config_get_boolean ("global",
2229 "disable_list_and_dump");
2231 disable_list_and_dump
= secure
;
2233 cache_push
= config_get_list ("global", "cache_push");
2235 while (optind
< argc
)
2237 if (strv_printf (&cache_push
, "%s", argv
[optind
++]) == 0)
2238 errx (EXIT_FAILURE
, "%s", pwmd_strerror (GPG_ERR_ENOMEM
));
2241 if (!strchr (socketarg
, '/'))
2243 socketdir
= getcwd (buf
, sizeof (buf
));
2244 socketname
= str_dup (socketarg
);
2245 socketpath
= str_asprintf ("%s/%s", socketdir
, socketname
);
2249 socketname
= str_dup (strrchr (socketarg
, '/')+1);
2250 socketarg
[strlen (socketarg
) - strlen (socketname
) - 1] = 0;
2251 socketdir
= str_dup (socketarg
);
2252 socketpath
= str_asprintf ("%s/%s", socketdir
, socketname
);
2255 if (chdir (datadir
))
2257 log_write ("%s: %s", datadir
,
2258 pwmd_strerror (gpg_error_from_errno (errno
)));
2259 unlink (socketpath
);
2263 x
= test_pidfile (socketpath
, socketname
, buf
, sizeof(buf
), &pidfile
, 0,
2265 if (!terminate
&& x
)
2269 estatus
= x
!= 1 ? EXIT_FAILURE
: EXIT_SUCCESS
;
2274 * bind() doesn't like the full pathname of the socket or any non alphanum
2275 * characters so change to the directory where the socket is wanted then
2276 * create it then change to datadir.
2278 if (chdir (socketdir
))
2280 log_write ("%s: %s", socketdir
,
2281 pwmd_strerror (gpg_error_from_errno (errno
)));
2287 if ((sockfd
= socket (PF_UNIX
, SOCK_STREAM
, 0)) == -1)
2289 log_write ("socket(): %s", pwmd_strerror (gpg_error_from_errno (errno
)));
2293 addr
.sun_family
= AF_UNIX
;
2294 snprintf (addr
.sun_path
, sizeof (addr
.sun_path
), "%s", socketname
);
2296 if (bind (sockfd
, (struct sockaddr
*) &addr
, sizeof (struct sockaddr
)) ==
2299 log_write ("bind(): %s", pwmd_strerror (gpg_error_from_errno (errno
)));
2301 if (errno
== EADDRINUSE
)
2304 log_write (_("Either there is another pwmd running or '%s' is a \n"
2305 "stale socket. Please remove it manually."), socketpath
);
2312 char *t
= config_get_string ("global", "socket_perms");
2317 mode
= strtol (t
, NULL
, 8);
2321 if (chmod (socketname
, mode
) == -1)
2323 log_write ("%s: %s", socketname
,
2324 pwmd_strerror (gpg_error_from_errno (errno
)));
2334 if (chdir (datadir
))
2336 log_write ("%s: %s", datadir
,
2337 pwmd_strerror (gpg_error_from_errno (errno
)));
2344 if (config_get_boolean ("global", "enable_tcp"))
2346 if (!tls_start_stop (0))
2355 * Set the cache entry for a file. Prompts for the password.
2359 for (opt
= 0; cache_push
[opt
]; opt
++)
2361 struct crypto_s
*crypto
= NULL
;
2362 char *pw_file
= config_get_string (cache_push
[opt
],
2364 rc
= crypto_init (&crypto
, NULL
, cache_push
[opt
], pw_file
!= NULL
,
2369 crypto
->flags
|= pw_file
? CRYPTO_FLAG_KEYFILE
: 0;
2370 crypto
->keyfile
= pw_file
;
2377 estatus
= EXIT_FAILURE
;
2381 rc
= do_cache_push (crypto
);
2384 log_write ("ERR %u: %s", rc
, pwmd_strerror(rc
));
2385 strv_free (cache_push
);
2386 log_write (_ ("Failed to add a file to the cache. Use --force to force startup. Exiting."));
2387 cache_clear (NULL
, NULL
, 1, 0);
2388 estatus
= EXIT_FAILURE
;
2389 crypto_free (crypto
);
2390 (void)cache_kill_scd ();
2394 log_write ("%s: %s", crypto
->filename
, pwmd_strerror(rc
));
2396 log_write (_("Successfully added '%s' to the cache."),
2399 crypto_free (crypto
);
2402 (void)cache_kill_scd ();
2403 strv_free (cache_push
);
2404 log_write (!nofork
? _("Done. Daemonizing...") :
2405 _("Done. Waiting for connections..."));
2408 backlog
= config_get_integer ("global", "backlog");
2409 if (listen (sockfd
, backlog
) == -1)
2411 log_write ("listen(): %s", pwmd_strerror (gpg_error_from_errno (errno
)));
2415 /* A client should set these with the OPTION command. */
2416 unsetenv ("DISPLAY");
2417 unsetenv ("GPG_TTY");
2425 log_write ("fork(): %s",
2426 pwmd_strerror (gpg_error_from_errno (errno
)));
2435 _exit (EXIT_SUCCESS
);
2439 (void)test_pidfile (socketpath
, socketname
, buf
, sizeof(buf
), &pidfile
, 1,
2443 pthread_key_create (&thread_name_key
, free_key
);
2444 pthread_setspecific (thread_name_key
, str_asprintf ("!%s", __FUNCTION__
));
2445 estatus
= server_loop (sockfd
, &socketpath
);
2448 if (socketpath
&& do_unlink
)
2450 unlink (socketpath
);
2456 gnutls_global_deinit ();
2457 tls_deinit_params ();
2459 pthread_cond_destroy (&rcfile_cond
);
2460 pthread_mutex_destroy (&rcfile_mutex
);
2461 pthread_key_delete (last_error_key
);
2462 #ifndef HAVE_PTHREAD_CANCEL
2463 pthread_key_delete (signal_thread_key
);
2467 config_free (global_config
);
2469 free_invoking_users (invoking_users
);
2471 xfree (home_directory
);
2473 xmlCleanupParser ();
2474 xmlCleanupGlobals ();
2480 if (estatus
== EXIT_SUCCESS
&& !terminate
)
2481 log_write (_("pwmd exiting normally"));
2483 pthread_key_delete (thread_name_key
);
2493 gpg_error_t
lock_flock (assuan_context_t ctx
, const char *filename
,
2499 rc
= open_check_file (filename
, fd
, NULL
, 1);
2503 TRY_FLOCK (ctx
, *fd
, type
, rc
);
2514 void unlock_flock (int *fd
)