1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
4 Ben Kibbey <bjk@luxsci.net>
6 This file is part of pwmd.
8 Pwmd is free software: you can redistribute it and/or modify
9 it under the terms of the GNU General Public License as published by
10 the Free Software Foundation, either version 2 of the License, or
11 (at your option) any later version.
13 Pwmd is distributed in the hope that it will be useful,
14 but WITHOUT ANY WARRANTY; without even the implied warranty of
15 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 GNU General Public License for more details.
18 You should have received a copy of the GNU General Public License
19 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
41 #include <glib/gprintf.h>
46 #include <netinet/in.h>
47 #include <arpa/inet.h>
50 #include <sys/resource.h>
59 #ifdef HAVE_PR_SET_NAME
60 #include <sys/prctl.h>
63 #include "pwmd-error.h"
79 static gboolean nofork
;
80 static pthread_cond_t quit_cond
;
81 static pthread_mutex_t quit_mutex
;
82 static gboolean no_passphrase_file
= FALSE
;
84 gboolean
do_cache_push(const gchar
*filename
, struct crypto_s
*crypto
);
85 static gboolean
signal_loop(sigset_t sigset
);
87 GCRY_THREAD_OPTION_PTHREAD_IMPL
;
89 static void cache_push_from_rcfile()
91 struct crypto_s
*crypto
;
92 gpg_error_t rc
= init_client_crypto(&crypto
);
95 log_write("%s: %s", __FUNCTION__
, pwmd_strerror(rc
));
99 rc
= set_agent_option(crypto
->agent
, "pinentry-mode", "error");
101 log_write("%s: %s", __FUNCTION__
, pwmd_strerror(rc
));
105 if (g_key_file_has_key(keyfileh
, "global", "cache_push", NULL
)) {
106 gchar
**cache_push
= g_key_file_get_string_list(keyfileh
, "global",
107 "cache_push", NULL
, NULL
);
110 for (p
= cache_push
; *p
; p
++) {
111 (void)do_cache_push(*p
, crypto
);
112 cleanup_crypto_stage1(crypto
);
115 g_strfreev(cache_push
);
118 (void)kill_scd(crypto
->agent
);
119 cleanup_crypto(&crypto
);
122 static void *reload_rcfile_thread(void *arg
)
124 #ifdef HAVE_PR_SET_NAME
125 prctl(PR_SET_NAME
, "reload rcfile");
127 pthread_setspecific(thread_name_key
, g_strdup(__FUNCTION__
));
128 MUTEX_LOCK(&rcfile_mutex
);
129 pthread_cleanup_push(cleanup_mutex_cb
, &rcfile_mutex
);
132 gboolean b
= disable_list_and_dump
;
136 pthread_cond_wait(&rcfile_cond
, &rcfile_mutex
);
137 users
= g_key_file_get_string_list(keyfileh
, "global", "allowed", NULL
, NULL
);
138 log_write(_("reloading configuration file '%s'"), rcfile
);
139 k
= parse_rcfile(FALSE
, cmdline
);
141 g_key_file_free(keyfileh
);
143 cache_push_from_rcfile();
147 disable_list_and_dump
= !disable_list_and_dump
? b
: TRUE
;
148 g_key_file_set_string_list(keyfileh
, "global", "allowed",
149 (const gchar
**)users
, g_strv_length(users
));
153 pthread_cleanup_pop(1);
157 gpg_error_t
send_error(assuan_context_t ctx
, gpg_error_t e
)
159 struct client_s
*client
= assuan_get_pointer(ctx
);
161 if (gpg_err_source(e
) == GPG_ERR_SOURCE_UNKNOWN
)
168 return assuan_process_done(ctx
, 0);
171 log_write("%s", pwmd_strerror(e
));
175 if (gpg_err_code(e
) == GPG_ERR_BAD_DATA
) {
176 xmlErrorPtr xe
= client
->xml_error
;
179 xe
= xmlGetLastError();
181 log_write("%s", xe
->message
);
182 if (client
->last_error
)
183 g_free(client
->last_error
);
185 client
->last_error
= g_strdup(xe
->message
);
188 e
= assuan_process_done(ctx
, assuan_set_error(ctx
, e
,
189 xe
? xe
->message
: NULL
));
191 if (xe
== client
->xml_error
)
196 client
->xml_error
= NULL
;
200 return assuan_process_done(ctx
, assuan_set_error(ctx
, e
, pwmd_strerror(e
)));
203 int assuan_log_cb(assuan_context_t ctx
, void *data
, unsigned cat
,
206 static pthread_mutex_t m
= PTHREAD_MUTEX_INITIALIZER
;
208 gboolean match
= FALSE
;
210 pthread_mutex_lock(&m
);
211 pthread_cleanup_push((void (*)(void *))pthread_mutex_unlock
, &m
);
212 t
= g_strv_length(debug_level
);
214 for (i
= 0; i
< t
; i
++) {
215 if (!g_ascii_strcasecmp(debug_level
[i
], (gchar
*)"init")
216 && cat
== ASSUAN_LOG_INIT
) {
221 if (!g_ascii_strcasecmp(debug_level
[i
], (gchar
*)"ctx")
222 && cat
== ASSUAN_LOG_CTX
) {
227 if (!g_ascii_strcasecmp(debug_level
[i
], (gchar
*)"engine")
228 && cat
== ASSUAN_LOG_ENGINE
) {
233 if (!g_ascii_strcasecmp(debug_level
[i
], (gchar
*)"data")
234 && cat
== ASSUAN_LOG_DATA
) {
239 if (!g_ascii_strcasecmp(debug_level
[i
], (gchar
*)"sysio")
240 && cat
== ASSUAN_LOG_SYSIO
) {
245 if (!g_ascii_strcasecmp(debug_level
[i
], (gchar
*)"control")
246 && cat
== ASSUAN_LOG_CONTROL
) {
256 if ((fd
= open(logfile
, O_WRONLY
|O_CREAT
|O_APPEND
, 0600)) == -1)
259 pthread_cleanup_push(cleanup_fd_cb
, &fd
);
260 write(fd
, msg
, strlen(msg
));
261 pthread_cleanup_pop(1);
266 fprintf(stderr
, "%s%s", data
? (gchar
*)data
: "", msg
);
271 pthread_cleanup_pop(1);
275 void log_write(const gchar
*fmt
, ...)
285 pthread_t tid
= pthread_self();
286 static pthread_mutex_t m
= PTHREAD_MUTEX_INITIALIZER
;
288 if ((!logfile
&& !isatty(STDERR_FILENO
) && !log_syslog
) || !fmt
)
291 pthread_mutex_lock(&m
);
292 pthread_cleanup_push((void (*)(void *))pthread_mutex_unlock
, &m
);
293 pthread_cleanup_push(cleanup_fd_cb
, &fd
);
295 if (!cmdline
&& logfile
) {
296 if ((fd
= open(logfile
, O_WRONLY
|O_CREAT
|O_APPEND
, 0600)) == -1)
302 if (g_vasprintf(&args
, fmt
, ap
) != -1) {
304 pthread_cleanup_push(g_free
, args
);
305 fprintf(stderr
, "%s\n", args
);
307 pthread_cleanup_pop(1);
310 pthread_cleanup_push(g_free
, args
);
311 name
= pthread_getspecific(thread_name_key
);
312 name
= print_fmt(buf
, sizeof(buf
), "%s(%p): ",
313 name
? name
: _("unknown"), (pthread_t
*)tid
);
315 if (!cmdline
&& log_syslog
&& !nofork
)
316 syslog(LOG_INFO
, "%s%s", name
, args
);
319 tm
= localtime(&now
);
320 strftime(tbuf
, sizeof(tbuf
), "%b %d %Y %H:%M:%S ", tm
);
321 tbuf
[sizeof(tbuf
) - 1] = 0;
323 if (args
[strlen(args
)-1] == '\n')
324 args
[strlen(args
)-1] = 0;
326 line
= g_strdup_printf("%s %i %s%s\n", tbuf
, getpid(), name
,
328 pthread_cleanup_pop(1);
330 pthread_cleanup_push(g_free
, line
);
331 if (logfile
&& fd
!= -1) {
332 write(fd
, line
, strlen(line
));
337 fprintf(stdout
, "%s", line
);
341 pthread_cleanup_pop(1);
347 pthread_cleanup_pop(1);
348 pthread_cleanup_pop(0);
349 pthread_mutex_unlock(&m
);
352 static gpg_error_t
setup_crypto()
356 gcry_control(GCRYCTL_SET_THREAD_CBS
, &gcry_threads_pthread
);
358 if (!gcry_check_version(NULL
))
359 errx(EXIT_FAILURE
, _("gcry_check_version(): Incompatible libgcrypt. Wanted %s, got %s."), GCRYPT_VERSION
, gcry_check_version(NULL
));
361 gcry_set_allocation_handler(g_malloc
, g_malloc
, NULL
, g_realloc
, g_free
);
365 static gpg_error_t
validate_peer(struct client_s
*cl
)
368 gboolean allowed
= FALSE
;
369 assuan_peercred_t peercred
;
370 gpg_error_t rc
= assuan_get_peercred(cl
->ctx
, &peercred
);
375 users
= g_key_file_get_string_list(keyfileh
, "global", "allowed", NULL
, NULL
);
378 for (gchar
**p
= users
; *p
; p
++) {
379 struct passwd pw
, *result
;
380 struct group gr
, *gresult
;
384 size_t len
= sysconf(_SC_GETGR_R_SIZE_MAX
);
393 return GPG_ERR_ENOMEM
;
396 if (!getgrnam_r(*(p
)+1, &gr
, buf
, len
, &gresult
) && gresult
) {
397 if (gresult
->gr_gid
== peercred
->gid
) {
403 len
= sysconf(_SC_GETPW_R_SIZE_MAX
);
408 gchar
*tbuf
= g_malloc(len
);
410 for (gchar
**t
= gresult
->gr_mem
; *t
; t
++) {
411 if (!getpwnam_r(*t
, &pw
, tbuf
, len
, &result
) && result
) {
412 if (result
->pw_uid
== peercred
->uid
) {
427 size_t len
= sysconf(_SC_GETPW_R_SIZE_MAX
);
436 return GPG_ERR_ENOMEM
;
439 if (!getpwnam_r(*p
, &pw
, buf
, len
, &result
) && result
) {
440 if (result
->pw_uid
== peercred
->uid
) {
454 log_write("peer %s: uid=%i, gid=%i, pid=%i",
455 allowed
? _("accepted") : _("rejected"), peercred
->uid
,
456 peercred
->gid
, peercred
->pid
);
457 return allowed
? 0 : GPG_ERR_INV_USER_ID
;
460 static void xml_error_cb(void *data
, xmlErrorPtr e
)
462 struct client_s
*client
= data
;
465 * Keep the first reported error as the one to show in the error
466 * description. Reset in send_error().
468 if (client
->xml_error
)
471 xmlCopyError(e
, client
->xml_error
);
474 static gboolean
new_connection(struct client_s
*cl
)
477 static struct assuan_malloc_hooks mhooks
= { g_malloc
, g_realloc
, g_free
};
479 cl
->thd
->status_msg_pipe
[0] = -1;
480 cl
->thd
->status_msg_pipe
[1] = -1;
481 rc
= assuan_new_ext(&cl
->ctx
, GPG_ERR_SOURCE_DEFAULT
, &mhooks
,
482 debug_level
? assuan_log_cb
: NULL
, NULL
);
486 rc
= assuan_init_socket_server(cl
->ctx
, cl
->thd
->fd
, 2);
490 assuan_set_pointer(cl
->ctx
, cl
);
491 assuan_set_hello_line(cl
->ctx
, PACKAGE_STRING
);
492 rc
= register_commands(cl
->ctx
);
496 rc
= assuan_accept(cl
->ctx
);
500 rc
= validate_peer(cl
);
501 /* May not be implemented on all platforms. */
502 if (rc
&& gpg_err_code(rc
) != GPG_ERR_ASS_GENERAL
)
505 rc
= init_client_crypto(&cl
->crypto
);
509 if (pipe(cl
->thd
->status_msg_pipe
) == -1) {
510 cl
->thd
->status_msg_pipe
[0] = -1;
511 cl
->thd
->status_msg_pipe
[1] = -1;
512 rc
= gpg_error_from_syserror();
516 cl
->crypto
->agent
->client_ctx
= cl
->ctx
;
517 fcntl(cl
->thd
->status_msg_pipe
[0], F_SETFL
, O_NONBLOCK
);
518 fcntl(cl
->thd
->status_msg_pipe
[1], F_SETFL
, O_NONBLOCK
);
519 pthread_mutex_init(&cl
->thd
->status_mutex
, NULL
);
520 cl
->crypto
->client_ctx
= cl
->ctx
;
521 xmlSetStructuredErrorFunc(cl
, xml_error_cb
);
525 log_write("%s", pwmd_strerror(rc
));
530 * This is called after a client_thread() terminates. Set with
531 * pthread_cleanup_push().
533 static void cleanup_cb(void *arg
)
535 struct client_thread_s
*cn
= arg
;
536 struct client_s
*cl
= cn
->cl
;
537 struct status_msg_s
*msg
;
539 MUTEX_LOCK(&cn_mutex
);
540 cn_thread_list
= g_slist_remove(cn_thread_list
, cn
);
541 MUTEX_UNLOCK(&cn_mutex
);
547 assuan_release(cl
->ctx
);
548 else if (cl
->thd
&& cl
->thd
->fd
!= -1)
552 cleanup_crypto(&cl
->crypto
);
561 for (msg
= cn
->msg_queue
; msg
; msg
= msg
->next
) {
566 if (cn
->status_msg_pipe
[0] != -1)
567 close(cn
->status_msg_pipe
[0]);
569 if (cn
->status_msg_pipe
[1] != -1)
570 close(cn
->status_msg_pipe
[1]);
572 pthread_mutex_destroy(&cn
->status_mutex
);
573 log_write(_("exiting, fd=%i"), cn
->fd
);
575 send_status_all(STATUS_CLIENTS
, NULL
);
576 pthread_cond_signal(&quit_cond
);
579 gpg_error_t
send_msg_queue(struct client_thread_s
*thd
)
581 MUTEX_LOCK(&thd
->status_mutex
);
585 read(thd
->status_msg_pipe
[0], &c
, 1);
587 while (thd
->msg_queue
) {
588 struct status_msg_s
*msg
= thd
->msg_queue
;
590 MUTEX_UNLOCK(&thd
->status_mutex
);
591 rc
= send_status(thd
->cl
->ctx
, msg
->s
, msg
->line
);
592 MUTEX_LOCK(&thd
->status_mutex
);
594 thd
->msg_queue
= thd
->msg_queue
->next
;
601 MUTEX_UNLOCK(&thd
->status_mutex
);
605 static void *client_thread(void *data
)
607 struct client_thread_s
*thd
= data
;
608 struct client_s
*cl
= g_malloc0(sizeof(struct client_s
));
610 #ifdef HAVE_PR_SET_NAME
611 prctl(PR_SET_NAME
, "client");
613 pthread_setspecific(thread_name_key
, g_strdup(__FUNCTION__
));
616 log_write("%s(%i): %s", __FILE__
, __LINE__
,
617 pwmd_strerror(GPG_ERR_ENOMEM
));
621 pthread_cleanup_push(cleanup_cb
, thd
);
625 if (new_connection(cl
)) {
626 gboolean finished
= FALSE
;
629 send_status_all(STATUS_CLIENTS
, NULL
);
630 rc
= send_status(cl
->ctx
, STATUS_CACHE
, NULL
);
632 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(rc
));
642 FD_SET(thd
->fd
, &rfds
);
643 FD_SET(thd
->status_msg_pipe
[0], &rfds
);
644 n
= thd
->fd
> thd
->status_msg_pipe
[0] ? thd
->fd
: thd
->status_msg_pipe
[0];
646 n
= select(n
+1, &rfds
, NULL
, NULL
, NULL
);
648 log_write("%s", strerror(errno
));
652 if (FD_ISSET(thd
->status_msg_pipe
[0], &rfds
)) {
653 rc
= send_msg_queue(thd
);
654 if (rc
&& gpg_err_code(rc
) != GPG_ERR_EPIPE
) {
655 log_write("%s(%i): %s", __FUNCTION__
, __LINE__
,
661 if (!FD_ISSET(thd
->fd
, &rfds
))
664 rc
= assuan_process_next(cl
->ctx
, &eof
);
666 if (gpg_err_code(rc
) == GPG_ERR_EOF
|| eof
)
669 log_write("assuan_process_next(): %s", pwmd_strerror(rc
));
670 rc
= send_error(cl
->ctx
, rc
);
673 log_write("assuan_process_done(): %s", pwmd_strerror(rc
));
678 /* Since the msg queue pipe fd's are non-blocking, check for
679 * pending status msgs here. GPG_ERR_EPIPE can be seen when the
680 * client has already disconnected and will be converted to
681 * GPG_ERR_EOF during assuan_process_next().
683 rc
= send_msg_queue(thd
);
684 if (rc
&& gpg_err_code(rc
) != GPG_ERR_EPIPE
) {
685 log_write("%s(%i): %s", __FUNCTION__
, __LINE__
,
692 pthread_cleanup_pop(1);
696 static gboolean
xml_import(const gchar
*filename
, const gchar
*outfile
,
697 const gchar
*keygrip
, const char *sign_keygrip
, const gchar
*keyfile
,
698 gboolean no_passphrase
, const gchar
*cipher
, const gchar
*params
,
708 struct crypto_s
*crypto
;
709 gint algo
= cipher
? cipher_string_to_gcrypt((gchar
*)cipher
) :
713 log_write("%s", pwmd_strerror(GPG_ERR_CIPHER_ALGO
));
717 if (stat(filename
, &st
) == -1) {
718 log_write("%s: %s", filename
, pwmd_strerror(gpg_error_from_syserror()));
722 rc
= init_client_crypto(&crypto
);
726 memcpy(&crypto
->save
.hdr
, &crypto
->hdr
, sizeof(file_header_t
));
727 crypto
->save
.hdr
.flags
= set_cipher_flag(crypto
->save
.hdr
.flags
, algo
);
728 log_write(_("Importing XML from '%s'. Output will be written to '%s' ..."),
731 if ((fd
= open(filename
, O_RDONLY
)) == -1) {
732 log_write("%s: %s", filename
, pwmd_strerror(gpg_error_from_syserror()));
736 if ((xmlbuf
= xmalloc(st
.st_size
+1)) == NULL
) {
738 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
742 if (read(fd
, xmlbuf
, st
.st_size
) == -1) {
743 rc
= gpg_error_from_syserror();
745 log_write("%s: %s", filename
, pwmd_strerror(rc
));
750 xmlbuf
[st
.st_size
] = 0;
752 * Make sure the document validates.
754 if ((doc
= xmlReadDoc(xmlbuf
, NULL
, "UTF-8", XML_PARSE_NOBLANKS
)) == NULL
) {
755 log_write("xmlReadDoc() failed");
761 xmlNodePtr n
= xmlDocGetRootElement(doc
);
762 if (strcmp((gchar
*)n
->name
, (gchar
*)"pwmd")) {
763 log_write(_("Could not find root \"pwmd\" element."));
764 rc
= GPG_ERR_BAD_DATA
;
768 rc
= validate_import(n
? n
->children
: n
);
771 log_write("%s", pwmd_strerror(rc
));
776 xmlDocDumpMemory(doc
, &xml
, &len
);
778 crypto
->save
.s2k_count
= (gulong
)s2k_count
;
779 rc
= set_pinentry_options(crypto
->agent
);
781 rc
= export_common(crypto
, keygrip
, sign_keygrip
, no_passphrase
, xml
,
782 len
, outfile
, params
, keyfile
);
786 send_error(NULL
, rc
);
790 cleanup_crypto(&crypto
);
794 cleanup_crypto(&crypto
);
798 gboolean
do_cache_push(const gchar
*filename
, struct crypto_s
*crypto
)
805 struct cache_data_s
*cdata
;
807 log_write(_("Trying to add datafile '%s' to the file cache ..."),
810 if (valid_filename(filename
) == FALSE
) {
811 log_write(_("%s: Invalid characters in filename"), filename
);
815 rc
= read_data_file(filename
, crypto
);
817 log_write("%s", pwmd_strerror(rc
));
821 if ((key
= get_key_file_string(filename
, "passphrase"))) {
822 log_write(_("Trying the passphrase specified in config ..."));
823 keylen
= strlen(key
);
825 else if ((key
= get_key_file_string(filename
, "passphrase_file"))) {
826 gint fd
= open((gchar
*)key
, O_RDONLY
);
829 log_write(_("Trying the passphrase using file '%s' ..."), key
);
831 log_write("%s: %s", key
, pwmd_strerror(gpg_error_from_syserror()));
836 stat((gchar
*)key
, &st
);
838 key
= g_malloc(st
.st_size
);
839 if (read(fd
, key
, st
.st_size
) != st
.st_size
) {
840 log_write("short read() count");
850 rc
= set_agent_passphrase(crypto
, key
, keylen
);
853 log_write("%s", pwmd_strerror(rc
));
858 crypto
->filename
= g_strdup(filename
);
859 rc
= decrypt_data(crypto
);
861 log_write("%s", pwmd_strerror(rc
));
865 doc
= parse_doc((gchar
*)crypto
->plaintext
, crypto
->plaintext_len
);
867 log_write("%s", pwmd_strerror(GPG_ERR_ENOMEM
));
871 gcry_md_hash_buffer(GCRY_MD_MD5
, md5file
, filename
, strlen(filename
));
872 cdata
= g_malloc0(sizeof(struct cache_data_s
));
875 log_write("%s", pwmd_strerror(GPG_ERR_ENOMEM
));
880 gcry_sexp_build((gcry_sexp_t
*)&cdata
->pubkey
, NULL
, "%S", crypto
->pkey_sexp
);
881 gcry_sexp_build((gcry_sexp_t
*)&cdata
->sigkey
, NULL
, "%S", crypto
->sigpkey_sexp
);
882 cdata
->ctime
= crypto
->st
.st_ctime
;
883 gint timeout
= get_key_file_integer(filename
, "cache_timeout");
884 cache_add_file(md5file
, crypto
->grip
, cdata
, timeout
);
885 log_write(_("Successfully added '%s' to the cache."), filename
);
889 static void *accept_thread(void *arg
)
891 gint sockfd
= *(gint
*)arg
;
893 #ifdef HAVE_PR_SET_NAME
894 prctl(PR_SET_NAME
, "accept");
896 pthread_setspecific(thread_name_key
, g_strdup(__FUNCTION__
));
899 socklen_t slen
= sizeof(struct sockaddr_un
);
900 struct sockaddr_un raddr
;
902 struct client_thread_s
*new;
905 fd
= accept(sockfd
, (struct sockaddr
*)&raddr
, &slen
);
907 if (errno
!= EAGAIN
) {
908 if (!quit
) // probably EBADF
909 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
916 new = g_malloc0(sizeof(struct client_thread_s
));
918 log_write("%s(%i): %s", __FILE__
, __LINE__
,
919 pwmd_strerror(GPG_ERR_ENOMEM
));
924 MUTEX_LOCK(&cn_mutex
);
925 pthread_cleanup_push(cleanup_mutex_cb
, &cn_mutex
);
927 rc
= create_thread(client_thread
, new, &new->tid
, TRUE
);
929 cn_thread_list
= g_slist_append(cn_thread_list
, new);
930 log_write(_("new connection: tid=%p, fd=%i"), (pthread_t
*)new->tid
, fd
);
933 pthread_cleanup_pop(1);
937 log_write("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
942 /* Just in case accept() failed for some reason other than EBADF */
947 static void *cache_timer_thread(void *arg
)
949 #ifdef HAVE_PR_SET_NAME
950 prctl(PR_SET_NAME
, "cache timer");
952 pthread_setspecific(thread_name_key
, g_strdup(__FUNCTION__
));
956 cache_adjust_timeout();
962 static void catch_sigabrt(int sig
)
970 static gboolean
signal_loop(sigset_t sigset
)
972 gboolean done
= FALSE
;
973 gboolean sigint
= FALSE
;
976 gint sig
= sigwaitinfo(&sigset
, NULL
);
980 log_write("sigwaitinfo(): %s", strerror(errno
));
985 log_write(_("caught signal %i (%s)"), sig
, strsignal(sig
));
989 pthread_cond_signal(&rcfile_cond
);
992 // not really handled here.
993 catch_sigabrt(SIGABRT
);
996 log_write(_("clearing file cache"));
998 send_status_all(STATUS_CACHE
, NULL
);
1013 static void catchsig(int sig
)
1015 log_write("Caught SIGSEGV. Exiting.");
1016 #ifdef HAVE_BACKTRACE
1017 BACKTRACE(__FUNCTION__
);
1022 static void *waiting_for_exit(void *arg
)
1024 #ifdef HAVE_PR_SET_NAME
1025 prctl(PR_SET_NAME
, "exiting");
1027 pthread_setspecific(thread_name_key
, g_strdup(__FUNCTION__
));
1028 log_write(_("waiting for all clients to disconnect"));
1029 MUTEX_LOCK(&quit_mutex
);
1030 pthread_cleanup_push(cleanup_mutex_cb
, &quit_mutex
);
1033 MUTEX_LOCK(&cn_mutex
);
1034 gint n
= g_slist_length(cn_thread_list
);
1035 MUTEX_UNLOCK(&cn_mutex
);
1039 log_write(_("%i clients remain"), n
);
1040 pthread_cond_wait(&quit_cond
, &quit_mutex
);
1043 pthread_cleanup_pop(1);
1044 kill(getpid(), SIGUSR2
);
1048 static gboolean
server_loop(gint sockfd
, gchar
**socketpath
)
1050 pthread_t accept_tid
;
1051 pthread_t cache_timeout_tid
;
1054 gboolean segv
= FALSE
;
1058 sigemptyset(&sigset
);
1061 sigaddset(&sigset
, SIGTERM
);
1062 sigaddset(&sigset
, SIGINT
);
1064 /* Clears the file cache. */
1065 sigaddset(&sigset
, SIGUSR1
);
1067 /* Configuration file reloading. */
1068 sigaddset(&sigset
, SIGHUP
);
1070 /* For exiting cleanly. */
1071 sigaddset(&sigset
, SIGUSR2
);
1073 /* Clears the cache and exits when something bad happens. */
1074 signal(SIGABRT
, catch_sigabrt
);
1075 sigaddset(&sigset
, SIGABRT
);
1076 sigprocmask(SIG_BLOCK
, &sigset
, NULL
);
1078 /* Ignored everywhere. When a client disconnects abnormally this signal
1079 * gets raised. It isn't needed though because client_thread() will check
1080 * for rcs even after the client disconnects. */
1081 signal(SIGPIPE
, SIG_IGN
);
1083 /* Can show a backtrace of the stack in the log. */
1084 signal(SIGSEGV
, catchsig
);
1086 pthread_mutex_init(&quit_mutex
, NULL
);
1087 pthread_cond_init(&quit_cond
, NULL
);
1088 log_write(_("%s started for user %s"), PACKAGE_STRING
, g_get_user_name());
1089 log_write(_("Listening on %s"), *socketpath
);
1090 #ifndef HAVE_SO_PEERCRED
1091 log_write(_("Peer credential checking is NOT supported on this OS."));
1094 rc
= create_thread(reload_rcfile_thread
, NULL
, &rcfile_tid
, TRUE
);
1096 log_write("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1101 rc
= create_thread(cache_timer_thread
, NULL
, &cache_timeout_tid
, TRUE
);
1103 log_write("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1108 rc
= create_thread(accept_thread
, &sockfd
, &accept_tid
, TRUE
);
1110 log_write("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1115 sigdelset(&sigset
, SIGUSR2
);
1117 signal_loop(sigset
);
1123 * We're out of the main server loop. This happens when a signal was sent
1124 * to terminate the daemon. We'll wait for all clients to disconnect
1125 * before exiting but exit immediately if another termination signal is
1128 pthread_cancel(accept_tid
);
1129 shutdown(sockfd
, SHUT_RDWR
);
1131 unlink(*socketpath
);
1132 g_free(*socketpath
);
1134 MUTEX_LOCK(&cn_mutex
);
1135 n
= g_slist_length(cn_thread_list
);
1136 MUTEX_UNLOCK(&cn_mutex
);
1141 rc
= create_thread(waiting_for_exit
, NULL
, &tid
, TRUE
);
1143 sigaddset(&sigset
, SIGUSR2
);
1144 if (signal_loop(sigset
)) {
1145 log_write(_("Received second termination request. Exiting."));
1146 pthread_cancel(tid
);
1150 log_write("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1154 pthread_cancel(cache_timeout_tid
);
1157 pthread_cancel(rcfile_tid
);
1158 pthread_cond_destroy(&rcfile_cond
);
1159 pthread_mutex_destroy(&rcfile_mutex
);
1160 pthread_cond_destroy(&quit_cond
);
1161 pthread_mutex_destroy(&quit_mutex
);
1162 return segv
? EXIT_FAILURE
: EXIT_SUCCESS
;;
1165 static void startup_failure()
1167 log_write(_("Failed to add a file to the cache. Use --ignore to force startup. Exiting."));
1171 /* This is called from cache.c:clear_once(). See
1172 * command.c:clearcache_command() for details about lock checking.
1174 static gpg_error_t
free_cache_data(file_cache_t
*cache
)
1176 gpg_error_t rc
= GPG_ERR_NO_DATA
;
1178 struct client_thread_s
*found
= NULL
;
1179 gboolean self
= FALSE
;
1184 MUTEX_LOCK(&cn_mutex
);
1185 pthread_cleanup_push(cleanup_mutex_cb
, &cn_mutex
);
1186 t
= g_slist_length(cn_thread_list
);
1188 for (i
= 0; i
< t
; i
++) {
1189 struct client_thread_s
*thd
= g_slist_nth_data(cn_thread_list
, i
);
1191 if (!memcmp(thd
->cl
->md5file
, cache
->filename
,
1192 sizeof(cache
->filename
))) {
1193 if (pthread_equal(pthread_self(), thd
->tid
)) {
1199 /* Continue trying to find a client who has the same file open and
1200 * also has a lock. */
1201 rc
= cache_lock_mutex(thd
->cl
->ctx
, thd
->cl
->md5file
, TRUE
,
1212 rc
= cache_lock_mutex(found
->cl
->ctx
, found
->cl
->md5file
, TRUE
,
1215 if (!rc
|| rc
== GPG_ERR_NO_DATA
) {
1217 if (cache
->data
->doc
)
1218 xmlFreeDoc(cache
->data
->doc
);
1219 if (cache
->data
->pubkey
)
1220 gcry_sexp_release(cache
->data
->pubkey
);
1221 g_free(cache
->data
);
1226 cache_unlock_mutex(found
->cl
->md5file
, FALSE
);
1231 pthread_cleanup_pop(1);
1235 static gboolean
convert_v2_datafile(const gchar
*filename
, const gchar
*cipher
,
1236 const gchar
*keyfile
, const gchar
*keygrip
, const gchar
*sign_keygrip
,
1237 gboolean nopass
, const gchar
*outfile
, const gchar
*keyparam
,
1241 gpointer data
= NULL
;
1243 struct crypto_s
*crypto
= NULL
;
1247 if (outfile
[0] == '-' && outfile
[1] == 0)
1250 log_write(_("Converting version 2 data file \"%s\" ..."), filename
);
1251 if (access(filename
, R_OK
) == -1) {
1252 log_write("%s: %s", filename
, pwmd_strerror(gpg_error_from_syserror()));
1257 log_write(_("Using passphrase file \"%s\" for decryption ..."),
1259 if (access(keyfile
, R_OK
) == -1) {
1260 log_write("%s: %s", keyfile
,
1261 pwmd_strerror(gpg_error_from_syserror()));
1266 rc
= read_v2_datafile(filename
, keyfile
, &data
, &datalen
, &ver
, &algo
);
1268 log_write("%s", pwmd_strerror(rc
));
1273 algo
= cipher_string_to_gcrypt(cipher
);
1275 rc
= GPG_ERR_CIPHER_ALGO
;
1281 xmlDocPtr doc
= parse_doc(data
, datalen
);
1284 rc
= GPG_ERR_BAD_DATA
;
1288 rc
= convert_pre_212_elements(doc
);
1292 xmlDocDumpFormatMemory(doc
, (xmlChar
**)&data
, (gint
*)&datalen
, 0);
1294 rc
= GPG_ERR_ENOMEM
;
1302 rc
= init_client_crypto(&crypto
);
1304 rc
= set_pinentry_options(crypto
->agent
);
1306 memcpy(&crypto
->save
.hdr
, &crypto
->hdr
,
1307 sizeof(file_header_t
));
1308 crypto
->save
.hdr
.flags
= set_cipher_flag(crypto
->save
.hdr
.flags
, algo
);
1309 crypto
->save
.s2k_count
= (gulong
)s2k_count
;
1310 rc
= export_common(crypto
, keygrip
, sign_keygrip
, nopass
, data
,
1311 datalen
, outfile
, keyparam
,
1312 no_passphrase_file
? NULL
: keyfile
);
1314 log_write(_("Output written to \"%s\"."), outfile
);
1323 cleanup_crypto(&crypto
);
1326 log_write("%s", pwmd_strerror(rc
));
1327 return rc
? FALSE
: TRUE
;
1330 int main(int argc
, char *argv
[])
1333 struct sockaddr_un addr
;
1334 gchar buf
[PATH_MAX
];
1335 gchar
*socketpath
= NULL
, *socketdir
, *socketname
= NULL
;
1336 gchar
*socketarg
= NULL
;
1337 gchar
*datadir
= NULL
;
1341 gchar
**cache_push
= NULL
;
1342 gchar
*import
= NULL
, *keygrip
= NULL
, *sign_keygrip
= NULL
;
1343 gchar
*keyparam
= NULL
;
1344 gboolean rcfile_spec
= FALSE
;
1345 gint estatus
= EXIT_FAILURE
;
1347 gchar
*outfile
= NULL
;
1348 GMemVTable mtable
= { xmalloc
, xrealloc
, xfree
, xcalloc
, NULL
, NULL
};
1350 gboolean secure
= FALSE
;
1351 gint show_version
= 0;
1352 gboolean force
= FALSE
;
1353 gboolean no_passphrase
= FALSE
;
1355 gchar
*convertfile
= NULL
;
1356 gchar
*cipher
= NULL
;
1357 gchar
*keyfile
= NULL
;
1358 glong s2k_count
= -1;
1359 GError
*error
= NULL
;
1360 gchar
*debug_level_opt
= NULL
;
1361 GOptionContext
*context
;
1362 GOptionEntry options
[] =
1364 { "version", 0, 0, G_OPTION_ARG_NONE
, &show_version
,
1365 "version information", NULL
},
1366 { "no-fork", 'n', 0, G_OPTION_ARG_NONE
, &nofork
,
1367 "run as a foreground process", NULL
},
1368 { "disable-dump", 'D', 0, G_OPTION_ARG_NONE
, &secure
,
1369 "disable the LIST, XPATH and DUMP commands", NULL
},
1370 { "rcfile", 'f', 0, G_OPTION_ARG_FILENAME
, &rcfile
,
1371 "load the specified rcfile (~/.pwmd/config)", "filename" },
1372 { "ignore", 0, 0, G_OPTION_ARG_NONE
, &force
,
1373 "ignore cache failures on startup", NULL
},
1374 { "outfile", 'o', 0, G_OPTION_ARG_FILENAME
, &outfile
,
1375 "output file when importing (- for stdout)", "filename" },
1376 { "convert", 'C', 0, G_OPTION_ARG_FILENAME
, &convertfile
,
1377 "convert a version 2 data file to version 3", "filename" },
1378 { "passphrase-file", 'k', 0, G_OPTION_ARG_FILENAME
, &keyfile
,
1379 "for decryption when converting", "filename" },
1380 { "no-passphrase-file", 0, 0, G_OPTION_ARG_NONE
, &no_passphrase_file
,
1381 "no --passphrase-file after conversion", NULL
},
1382 { "import", 'I', 0, G_OPTION_ARG_FILENAME
, &import
,
1383 "import an XML file", "filename" },
1384 { "keygrip", 0, 0, G_OPTION_ARG_STRING
, &keygrip
,
1385 "the public keygrip to use for encryption", "hexstring"},
1386 { "sign-keygrip", 0, 0, G_OPTION_ARG_STRING
, &sign_keygrip
,
1387 "the keygrip to use for signing of the data", "hexstring"},
1388 { "keyparam", 0, 0, G_OPTION_ARG_STRING
, &keyparam
,
1389 "alternate key parameters to use (RSA-2048)", "s-exp"},
1390 { "no-passphrase", 0, 0, G_OPTION_ARG_NONE
, &no_passphrase
,
1391 "for the imported/converted keypair", NULL
},
1392 { "cipher", 0, 0, G_OPTION_ARG_STRING
, &cipher
,
1393 "encryption cipher, see man page (AES-256)", "string" },
1394 { "s2k-count", 0, 0, G_OPTION_ARG_INT64
, &s2k_count
,
1395 "hash iteration count >65536 (calibrated)", "iterations" },
1396 { "debug-level", 0, 0, G_OPTION_ARG_STRING
, &debug_level_opt
,
1397 "protocol output, see man page", "keywords"},
1402 #ifdef HAVE_SETRLIMIT
1405 rl
.rlim_cur
= rl
.rlim_max
= 0;
1407 if (setrlimit(RLIMIT_CORE
, &rl
) != 0)
1408 err(EXIT_FAILURE
, "setrlimit()");
1413 setlocale(LC_ALL
, "");
1414 bindtextdomain("pwmd", LOCALEDIR
);
1421 g_mem_set_vtable(&mtable
);
1422 g_thread_init(NULL
);
1425 xmlMemSetup(g_free
, g_malloc
, g_realloc
, g_strdup
);
1430 g_snprintf(buf
, sizeof(buf
), "%s/.pwmd", g_get_home_dir());
1431 if (mkdir(buf
, 0700) == -1 && errno
!= EEXIST
)
1432 err(EXIT_FAILURE
, "%s", buf
);
1434 g_snprintf(buf
, sizeof(buf
), "%s/.pwmd/data", g_get_home_dir());
1435 if (mkdir(buf
, 0700) == -1 && errno
!= EEXIST
)
1436 err(EXIT_FAILURE
, "%s", buf
);
1439 context
= g_option_context_new("- Password Manager Daemon");
1440 g_option_context_add_main_entries(context
, options
, NULL
);
1441 if (!g_option_context_parse(context
, &argc
, &argv
, &error
))
1443 g_print("Option parsing failed: %s\n", error
->message
);
1449 "Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011\n"
1451 "Released under the terms of the GPL v2. Use at your own risk.\n\n"
1452 "Compile time features:\n%s"), PACKAGE_STRING
, PACKAGE_BUGREPORT
,
1477 pthread_mutexattr_t attr
;
1478 pthread_mutexattr_init(&attr
);
1479 pthread_mutexattr_settype(&attr
, PTHREAD_MUTEX_RECURSIVE
);
1480 pthread_mutex_init(&rcfile_mutex
, &attr
);
1481 pthread_mutex_init(&cn_mutex
, &attr
);
1482 pthread_mutexattr_destroy(&attr
);
1485 rcfile
= g_strdup_printf("%s/.pwmd/config", g_get_home_dir());
1489 if ((keyfileh
= parse_rcfile(rcfile_spec
, cmdline
)) == NULL
)
1492 if (debug_level_opt
)
1493 debug_level
= g_strsplit(debug_level_opt
, ",", 0);
1495 if (g_key_file_has_key(keyfileh
, "global", "syslog", NULL
) == TRUE
)
1496 log_syslog
= g_key_file_get_boolean(keyfileh
, "global", "syslog", NULL
);
1498 if (log_syslog
== TRUE
)
1499 openlog("pwmd", LOG_NDELAY
|LOG_PID
, LOG_DAEMON
);
1501 if (g_key_file_has_key(keyfileh
, "global", "priority", NULL
)) {
1502 x
= g_key_file_get_integer(keyfileh
, "global", "priority", NULL
);
1505 if (setpriority(PRIO_PROCESS
, 0, x
) == -1) {
1506 log_write("setpriority(): %s", pwmd_strerror(gpg_error_from_syserror()));
1511 #ifdef HAVE_MLOCKALL
1512 if (disable_mlock
== FALSE
&& mlockall(MCL_CURRENT
|MCL_FUTURE
) == -1) {
1513 log_write("mlockall(): %s", pwmd_strerror(gpg_error_from_syserror()));
1518 rc
= cache_init(free_cache_data
);
1520 log_write("pwmd: gpg-agent: %s",
1521 gpg_err_code(rc
) == GPG_ERR_UNKNOWN_VERSION
1522 ? _("incompatible version: 2.1.0 or later required")
1523 : pwmd_strerror(rc
));
1527 if (s2k_count
== -1)
1528 s2k_count
= get_key_file_ulong(NULL
, "s2k_count");
1532 gchar
*tmp
= g_option_context_get_help(context
, TRUE
, NULL
);
1533 fprintf(stderr
, "%s", tmp
);
1538 estatus
= convert_v2_datafile(convertfile
, cipher
, keyfile
, keygrip
,
1539 sign_keygrip
, no_passphrase
, outfile
, keyparam
,
1541 g_key_file_free(keyfileh
);
1548 gchar
*tmp
= g_option_context_get_help(context
, TRUE
, NULL
);
1549 fprintf(stderr
, "%s", tmp
);
1554 if (outfile
[0] == '-' && outfile
[1] == 0)
1557 estatus
= xml_import(import
, outfile
, keygrip
, sign_keygrip
, keyfile
,
1558 no_passphrase
, cipher
, keyparam
, (gulong
)s2k_count
);
1559 g_key_file_free(keyfileh
);
1564 g_option_context_free(context
);
1565 if ((p
= g_key_file_get_string(keyfileh
, "global", "socket_path", NULL
)) == NULL
)
1566 errx(EXIT_FAILURE
, _("%s: socket_path not defined"), rcfile
);
1568 socketarg
= expand_homedir(p
);
1571 if ((p
= g_key_file_get_string(keyfileh
, "global", "data_directory", NULL
)) == NULL
)
1572 errx(EXIT_FAILURE
, _("%s: data_directory not defined"), rcfile
);
1574 datadir
= expand_homedir(p
);
1577 if (secure
== FALSE
&& g_key_file_has_key(keyfileh
, "global", "disable_list_and_dump", NULL
) == TRUE
) {
1578 n
= g_key_file_get_boolean(keyfileh
, "global", "disable_list_and_dump", NULL
);
1579 disable_list_and_dump
= n
;
1582 disable_list_and_dump
= secure
;
1584 setup_logging(keyfileh
);
1586 if (g_key_file_has_key(keyfileh
, "global", "cache_push", NULL
) == TRUE
)
1587 cache_push
= g_key_file_get_string_list(keyfileh
, "global", "cache_push", NULL
, NULL
);
1589 for (gint n
= 1; n
< argc
; n
++) {
1590 if (strv_printf(&cache_push
, "%s", argv
[n
]) == FALSE
)
1591 errx(EXIT_FAILURE
, "%s", pwmd_strerror(GPG_ERR_ENOMEM
));
1594 if (strchr(socketarg
, '/') == NULL
) {
1595 socketdir
= g_get_current_dir();
1596 socketname
= g_strdup(socketarg
);
1597 socketpath
= g_strdup_printf("%s/%s", socketdir
, socketname
);
1600 socketname
= g_strdup(strrchr(socketarg
, '/'));
1602 socketarg
[strlen(socketarg
) - strlen(socketname
) -1] = 0;
1603 socketdir
= g_strdup(socketarg
);
1604 socketpath
= g_strdup_printf("%s/%s", socketdir
, socketname
);
1607 if (chdir(datadir
)) {
1608 log_write("%s: %s", datadir
, pwmd_strerror(gpg_error_from_syserror()));
1614 * Set the cache entry for a file. Prompts for the password.
1617 struct crypto_s
*crypto
;
1618 gpg_error_t rc
= init_client_crypto(&crypto
);
1621 estatus
= EXIT_FAILURE
;
1625 rc
= set_pinentry_options(crypto
->agent
);
1627 estatus
= EXIT_FAILURE
;
1631 for (opt
= 0; cache_push
[opt
]; opt
++) {
1632 if (!do_cache_push(cache_push
[opt
], crypto
) && !force
) {
1633 g_strfreev(cache_push
);
1635 estatus
= EXIT_FAILURE
;
1636 cleanup_crypto(&crypto
);
1640 cleanup_crypto_stage1(crypto
);
1643 (void)kill_scd(crypto
->agent
);
1644 cleanup_crypto(&crypto
);
1645 g_strfreev(cache_push
);
1646 log_write(!nofork
? _("Done. Daemonizing...") : _("Done. Waiting for connections..."));
1649 clear_rcfile_keys();
1652 * bind() doesn't like the full pathname of the socket or any non alphanum
1653 * characters so change to the directory where the socket is wanted then
1654 * create it then change to datadir.
1656 if (chdir(socketdir
)) {
1657 log_write("%s: %s", socketdir
, pwmd_strerror(gpg_error_from_syserror()));
1663 if ((sockfd
= socket(PF_UNIX
, SOCK_STREAM
, 0)) == -1) {
1664 log_write("socket(): %s", pwmd_strerror(gpg_error_from_syserror()));
1668 addr
.sun_family
= AF_UNIX
;
1669 g_snprintf(addr
.sun_path
, sizeof(addr
.sun_path
), "%s", socketname
);
1671 if (bind(sockfd
, (struct sockaddr
*)&addr
, sizeof(struct sockaddr
)) == -1) {
1672 log_write("bind(): %s", pwmd_strerror(gpg_error_from_syserror()));
1674 if (errno
== EADDRINUSE
)
1675 log_write(_("Either there is another pwmd running or '%s' is a \n"
1676 "stale socket. Please remove it manually."), socketpath
);
1682 if (g_key_file_has_key(keyfileh
, "global", "socket_perms", NULL
) == TRUE
) {
1683 gchar
*t
= g_key_file_get_string(keyfileh
, "global", "socket_perms", NULL
);
1684 mode_t mode
= strtol(t
, NULL
, 8);
1685 mode_t mask
= umask(0);
1689 if (chmod(socketname
, mode
) == -1) {
1690 log_write("%s: %s", socketname
, pwmd_strerror(gpg_error_from_syserror()));
1700 g_free(--socketname
);
1702 if (chdir(datadir
)) {
1703 log_write("%s: %s", datadir
, pwmd_strerror(gpg_error_from_syserror()));
1711 if (listen(sockfd
, 0) == -1) {
1712 log_write("listen(): %s", pwmd_strerror(gpg_error_from_syserror()));
1721 log_write("fork(): %s", pwmd_strerror(gpg_error_from_syserror()));
1730 _exit(EXIT_SUCCESS
);
1734 pthread_key_create(&thread_name_key
, free_key
);
1735 pthread_setspecific(thread_name_key
, g_strdup("main"));
1736 pthread_cond_init(&rcfile_cond
, NULL
);
1737 pthread_key_create(&last_error_key
, free_key
);
1738 estatus
= server_loop(sockfd
, &socketpath
);
1741 if (socketpath
&& do_unlink
) {
1748 g_key_file_free(keyfileh
);
1751 xmlCleanupGlobals();
1753 if (estatus
== EXIT_SUCCESS
)
1754 log_write(_("pwmd exiting normally"));
1756 #if defined(DEBUG) && !defined(MEM_DEBUG)