2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of pwmd.
7 Pwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Pwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Pwmd. If not, see <http://www.gnu.org/licenses/>.
30 #include <sys/socket.h>
44 #include <netinet/in.h>
45 #include <arpa/inet.h>
48 #include <sys/resource.h>
61 #ifdef HAVE_GETOPT_LONG
66 #include "getopt_long.h"
69 #ifdef HAVE_PR_SET_NAME
70 #include <sys/prctl.h>
73 #include "pwmd-error.h"
81 #include "util-misc.h"
82 #include "util-string.h"
93 static pthread_cond_t quit_cond
;
94 static pthread_mutex_t quit_mutex
;
95 static int no_passphrase_file
= 0;
99 static pthread_t tls_tid
;
100 static pthread_t tls6_tid
;
102 static int start_stop_tls(int term
);
105 static int do_cache_push(const char *filename
, struct crypto_s
*crypto
);
106 static int signal_loop(sigset_t sigset
);
108 GCRY_THREAD_OPTION_PTHREAD_IMPL
;
110 static void cache_push_from_rcfile()
112 struct crypto_s
*crypto
;
114 gpg_error_t rc
= init_client_crypto(&crypto
);
117 log_write("%s: %s", __FUNCTION__
, pwmd_strerror(rc
));
121 rc
= set_agent_option(crypto
->agent
, "pinentry-mode", "error");
123 log_write("%s: %s", __FUNCTION__
, pwmd_strerror(rc
));
127 cache_push
= config_get_list("global", "cache_push");
131 for (p
= cache_push
; *p
; p
++) {
132 (void)do_cache_push(*p
, crypto
);
133 cleanup_crypto_stage1(crypto
);
136 strv_free(cache_push
);
139 (void)kill_scd(crypto
->agent
);
140 cleanup_crypto(&crypto
);
143 static void setup_logging()
145 int n
= config_get_boolean("global", "enable_logging");
148 char *p
= config_get_string("global", "log_path");
151 logfile
= expand_homedir(p
);
159 log_syslog
= config_get_boolean("global", "syslog");
161 openlog("pwmd", LOG_NDELAY
|LOG_PID
, LOG_DAEMON
);
164 static void *reload_rcfile_thread(void *arg
)
166 #ifdef HAVE_PR_SET_NAME
167 prctl(PR_SET_NAME
, "reload rcfile");
169 pthread_setspecific(thread_name_key
, str_dup(__FUNCTION__
));
170 MUTEX_LOCK(&rcfile_mutex
);
171 pthread_cleanup_push(cleanup_mutex_cb
, &rcfile_mutex
);
175 struct slist_s
*config
;
177 int b
= disable_list_and_dump
;
179 int tcp_require_key
= config_get_bool_param(global_config
, "global",
180 "tcp_require_key", &exists
);
183 pthread_cond_wait(&rcfile_cond
, &rcfile_mutex
);
184 users
= config_get_list("global", "allowed");
185 log_write(_("reloading configuration file '%s'"), rcfile
);
186 config
= config_parse(rcfile
);
188 config_free(global_config
);
189 global_config
= config
;
191 cache_push_from_rcfile();
192 config_clear_keyss();
195 disable_list_and_dump
= !disable_list_and_dump
? b
: 1;
197 if (config_get_bool_param(global_config
, "global", "tcp_require_key",
201 config_set_bool_param(&global_config
, "global", "tcp_require_key",
202 tcp_require_key
? "true" : "false");
204 char *tmp
= strv_join(",", users
);
205 config_set_list_param(&global_config
, "global", "allowed", tmp
);
209 /* Kill existing listening threads since the configured listening
210 * protocols may have changed. */
216 pthread_cleanup_pop(1);
220 gpg_error_t
send_error(assuan_context_t ctx
, gpg_error_t e
)
222 struct client_s
*client
= assuan_get_pointer(ctx
);
224 if (gpg_err_source(e
) == GPG_ERR_SOURCE_UNKNOWN
)
231 return assuan_process_done(ctx
, 0);
234 log_write("%s", pwmd_strerror(e
));
238 if (gpg_err_code(e
) == GPG_ERR_BAD_DATA
) {
239 xmlErrorPtr xe
= client
->xml_error
;
242 xe
= xmlGetLastError();
244 log_write("%s", xe
->message
);
245 if (client
->last_error
)
246 xfree(client
->last_error
);
248 client
->last_error
= str_dup(xe
->message
);
251 e
= assuan_process_done(ctx
, assuan_set_error(ctx
, e
,
252 xe
? xe
->message
: NULL
));
254 if (xe
== client
->xml_error
)
259 client
->xml_error
= NULL
;
263 return assuan_process_done(ctx
, assuan_set_error(ctx
, e
, pwmd_strerror(e
)));
266 int assuan_log_cb(assuan_context_t ctx
, void *data
, unsigned cat
,
269 static pthread_mutex_t m
= PTHREAD_MUTEX_INITIALIZER
;
273 pthread_mutex_lock(&m
);
274 pthread_cleanup_push((void (*)(void *))pthread_mutex_unlock
, &m
);
275 t
= strv_length(debug_level
);
277 for (i
= 0; i
< t
; i
++) {
278 if (!strcasecmp(debug_level
[i
], (char *)"init")
279 && cat
== ASSUAN_LOG_INIT
) {
284 if (!strcasecmp(debug_level
[i
], (char *)"ctx")
285 && cat
== ASSUAN_LOG_CTX
) {
290 if (!strcasecmp(debug_level
[i
], (char *)"engine")
291 && cat
== ASSUAN_LOG_ENGINE
) {
296 if (!strcasecmp(debug_level
[i
], (char *)"data")
297 && cat
== ASSUAN_LOG_DATA
) {
302 if (!strcasecmp(debug_level
[i
], (char *)"sysio")
303 && cat
== ASSUAN_LOG_SYSIO
) {
308 if (!strcasecmp(debug_level
[i
], (char *)"control")
309 && cat
== ASSUAN_LOG_CONTROL
) {
319 if ((fd
= open(logfile
, O_WRONLY
|O_CREAT
|O_APPEND
, 0600)) == -1)
322 pthread_cleanup_push(cleanup_fd_cb
, &fd
);
323 write(fd
, msg
, strlen(msg
));
324 pthread_cleanup_pop(1);
329 fprintf(stderr
, "%s%s", data
? (char *)data
: "", msg
);
334 pthread_cleanup_pop(1);
338 void log_write(const char *fmt
, ...)
348 pthread_t tid
= pthread_self();
349 static pthread_mutex_t m
= PTHREAD_MUTEX_INITIALIZER
;
351 if ((!logfile
&& !isatty(STDERR_FILENO
) && !log_syslog
) || !fmt
)
354 pthread_mutex_lock(&m
);
355 pthread_cleanup_push((void (*)(void *))pthread_mutex_unlock
, &m
);
356 pthread_cleanup_push(cleanup_fd_cb
, &fd
);
358 if (!cmdline
&& logfile
) {
359 if ((fd
= open(logfile
, O_WRONLY
|O_CREAT
|O_APPEND
, 0600)) == -1)
365 if (str_vasprintf(&args
, fmt
, ap
) != -1) {
367 pthread_cleanup_push(xfree
, args
);
368 fprintf(stderr
, "%s\n", args
);
370 pthread_cleanup_pop(1);
373 pthread_cleanup_push(xfree
, args
);
374 name
= pthread_getspecific(thread_name_key
);
375 snprintf(buf
, sizeof(buf
), "%s(%p): ", name
? name
: _("unknown"),
379 if (!cmdline
&& log_syslog
&& !nofork
)
380 syslog(LOG_INFO
, "%s%s", name
, args
);
383 tm
= localtime(&now
);
384 strftime(tbuf
, sizeof(tbuf
), "%b %d %Y %H:%M:%S ", tm
);
385 tbuf
[sizeof(tbuf
) - 1] = 0;
387 if (args
[strlen(args
)-1] == '\n')
388 args
[strlen(args
)-1] = 0;
390 line
= str_asprintf("%s %i %s%s\n", tbuf
, getpid(), name
,
392 pthread_cleanup_pop(1);
394 pthread_cleanup_push(xfree
, line
);
395 if (logfile
&& fd
!= -1) {
396 write(fd
, line
, strlen(line
));
401 fprintf(stdout
, "%s", line
);
405 pthread_cleanup_pop(1);
411 pthread_cleanup_pop(1);
412 pthread_cleanup_pop(0);
413 pthread_mutex_unlock(&m
);
417 static int secure_mem_check(const void *arg
)
423 static gpg_error_t
setup_crypto()
425 gcry_control(GCRYCTL_SET_THREAD_CBS
, &gcry_threads_pthread
);
427 if (!gcry_check_version(GCRYPT_VERSION
)) {
428 fprintf(stderr
, _("gcry_check_version(): Incompatible libgcrypt. "
429 "Wanted %s, got %s.\n"), GCRYPT_VERSION
,
430 gcry_check_version(NULL
));
431 return GPG_ERR_UNKNOWN_VERSION
;
434 gcry_set_allocation_handler(xmalloc
, xmalloc
, NULL
, xrealloc
, xfree
);
438 static gpg_error_t
validate_peer(struct client_s
*cl
)
442 assuan_peercred_t peercred
;
450 rc
= assuan_get_peercred(cl
->ctx
, &peercred
);
454 users
= config_get_list("global", "allowed");
456 for (char **p
= users
; *p
; p
++) {
457 struct passwd pw
, *result
;
458 struct group gr
, *gresult
;
462 size_t len
= sysconf(_SC_GETGR_R_SIZE_MAX
);
471 return GPG_ERR_ENOMEM
;
474 if (!getgrnam_r(*(p
)+1, &gr
, buf
, len
, &gresult
) && gresult
) {
475 if (gresult
->gr_gid
== peercred
->gid
) {
481 len
= sysconf(_SC_GETPW_R_SIZE_MAX
);
486 char *tbuf
= xmalloc(len
);
488 for (char **t
= gresult
->gr_mem
; *t
; t
++) {
489 if (!getpwnam_r(*t
, &pw
, tbuf
, len
, &result
) && result
) {
490 if (result
->pw_uid
== peercred
->uid
) {
505 size_t len
= sysconf(_SC_GETPW_R_SIZE_MAX
);
514 return GPG_ERR_ENOMEM
;
517 if (!getpwnam_r(*p
, &pw
, buf
, len
, &result
) && result
) {
518 if (result
->pw_uid
== peercred
->uid
) {
532 log_write("peer %s: uid=%i, gid=%i, pid=%i",
533 allowed
? _("accepted") : _("rejected"), peercred
->uid
,
534 peercred
->gid
, peercred
->pid
);
535 return allowed
? 0 : GPG_ERR_INV_USER_ID
;
538 static void xml_error_cb(void *data
, xmlErrorPtr e
)
540 struct client_s
*client
= data
;
543 * Keep the first reported error as the one to show in the error
544 * description. Reset in send_error().
546 if (client
->xml_error
)
549 xmlCopyError(e
, client
->xml_error
);
552 static pid_t
hook_waitpid(assuan_context_t ctx
, pid_t pid
, int action
,
553 int *status
, int options
)
555 return waitpid(pid
, status
, options
);
558 static ssize_t
hook_read(assuan_context_t ctx
, assuan_fd_t fd
, void *data
,
562 struct client_s
*client
= assuan_get_pointer(ctx
);
564 if (client
->thd
->remote
)
565 return tls_read_hook(ctx
, (int)fd
, data
, len
);
568 return read((int)fd
, data
, len
);
571 static ssize_t
hook_write(assuan_context_t ctx
, assuan_fd_t fd
,
572 const void *data
, size_t len
)
575 struct client_s
*client
= assuan_get_pointer(ctx
);
577 if (client
->thd
->remote
)
578 return tls_write_hook(ctx
, (int)fd
, data
, len
);
581 return write((int)fd
, data
, len
);
584 static int new_connection(struct client_s
*cl
)
587 static struct assuan_malloc_hooks mhooks
= { xmalloc
, xrealloc
, xfree
};
588 static struct assuan_system_hooks shooks
= {
589 ASSUAN_SYSTEM_HOOKS_VERSION
,
597 NULL
, //sendmsg both are used for FD passing
606 if (cl
->thd
->remote
) {
607 char *prio
= config_get_string("global", "tls_cipher_suite");
609 cl
->thd
->tls
= tls_init(cl
->thd
->fd
, prio
);
616 rc
= assuan_new_ext(&cl
->ctx
, GPG_ERR_SOURCE_DEFAULT
, &mhooks
,
617 debug_level
? assuan_log_cb
: NULL
, NULL
);
621 assuan_ctx_set_system_hooks(cl
->ctx
, &shooks
);
622 rc
= assuan_init_socket_server(cl
->ctx
, cl
->thd
->fd
, 2);
626 assuan_set_pointer(cl
->ctx
, cl
);
627 assuan_set_hello_line(cl
->ctx
, PACKAGE_STRING
);
628 rc
= register_commands(cl
->ctx
);
632 rc
= assuan_accept(cl
->ctx
);
636 rc
= validate_peer(cl
);
637 /* May not be implemented on all platforms. */
638 if (rc
&& gpg_err_code(rc
) != GPG_ERR_ASS_GENERAL
)
641 rc
= init_client_crypto(&cl
->crypto
);
645 cl
->crypto
->agent
->client_ctx
= cl
->ctx
;
646 cl
->crypto
->client_ctx
= cl
->ctx
;
647 xmlSetStructuredErrorFunc(cl
, xml_error_cb
);
651 log_write("%s", pwmd_strerror(rc
));
656 * This is called after a client_thread() terminates. Set with
657 * pthread_cleanup_push().
659 static void cleanup_cb(void *arg
)
661 struct client_thread_s
*cn
= arg
;
662 struct client_s
*cl
= cn
->cl
;
664 MUTEX_LOCK(&cn_mutex
);
665 cn_thread_list
= slist_remove(cn_thread_list
, cn
);
666 MUTEX_UNLOCK(&cn_mutex
);
673 gnutls_deinit(cn
->tls
->ses
);
680 assuan_release(cl
->ctx
);
681 else if (cl
->thd
&& cl
->thd
->fd
!= -1)
685 cleanup_crypto(&cl
->crypto
);
694 while (cn
->msg_queue
) {
695 struct status_msg_s
*msg
= cn
->msg_queue
;
697 cn
->msg_queue
= msg
->next
;
702 if (cn
->status_msg_pipe
[0] != -1)
703 close(cn
->status_msg_pipe
[0]);
705 if (cn
->status_msg_pipe
[1] != -1)
706 close(cn
->status_msg_pipe
[1]);
708 pthread_mutex_destroy(&cn
->status_mutex
);
709 log_write(_("exiting, fd=%i"), cn
->fd
);
711 send_status_all(STATUS_CLIENTS
, NULL
);
712 pthread_cond_signal(&quit_cond
);
715 static gpg_error_t
send_msg_queue(struct client_thread_s
*thd
)
717 MUTEX_LOCK(&thd
->status_mutex
);
721 read(thd
->status_msg_pipe
[0], &c
, 1);
723 while (thd
->msg_queue
) {
724 struct status_msg_s
*msg
= thd
->msg_queue
;
726 thd
->msg_queue
= thd
->msg_queue
->next
;
727 MUTEX_UNLOCK(&thd
->status_mutex
);
728 rc
= send_status(thd
->cl
->ctx
, msg
->s
, msg
->line
);
729 MUTEX_LOCK(&thd
->status_mutex
);
737 MUTEX_UNLOCK(&thd
->status_mutex
);
741 static void *client_thread(void *data
)
743 struct client_thread_s
*thd
= data
;
744 struct client_s
*cl
= xcalloc(1, sizeof(struct client_s
));
746 #ifdef HAVE_PR_SET_NAME
747 prctl(PR_SET_NAME
, "client");
749 pthread_setspecific(thread_name_key
, str_dup(__FUNCTION__
));
752 log_write("%s(%i): %s", __FILE__
, __LINE__
,
753 pwmd_strerror(GPG_ERR_ENOMEM
));
757 MUTEX_LOCK(&cn_mutex
);
758 pthread_cleanup_push(cleanup_cb
, thd
);
761 MUTEX_UNLOCK(&cn_mutex
);
763 if (new_connection(cl
)) {
767 send_status_all(STATUS_CLIENTS
, NULL
);
768 rc
= send_status(cl
->ctx
, STATUS_CACHE
, NULL
);
770 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(rc
));
780 FD_SET(thd
->fd
, &rfds
);
781 FD_SET(thd
->status_msg_pipe
[0], &rfds
);
782 n
= thd
->fd
> thd
->status_msg_pipe
[0] ? thd
->fd
: thd
->status_msg_pipe
[0];
784 n
= select(n
+1, &rfds
, NULL
, NULL
, NULL
);
786 log_write("%s", strerror(errno
));
790 if (FD_ISSET(thd
->status_msg_pipe
[0], &rfds
)) {
791 rc
= send_msg_queue(thd
);
792 if (rc
&& gpg_err_code(rc
) != GPG_ERR_EPIPE
) {
793 log_write("%s(%i): %s", __FUNCTION__
, __LINE__
,
799 if (!FD_ISSET(thd
->fd
, &rfds
))
802 rc
= assuan_process_next(cl
->ctx
, &eof
);
804 if (gpg_err_code(rc
) == GPG_ERR_EOF
|| eof
)
807 log_write("assuan_process_next(): %s", pwmd_strerror(rc
));
808 rc
= send_error(cl
->ctx
, rc
);
811 log_write("assuan_process_done(): %s", pwmd_strerror(rc
));
816 /* Since the msg queue pipe fd's are non-blocking, check for
817 * pending status msgs here. GPG_ERR_EPIPE can be seen when the
818 * client has already disconnected and will be converted to
819 * GPG_ERR_EOF during assuan_process_next().
821 rc
= send_msg_queue(thd
);
822 if (rc
&& gpg_err_code(rc
) != GPG_ERR_EPIPE
) {
823 log_write("%s(%i): %s", __FUNCTION__
, __LINE__
,
830 pthread_cleanup_pop(1);
834 static int xml_import(const char *filename
, const char *outfile
,
835 const char *keygrip
, const char *sign_keygrip
, const char *keyfile
,
836 int no_passphrase
, const char *cipher
, const char *params
,
837 unsigned long s2k_count
, uint64_t iterations
)
846 struct crypto_s
*crypto
;
847 int algo
= cipher
? cipher_string_to_gcrypt((char *)cipher
) :
851 log_write("ERR %i: %s", gpg_error(GPG_ERR_CIPHER_ALGO
),
852 pwmd_strerror(GPG_ERR_CIPHER_ALGO
));
856 if (stat(filename
, &st
) == -1) {
857 log_write("%s: %s", filename
, pwmd_strerror(gpg_error_from_syserror()));
861 rc
= init_client_crypto(&crypto
);
865 memcpy(&crypto
->save
.hdr
, &crypto
->hdr
, sizeof(file_header_t
));
866 crypto
->save
.hdr
.flags
= set_cipher_flag(crypto
->save
.hdr
.flags
, algo
);
867 log_write(_("Importing XML from '%s'. Output will be written to '%s' ..."),
870 if ((fd
= open(filename
, O_RDONLY
)) == -1) {
871 log_write("%s: %s", filename
, pwmd_strerror(gpg_error_from_syserror()));
875 if ((xmlbuf
= xmalloc(st
.st_size
+1)) == NULL
) {
877 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
881 if (read(fd
, xmlbuf
, st
.st_size
) == -1) {
882 rc
= gpg_error_from_syserror();
884 log_write("%s: %s", filename
, pwmd_strerror(rc
));
889 xmlbuf
[st
.st_size
] = 0;
891 * Make sure the document validates.
893 if ((doc
= xmlReadDoc(xmlbuf
, NULL
, "UTF-8", XML_PARSE_NOBLANKS
)) == NULL
) {
894 log_write("xmlReadDoc() failed");
900 xmlNodePtr n
= xmlDocGetRootElement(doc
);
901 if (!xmlStrEqual(n
->name
, (xmlChar
*)"pwmd")) {
902 log_write(_("Could not find root \"pwmd\" element."));
903 rc
= GPG_ERR_BAD_DATA
;
907 rc
= validate_import(n
? n
->children
: n
);
910 log_write("ERR %i: %s", rc
, pwmd_strerror(rc
));
915 xmlDocDumpMemory(doc
, &xml
, &len
);
917 crypto
->save
.s2k_count
= s2k_count
;
918 crypto
->save
.hdr
.iterations
= iterations
;
919 rc
= set_pinentry_options(crypto
->agent
);
921 rc
= export_common(crypto
, keygrip
, sign_keygrip
, no_passphrase
, xml
,
922 len
, outfile
, params
, keyfile
);
926 send_error(NULL
, rc
);
930 cleanup_crypto(&crypto
);
934 cleanup_crypto(&crypto
);
938 static int do_cache_push(const char *filename
, struct crypto_s
*crypto
)
940 unsigned char md5file
[16];
945 struct cache_data_s
*cdata
;
949 log_write(_("Trying to add datafile '%s' to the file cache ..."),
952 if (valid_filename(filename
) == 0) {
953 log_write(_("%s: Invalid characters in filename"), filename
);
957 rc
= read_data_file(filename
, crypto
);
959 log_write("ERR %i: %s", rc
, pwmd_strerror(rc
));
963 if ((key
= config_get_string(filename
, "passphrase"))) {
964 log_write(_("Trying the passphrase specified in config ..."));
965 keylen
= strlen(key
);
967 else if ((key
= config_get_string(filename
, "passphrase_file"))) {
968 int fd
= open((char *)key
, O_RDONLY
);
971 log_write(_("Trying the passphrase using file '%s' ..."), key
);
973 log_write("%s: %s", key
, pwmd_strerror(gpg_error_from_syserror()));
978 stat((char *)key
, &st
);
980 key
= xmalloc(st
.st_size
);
981 if (read(fd
, key
, st
.st_size
) != st
.st_size
) {
982 log_write("short read() count");
992 rc
= set_agent_passphrase(crypto
, key
, keylen
);
995 log_write("ERR %i: %s", rc
, pwmd_strerror(rc
));
1000 crypto
->filename
= str_dup(filename
);
1001 rc
= decrypt_data(NULL
, crypto
);
1003 log_write("ERR %i: %s", rc
, pwmd_strerror(rc
));
1007 doc
= parse_doc((char *)crypto
->plaintext
, crypto
->plaintext_len
);
1009 log_write("%s", pwmd_strerror(GPG_ERR_ENOMEM
));
1013 gcry_md_hash_buffer(GCRY_MD_MD5
, md5file
, filename
, strlen(filename
));
1014 cdata
= xcalloc(1, sizeof(struct cache_data_s
));
1017 log_write("%s", pwmd_strerror(GPG_ERR_ENOMEM
));
1021 rc
= get_checksum(filename
, &crc
, &len
);
1023 log_write("ERR %i: %s", rc
, pwmd_strerror(rc
));
1025 free_cache_data_once(cdata
);
1030 rc
= encrypt_xml(NULL
, cache_key
, cache_keysize
, GCRY_CIPHER_AES
,
1031 crypto
->plaintext
, crypto
->plaintext_len
, &cdata
->doc
,
1032 &cdata
->doclen
, &cache_iv
, &cache_blocksize
, 0);
1034 log_write("ERR %i: %s", rc
, pwmd_strerror(rc
));
1036 free_cache_data_once(cdata
);
1040 gcry_sexp_build((gcry_sexp_t
*)&cdata
->pubkey
, NULL
, "%S", crypto
->pkey_sexp
);
1041 gcry_sexp_build((gcry_sexp_t
*)&cdata
->sigkey
, NULL
, "%S", crypto
->sigpkey_sexp
);
1042 int timeout
= config_get_integer(filename
, "cache_timeout");
1043 cache_add_file(md5file
, crypto
->grip
, cdata
, timeout
);
1044 log_write(_("Successfully added '%s' to the cache."), filename
);
1048 static gpg_error_t
init_client_thread(int fd
, const char *addr
)
1051 struct client_thread_s
*new = xcalloc(1, sizeof(struct client_thread_s
));
1055 return GPG_ERR_ENOMEM
;
1058 MUTEX_LOCK(&cn_mutex
);
1059 pthread_cleanup_push(cleanup_mutex_cb
, &cn_mutex
);
1061 if (pipe(new->status_msg_pipe
) == -1)
1062 rc
= gpg_error_from_syserror();
1065 fcntl(new->status_msg_pipe
[0], F_SETFL
, O_NONBLOCK
);
1066 fcntl(new->status_msg_pipe
[1], F_SETFL
, O_NONBLOCK
);
1067 pthread_mutex_init(&new->status_mutex
, NULL
);
1072 new->remote
= addr
? 1 : 0;
1075 rc
= create_thread(client_thread
, new, &new->tid
, 1);
1077 close(new->status_msg_pipe
[0]);
1078 close(new->status_msg_pipe
[1]);
1079 pthread_mutex_destroy(&new->status_mutex
);
1084 struct slist_s
*list
= slist_append(cn_thread_list
, new);
1087 cn_thread_list
= list
;
1089 log_write(_("new connection: tid=%p, fd=%i, addr=%s"),
1090 (pthread_t
*)new->tid
, fd
, addr
);
1092 log_write(_("new connection: tid=%p, fd=%i"),
1093 (pthread_t
*)new->tid
, fd
);
1096 rc
= GPG_ERR_ENOMEM
;
1099 pthread_cleanup_pop(1);
1104 log_write("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1111 /* From Beej's Guide to Network Programming. It's a good tutorial. */
1112 static void *get_in_addr(struct sockaddr
*sa
)
1114 if (sa
->sa_family
== AF_INET
)
1115 return &(((struct sockaddr_in
*)sa
)->sin_addr
);
1117 return &(((struct sockaddr_in6
*)sa
)->sin6_addr
);
1120 static void *tcp_accept_thread(void *arg
)
1122 int sockfd
= *(int*)arg
;
1124 #ifdef HAVE_PR_SET_NAME
1125 prctl(PR_SET_NAME
, "tcp_accept");
1127 pthread_setspecific(thread_name_key
, str_dup(__FUNCTION__
));
1130 struct sockaddr_storage raddr
;
1131 socklen_t slen
= sizeof(raddr
);
1134 char s
[INET6_ADDRSTRLEN
];
1136 fd
= accept(sockfd
, (struct sockaddr
*)&raddr
, &slen
);
1138 if (errno
== EMFILE
|| errno
== ENFILE
)
1139 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
1140 else if (errno
!= EAGAIN
) {
1141 if (!quit
) // probably EBADF
1142 log_write("accept(): %s", strerror(errno
));
1153 inet_ntop(raddr
.ss_family
, get_in_addr((struct sockaddr
*)&raddr
),
1155 (void)init_client_thread(fd
, s
);
1156 n
= config_get_integer("global", "tcp_wait");
1161 /* Just in case accept() failed for some reason other than EBADF */
1166 static int start_stop_tls_with_protocol(int ipv6
, int term
)
1168 struct addrinfo hints
, *servinfo
, *p
;
1169 int port
= config_get_integer("global", "tcp_port");
1173 int *fd
= ipv6
? &tls6_fd
: &tls_fd
;
1175 if (term
|| config_get_boolean("global", "enable_tcp") == 0) {
1176 if (tls6_fd
!= -1) {
1177 pthread_cancel(tls6_tid
);
1178 pthread_join(tls6_tid
, NULL
);
1179 shutdown(tls6_fd
, SHUT_RDWR
);
1185 pthread_cancel(tls_tid
);
1186 pthread_join(tls_tid
, NULL
);
1187 shutdown(tls_fd
, SHUT_RDWR
);
1192 /* A client may still be connected. */
1193 if (!quit
&& x509_cred
!= NULL
)
1194 tls_deinit_params();
1199 if ((ipv6
&& tls6_fd
!= -1) || (!ipv6
&& tls_fd
!= -1))
1202 memset(&hints
, 0, sizeof(hints
));
1203 hints
.ai_family
= ipv6
? AF_INET6
: AF_INET
;
1204 hints
.ai_socktype
= SOCK_STREAM
;
1205 hints
.ai_flags
= AI_PASSIVE
;
1206 snprintf(buf
, sizeof(buf
), "%i", port
);
1208 if ((n
= getaddrinfo(NULL
, buf
, &hints
, &servinfo
)) == -1) {
1209 log_write("getaddrinfo(): %s", gai_strerror(n
));
1213 for (n
= 0, p
= servinfo
; p
!= NULL
; p
= p
->ai_next
) {
1216 if ((ipv6
&& p
->ai_family
!= AF_INET6
)
1217 || (!ipv6
&& p
->ai_family
!= AF_INET
))
1220 if ((*fd
= socket(p
->ai_family
, p
->ai_socktype
,
1221 p
->ai_protocol
)) == -1) {
1222 log_write("socket(): %s", strerror(errno
));
1226 if (setsockopt(*fd
, SOL_SOCKET
, SO_REUSEADDR
, &r
,
1227 sizeof(int)) == -1) {
1228 log_write("setsockopt(): %s", strerror(errno
));
1229 freeaddrinfo(servinfo
);
1233 if (bind(*fd
, p
->ai_addr
, p
->ai_addrlen
) == -1) {
1235 log_write("bind(): %s", strerror(errno
));
1243 freeaddrinfo(servinfo
);
1246 log_write("%s", _("could not bind"));
1250 #ifdef HAVE_DECL_SO_BINDTODEVICE
1251 char *tmp
= config_get_string("global", "tcp_interface");
1252 if (tmp
&& setsockopt(*fd
, SOL_SOCKET
, SO_BINDTODEVICE
, tmp
, 1) == -1) {
1253 log_write("setsockopt(): %s", strerror(errno
));
1261 if (x509_cred
== NULL
) {
1262 rc
= tls_init_params();
1267 if (listen(*fd
, 0) == -1) {
1268 log_write("listen(): %s", strerror(errno
));
1273 rc
= create_thread(tcp_accept_thread
, fd
, &tls6_tid
, 0);
1275 rc
= create_thread(tcp_accept_thread
, fd
, &tls_tid
, 0);
1278 log_write("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1286 start_stop_tls_with_protocol(0, 1);
1298 static int start_stop_tls(int term
)
1300 char *s
= config_get_string("global", "tcp_bind");
1306 if (!strcmp(s
, "any")) {
1307 b
= start_stop_tls_with_protocol(0, term
);
1309 b
= start_stop_tls_with_protocol(1, term
);
1311 else if (!strcmp(s
, "ipv4"))
1312 b
= start_stop_tls_with_protocol(0, term
);
1313 else if (!strcmp(s
, "ipv6"))
1314 b
= start_stop_tls_with_protocol(1, term
);
1323 static void *accept_thread(void *arg
)
1325 int sockfd
= *(int *)arg
;
1327 #ifdef HAVE_PR_SET_NAME
1328 prctl(PR_SET_NAME
, "accept");
1330 pthread_setspecific(thread_name_key
, str_dup(__FUNCTION__
));
1333 socklen_t slen
= sizeof(struct sockaddr_un
);
1334 struct sockaddr_un raddr
;
1337 fd
= accept(sockfd
, (struct sockaddr
*)&raddr
, &slen
);
1339 if (errno
== EMFILE
|| errno
== ENFILE
)
1340 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
1341 else if (errno
!= EAGAIN
) {
1342 if (!quit
) // probably EBADF
1343 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
1350 (void)init_client_thread(fd
, NULL
);
1353 /* Just in case accept() failed for some reason other than EBADF */
1358 static void *cache_timer_thread(void *arg
)
1360 #ifdef HAVE_PR_SET_NAME
1361 prctl(PR_SET_NAME
, "cache timer");
1363 pthread_setspecific(thread_name_key
, str_dup(__FUNCTION__
));
1367 cache_adjust_timeout();
1373 static void catch_sigabrt(int sig
)
1381 static int signal_loop(sigset_t sigset
)
1387 int sig
= sigwaitinfo(&sigset
, NULL
);
1390 if (errno
!= EAGAIN
)
1391 log_write("sigwaitinfo(): %s", strerror(errno
));
1396 log_write(_("caught signal %i (%s)"), sig
, strsignal(sig
));
1400 pthread_cond_signal(&rcfile_cond
);
1403 // not really handled here.
1404 catch_sigabrt(SIGABRT
);
1407 log_write(_("clearing file cache"));
1409 send_status_all(STATUS_CACHE
, NULL
);
1424 static void catchsig(int sig
)
1426 log_write("Caught SIGSEGV. Exiting.");
1427 #ifdef HAVE_BACKTRACE
1428 BACKTRACE(__FUNCTION__
);
1433 static void *waiting_for_exit(void *arg
)
1435 #ifdef HAVE_PR_SET_NAME
1436 prctl(PR_SET_NAME
, "exiting");
1438 pthread_setspecific(thread_name_key
, str_dup(__FUNCTION__
));
1439 log_write(_("waiting for all clients to disconnect"));
1440 MUTEX_LOCK(&quit_mutex
);
1441 pthread_cleanup_push(cleanup_mutex_cb
, &quit_mutex
);
1444 MUTEX_LOCK(&cn_mutex
);
1445 int n
= slist_length(cn_thread_list
);
1446 MUTEX_UNLOCK(&cn_mutex
);
1450 log_write(_("%i clients remain"), n
);
1451 pthread_cond_wait(&quit_cond
, &quit_mutex
);
1454 pthread_cleanup_pop(1);
1455 kill(getpid(), SIGUSR2
);
1459 static int server_loop(int sockfd
, char **socketpath
)
1461 pthread_t accept_tid
;
1462 pthread_t cache_timeout_tid
;
1463 int cancel_timeout_thread
= 0, cancel_accept_thread
= 0;
1470 sigemptyset(&sigset
);
1473 sigaddset(&sigset
, SIGTERM
);
1474 sigaddset(&sigset
, SIGINT
);
1476 /* Clears the file cache. */
1477 sigaddset(&sigset
, SIGUSR1
);
1479 /* Configuration file reloading. */
1480 sigaddset(&sigset
, SIGHUP
);
1482 /* For exiting cleanly. */
1483 sigaddset(&sigset
, SIGUSR2
);
1485 /* Clears the cache and exits when something bad happens. */
1486 signal(SIGABRT
, catch_sigabrt
);
1487 sigaddset(&sigset
, SIGABRT
);
1488 sigprocmask(SIG_BLOCK
, &sigset
, NULL
);
1490 /* Ignored everywhere. When a client disconnects abnormally this signal
1491 * gets raised. It isn't needed though because client_thread() will check
1492 * for rcs even after the client disconnects. */
1493 signal(SIGPIPE
, SIG_IGN
);
1495 /* Can show a backtrace of the stack in the log. */
1496 signal(SIGSEGV
, catchsig
);
1499 /* Needs to be done after the fork(). */
1500 if (!start_stop_tls(0)) {
1506 pthread_mutex_init(&quit_mutex
, NULL
);
1507 pthread_cond_init(&quit_cond
, NULL
);
1508 log_write(_("%s started for user %s"), PACKAGE_STRING
, get_username());
1509 #ifndef HAVE_DECL_SO_PEERCRED
1510 log_write(_("Peer credential checking is NOT supported on this OS."));
1513 if (config_get_boolean("global", "enable_tcp"))
1514 log_write(_("Listening on %s and TCP port %i"), *socketpath
,
1515 config_get_integer("global", "tcp_port"));
1517 log_write(_("Listening on %s"), *socketpath
);
1519 log_write(_("Listening on %s"), *socketpath
);
1522 rc
= create_thread(reload_rcfile_thread
, NULL
, &rcfile_tid
, 0);
1524 log_write("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1529 rc
= create_thread(cache_timer_thread
, NULL
, &cache_timeout_tid
, 1);
1531 log_write("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1536 cancel_timeout_thread
= 1;
1537 rc
= create_thread(accept_thread
, &sockfd
, &accept_tid
, 1);
1539 log_write("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1544 cancel_accept_thread
= 1;
1545 sigdelset(&sigset
, SIGUSR2
);
1547 signal_loop(sigset
);
1553 * We're out of the main server loop. This happens when a signal was sent
1554 * to terminate the daemon. We'll wait for all clients to disconnect
1555 * before exiting but exit immediately if another termination signal is
1558 if (cancel_accept_thread
)
1559 pthread_cancel(accept_tid
);
1561 shutdown(sockfd
, SHUT_RDWR
);
1563 unlink(*socketpath
);
1566 MUTEX_LOCK(&cn_mutex
);
1567 n
= slist_length(cn_thread_list
);
1568 MUTEX_UNLOCK(&cn_mutex
);
1573 rc
= create_thread(waiting_for_exit
, NULL
, &tid
, 1);
1575 sigaddset(&sigset
, SIGUSR2
);
1576 if (signal_loop(sigset
)) {
1577 log_write(_("Received second termination request. Exiting."));
1578 pthread_cancel(tid
);
1582 log_write("%s(%i): pthread_create(): %s", __FILE__
, __LINE__
,
1586 if (cancel_timeout_thread
)
1587 pthread_cancel(cache_timeout_tid
);
1589 MUTEX_LOCK(&cn_mutex
);
1591 n
= slist_length(cn_thread_list
);
1593 for (i
= 0; i
< n
; i
++) {
1594 struct client_thread_s
*thd
= slist_nth_data(cn_thread_list
, i
);
1596 if (thd
->fd
!= -1) {
1603 MUTEX_UNLOCK(&cn_mutex
);
1609 pthread_cond_destroy(&quit_cond
);
1610 pthread_mutex_destroy(&quit_mutex
);
1611 return segv
? EXIT_FAILURE
: EXIT_SUCCESS
;;
1614 static void startup_failure()
1616 log_write(_("Failed to add a file to the cache. Use --ignore to force startup. Exiting."));
1620 /* This is called from cache.c:clear_once(). See
1621 * command.c:clearcache_command() for details about lock checking.
1623 static gpg_error_t
free_cache_data(file_cache_t
*cache
)
1625 gpg_error_t rc
= GPG_ERR_NO_DATA
;
1627 struct client_thread_s
*found
= NULL
;
1634 MUTEX_LOCK(&cn_mutex
);
1635 pthread_cleanup_push(cleanup_mutex_cb
, &cn_mutex
);
1636 t
= slist_length(cn_thread_list
);
1638 for (i
= 0; i
< t
; i
++) {
1639 struct client_thread_s
*thd
= slist_nth_data(cn_thread_list
, i
);
1644 if (!memcmp(thd
->cl
->md5file
, cache
->filename
,
1645 sizeof(cache
->filename
))) {
1646 if (pthread_equal(pthread_self(), thd
->tid
)) {
1652 /* Continue trying to find a client who has the same file open and
1653 * also has a lock. */
1654 rc
= cache_lock_mutex(thd
->cl
->ctx
, thd
->cl
->md5file
, -1, 0, -1);
1663 if (self
&& (!rc
|| rc
== GPG_ERR_NO_DATA
))
1664 rc
= cache_lock_mutex(found
->cl
->ctx
, found
->cl
->md5file
, -1, 0, -1);
1666 if (exiting
|| !rc
|| rc
== GPG_ERR_NO_DATA
) {
1667 free_cache_data_once(cache
->data
);
1669 cache
->defer_clear
= 0;
1670 cache
->timeout
= -1;
1673 cache_unlock_mutex(found
->cl
->md5file
, 0);
1679 cache
->defer_clear
= 1;
1681 pthread_cleanup_pop(1);
1686 static int convert_v2_datafile(const char *filename
, const char *cipher
,
1687 const char *keyfile
, const char *keygrip
, const char *sign_keygrip
,
1688 int nopass
, const char *outfile
, const char *keyparam
,
1689 unsigned long s2k_count
, uint64_t iterations
)
1694 struct crypto_s
*crypto
= NULL
;
1698 if (outfile
[0] == '-' && outfile
[1] == 0)
1701 log_write(_("Converting version 2 data file \"%s\" ..."), filename
);
1702 if (access(filename
, R_OK
) == -1) {
1703 log_write("%s: %s", filename
, pwmd_strerror(gpg_error_from_syserror()));
1708 log_write(_("Using passphrase file \"%s\" for decryption ..."),
1710 if (access(keyfile
, R_OK
) == -1) {
1711 log_write("%s: %s", keyfile
,
1712 pwmd_strerror(gpg_error_from_syserror()));
1717 rc
= read_v2_datafile(filename
, keyfile
, &data
, &datalen
, &ver
, &algo
);
1719 log_write("ERR %i: %s", rc
, pwmd_strerror(rc
));
1724 algo
= cipher_string_to_gcrypt(cipher
);
1726 rc
= GPG_ERR_CIPHER_ALGO
;
1732 xmlDocPtr doc
= parse_doc(data
, datalen
);
1735 rc
= GPG_ERR_BAD_DATA
;
1739 rc
= convert_pre_212_elements(doc
);
1743 xmlDocDumpFormatMemory(doc
, (xmlChar
**)&data
, (int *)&datalen
, 0);
1745 rc
= GPG_ERR_ENOMEM
;
1753 rc
= init_client_crypto(&crypto
);
1755 rc
= set_pinentry_options(crypto
->agent
);
1757 memcpy(&crypto
->save
.hdr
, &crypto
->hdr
,
1758 sizeof(file_header_t
));
1759 crypto
->save
.hdr
.flags
= set_cipher_flag(crypto
->save
.hdr
.flags
, algo
);
1760 crypto
->save
.s2k_count
= s2k_count
;
1761 crypto
->save
.hdr
.iterations
= iterations
;
1762 rc
= export_common(crypto
, keygrip
, sign_keygrip
, nopass
, data
,
1763 datalen
, outfile
, keyparam
,
1764 no_passphrase_file
? NULL
: keyfile
);
1766 log_write(_("Output written to \"%s\"."), outfile
);
1775 cleanup_crypto(&crypto
);
1778 log_write("ERR %i: %s", rc
, pwmd_strerror(rc
));
1782 static void usage(const char *pn
, int status
)
1784 FILE *fp
= status
== EXIT_FAILURE
? stderr
: stdout
;
1787 "Usage: %s [OPTIONS] [file1] [...]\n"
1788 " -f, --rcfile=filename load the specfied configuration file\n"
1789 " (~/.pwmd/config)\n"
1790 " --homedir alternate pwmd home directory (~/.pwmd)\n"
1791 " -n, --no-fork run as a foreground process\n"
1792 " -D, --disable-dump disable the LIST, XPATH and DUMP commands\n"
1793 " --ignore ignore file errors during startup\n"
1794 " --debug-level=keywords log protocol output (see manual for details)\n"
1795 " -o, --outfile=filename output file when importing or converting\n"
1796 " -C, --convert=filename convert a version 2 data file to version 3\n"
1797 " -I, --import=filename import a pwmd DTD formatted XML file)\n"
1798 " -k, --passphrase-file=file for use when importing or converting\n"
1799 " --no-passphrase-file prompt instead of using --passphrase-file when\n"
1801 " --no-passphrase when importing or converting\n"
1802 " --keygrip=hex public key to use when encrypting\n"
1803 " --sign-keygrip=hex private key to use when signing\n"
1804 " --keyparam=s-exp custom key parameters to use (RSA-2048)\n"
1805 " --cipher=string encryption cipher (aes256)\n"
1806 " --iterations=N cipher iteration count (N+1)\n"
1807 " --s2k-count=N hash iteration count (>65536, calibrated)\n"
1808 " --help this help text\n"
1809 " --version show version and compile time features\n"
1814 int main(int argc
, char *argv
[])
1817 struct sockaddr_un addr
;
1819 char *socketpath
= NULL
, *socketdir
, *socketname
= NULL
;
1820 char *socketarg
= NULL
;
1821 char *datadir
= NULL
;
1824 char **cache_push
= NULL
;
1825 char *import
= NULL
, *keygrip
= NULL
, *sign_keygrip
= NULL
;
1826 char *keyparam
= NULL
;
1827 int estatus
= EXIT_FAILURE
;
1829 char *outfile
= NULL
;
1832 int show_version
= 0;
1834 int no_passphrase
= 0;
1836 char *convertfile
= NULL
;
1837 char *cipher
= NULL
;
1838 char *keyfile
= NULL
;
1839 unsigned long s2k_count
= 0;
1840 uint64_t iterations
= 0;
1842 char *debug_level_opt
= NULL
;
1844 /* Must maintain the same order as longopts[] */
1845 enum { OPT_VERSION
, OPT_HELP
, OPT_DEBUG_LEVEL
, OPT_HOMEDIR
, OPT_NO_FORK
,
1846 OPT_DISABLE_DUMP
, OPT_IGNORE
, OPT_RCFILE
, OPT_CONVERT
,
1847 OPT_PASSPHRASE_FILE
, OPT_IMPORT
, OPT_OUTFILE
, OPT_NO_PASSPHRASE_FILE
,
1848 OPT_KEYGRIP
, OPT_SIGN_KEYGRIP
, OPT_KEYPARAM
, OPT_CIPHER
,
1849 OPT_ITERATIONS
, OPT_S2K_COUNT
, OPT_NO_PASSPHRASE
1851 const char *optstring
= "nf:C:k:I:o:";
1852 const struct option longopts
[] = {
1853 {"version", no_argument
, 0, 0 },
1854 {"help", no_argument
, 0, 0 },
1855 {"debug-level", required_argument
, 0, 0 },
1856 {"homedir", required_argument
, 0, 0 },
1857 {"no-fork", no_argument
, 0, 'n' },
1858 {"disable_dump", no_argument
, 0, 0 },
1859 {"ignore", no_argument
, 0, 0 },
1860 {"rcfile", required_argument
, 0, 'f' },
1861 {"convert", required_argument
, 0, 'C' },
1862 {"passphrase-file", required_argument
, 0, 'k' },
1863 {"import", required_argument
, 0, 'I' },
1864 {"outfile", required_argument
, 0, 'o' },
1865 {"no-passphrase-file", no_argument
, 0, 0 },
1866 {"keygrip", required_argument
, 0, 0 },
1867 {"sign-keygrip", required_argument
, 0, 0 },
1868 {"keyparam", required_argument
, 0, 0 },
1869 {"cipher", required_argument
, 0, 0 },
1870 {"cipher-iterations", required_argument
, 0, 0 },
1871 {"s2k-count", required_argument
, 0, 0 },
1872 {"no-passphrase", no_argument
, 0, 0 },
1877 #ifdef HAVE_SETRLIMIT
1880 rl
.rlim_cur
= rl
.rlim_max
= 0;
1882 if (setrlimit(RLIMIT_CORE
, &rl
) != 0)
1883 err(EXIT_FAILURE
, "setrlimit()");
1888 setlocale(LC_ALL
, "");
1889 bindtextdomain("pwmd", LOCALEDIR
);
1902 gnutls_global_set_mem_functions(xmalloc
, xmalloc
, secure_mem_check
,
1904 gnutls_global_init();
1905 gnutls_global_set_log_function(tls_log
);
1906 gnutls_global_set_log_level(1);
1910 xmlMemSetup(xfree
, xmalloc
, xrealloc
, str_dup
);
1917 while ((opt
= getopt_long(argc
, argv
, optstring
, longopts
, &optindex
)) != -1) {
1923 convertfile
= optarg
;
1938 rcfile
= str_dup(optarg
);
1941 usage(argv
[0], EXIT_FAILURE
);
1951 case OPT_DEBUG_LEVEL
:
1952 debug_level_opt
= optarg
;
1955 homedir
= str_dup(optarg
);
1960 case OPT_DISABLE_DUMP
:
1967 rcfile
= str_dup(optarg
);
1970 convertfile
= optarg
;
1972 case OPT_PASSPHRASE_FILE
:
1981 case OPT_NO_PASSPHRASE_FILE
:
1982 no_passphrase_file
= 1;
1987 case OPT_SIGN_KEYGRIP
:
1988 sign_keygrip
= optarg
;
1996 case OPT_ITERATIONS
:
1997 iterations
= strtoull(optarg
, NULL
, 10);
2000 s2k_count
= strtoul(optarg
, NULL
, 10);
2002 case OPT_NO_PASSPHRASE
:
2013 "Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012\n"
2015 "Released under the terms of the GPL v2. Use at your own risk.\n\n"
2016 "Compile time features:\n%s"), PACKAGE_STRING
, PACKAGE_BUGREPORT
,
2047 homedir
= str_asprintf("%s/.pwmd", get_home_dir());
2049 if (mkdir(homedir
, 0700) == -1 && errno
!= EEXIST
)
2050 err(EXIT_FAILURE
, "%s", homedir
);
2052 snprintf(buf
, sizeof(buf
), "%s/data", homedir
);
2053 if (mkdir(buf
, 0700) == -1 && errno
!= EEXIST
)
2054 err(EXIT_FAILURE
, "%s", buf
);
2056 datadir
= str_dup(buf
);
2057 pthread_mutexattr_t attr
;
2058 pthread_mutexattr_init(&attr
);
2059 pthread_mutexattr_settype(&attr
, PTHREAD_MUTEX_RECURSIVE
);
2060 pthread_mutex_init(&rcfile_mutex
, &attr
);
2061 pthread_cond_init(&rcfile_cond
, NULL
);
2062 pthread_mutex_init(&cn_mutex
, &attr
);
2063 pthread_mutexattr_destroy(&attr
);
2064 pthread_key_create(&last_error_key
, free_key
);
2067 rcfile
= str_asprintf("%s/config", homedir
);
2069 global_config
= config_parse(rcfile
);
2075 if (debug_level_opt
)
2076 debug_level
= str_split(debug_level_opt
, ",", 0);
2078 x
= config_get_int_param(global_config
, "global", "priority", &exists
);
2081 if (setpriority(PRIO_PROCESS
, 0, x
) == -1) {
2082 log_write("setpriority(): %s", pwmd_strerror(gpg_error_from_syserror()));
2086 #ifdef HAVE_MLOCKALL
2087 if (disable_mlock
== 0 && mlockall(MCL_CURRENT
|MCL_FUTURE
) == -1) {
2088 log_write("mlockall(): %s", pwmd_strerror(gpg_error_from_syserror()));
2093 rc
= cache_init(free_cache_data
);
2095 log_write("pwmd: ERR %i: %s", rc
,
2096 gpg_err_code(rc
) == GPG_ERR_UNKNOWN_VERSION
2097 ? _("incompatible version: 2.1.0 or later required")
2098 : pwmd_strerror(rc
));
2103 s2k_count
= config_get_ulong(NULL
, "s2k_count");
2107 usage(argv
[0], EXIT_FAILURE
);
2109 estatus
= convert_v2_datafile(convertfile
, cipher
, keyfile
, keygrip
,
2110 sign_keygrip
, no_passphrase
, outfile
,
2111 keyparam
, s2k_count
, iterations
);
2112 config_free(global_config
);
2119 usage(argv
[0], EXIT_FAILURE
);
2121 if (outfile
[0] == '-' && outfile
[1] == 0)
2124 estatus
= xml_import(import
, outfile
, keygrip
, sign_keygrip
, keyfile
,
2125 no_passphrase
, cipher
, keyparam
, s2k_count
, iterations
);
2126 config_free(global_config
);
2131 p
= config_get_string("global", "socket_path");
2133 p
= str_asprintf("%s/socket", homedir
);
2135 socketarg
= expand_homedir(p
);
2139 disable_list_and_dump
= config_get_boolean("global",
2140 "disable_list_and_dump");
2142 disable_list_and_dump
= secure
;
2144 cache_push
= config_get_list("global", "cache_push");
2146 while (optind
< argc
) {
2147 if (strv_printf(&cache_push
, "%s", argv
[optind
++]) == 0)
2148 errx(EXIT_FAILURE
, "%s", pwmd_strerror(GPG_ERR_ENOMEM
));
2151 if (strchr(socketarg
, '/') == NULL
) {
2152 socketdir
= getcwd(buf
, sizeof(buf
));
2153 socketname
= str_dup(socketarg
);
2154 socketpath
= str_asprintf("%s/%s", socketdir
, socketname
);
2157 socketname
= str_dup(strrchr(socketarg
, '/'));
2159 socketarg
[strlen(socketarg
) - strlen(socketname
) -1] = 0;
2160 socketdir
= str_dup(socketarg
);
2161 socketpath
= str_asprintf("%s/%s", socketdir
, socketname
);
2164 if (chdir(datadir
)) {
2165 log_write("%s: %s", datadir
, pwmd_strerror(gpg_error_from_syserror()));
2171 * Set the cache entry for a file. Prompts for the password.
2174 struct crypto_s
*crypto
;
2175 gpg_error_t rc
= init_client_crypto(&crypto
);
2178 estatus
= EXIT_FAILURE
;
2182 rc
= set_pinentry_options(crypto
->agent
);
2184 estatus
= EXIT_FAILURE
;
2188 for (opt
= 0; cache_push
[opt
]; opt
++) {
2189 if (!do_cache_push(cache_push
[opt
], crypto
) && !force
) {
2190 strv_free(cache_push
);
2192 estatus
= EXIT_FAILURE
;
2193 cleanup_crypto(&crypto
);
2197 cleanup_crypto_stage1(crypto
);
2200 (void)kill_scd(crypto
->agent
);
2201 cleanup_crypto(&crypto
);
2202 strv_free(cache_push
);
2203 log_write(!nofork
? _("Done. Daemonizing...") : _("Done. Waiting for connections..."));
2206 config_clear_keyss();
2209 * bind() doesn't like the full pathname of the socket or any non alphanum
2210 * characters so change to the directory where the socket is wanted then
2211 * create it then change to datadir.
2213 if (chdir(socketdir
)) {
2214 log_write("%s: %s", socketdir
, pwmd_strerror(gpg_error_from_syserror()));
2220 if ((sockfd
= socket(PF_UNIX
, SOCK_STREAM
, 0)) == -1) {
2221 log_write("socket(): %s", pwmd_strerror(gpg_error_from_syserror()));
2225 addr
.sun_family
= AF_UNIX
;
2226 snprintf(addr
.sun_path
, sizeof(addr
.sun_path
), "%s", socketname
);
2228 if (bind(sockfd
, (struct sockaddr
*)&addr
, sizeof(struct sockaddr
)) == -1) {
2229 log_write("bind(): %s", pwmd_strerror(gpg_error_from_syserror()));
2231 if (errno
== EADDRINUSE
)
2232 log_write(_("Either there is another pwmd running or '%s' is a \n"
2233 "stale socket. Please remove it manually."), socketpath
);
2240 char *t
= config_get_string("global", "socket_perms");
2245 mode
= strtol(t
, NULL
, 8);
2249 if (chmod(socketname
, mode
) == -1) {
2250 log_write("%s: %s", socketname
,
2251 pwmd_strerror(gpg_error_from_syserror()));
2262 xfree(--socketname
);
2264 if (chdir(datadir
)) {
2265 log_write("%s: %s", datadir
, pwmd_strerror(gpg_error_from_syserror()));
2273 if (listen(sockfd
, 0) == -1) {
2274 log_write("listen(): %s", pwmd_strerror(gpg_error_from_syserror()));
2283 log_write("fork(): %s", pwmd_strerror(gpg_error_from_syserror()));
2292 _exit(EXIT_SUCCESS
);
2296 pthread_key_create(&thread_name_key
, free_key
);
2297 pthread_setspecific(thread_name_key
, str_dup("main"));
2298 estatus
= server_loop(sockfd
, &socketpath
);
2301 if (socketpath
&& do_unlink
) {
2308 gnutls_global_deinit();
2310 pthread_cancel(rcfile_tid
);
2311 pthread_join(rcfile_tid
, NULL
);
2312 pthread_cond_destroy(&rcfile_cond
);
2313 pthread_mutex_destroy(&rcfile_mutex
);
2316 config_free(global_config
);
2319 xfree(home_directory
);
2322 xmlCleanupGlobals();
2324 if (estatus
== EXIT_SUCCESS
)
2325 log_write(_("pwmd exiting normally"));
2328 #if defined(DEBUG) && !defined(MEM_DEBUG)