1 /* vim:tw=78:ts=8:sw=4:set ft=c: */
3 Copyright (C) 2006-2011 Ben Kibbey <bjk@luxsci.net>
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU General Public License as published by
7 the Free Software Foundation; either version 2 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
15 You should have received a copy of the GNU General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02110-1301 USA
38 #include <glib/gprintf.h>
39 #include <glib/gstdio.h>
46 #include <netinet/in.h>
47 #include <arpa/inet.h>
50 #include <sys/resource.h>
67 #include "pwmd_error.h"
74 GCRY_THREAD_OPTION_PTH_IMPL
;
76 static void *reload_rcfile_thread(void *arg
)
78 gboolean b
= disable_list_and_dump
;
79 gchar
**users
= g_key_file_get_string_list(keyfileh
, "global", "allowed",
82 pth_attr_t attr
= pth_attr_of(pth_self());
84 pth_attr_set(attr
, PTH_ATTR_NAME
, __FUNCTION__
);
85 pth_attr_destroy(attr
);
86 MUTEX_LOCK(&rcfile_mutex
);
87 log_write(_("reloading configuration file '%s'"), rcfile
);
88 k
= parse_rcfile(FALSE
);
93 g_key_file_free(keyfileh
);
95 parse_rcfile_keys(FALSE
);
97 send_status_all(STATUS_CONFIG
);
99 disable_list_and_dump
= !disable_list_and_dump
? b
: TRUE
;
100 g_key_file_set_string_list(keyfileh
, "global", "allowed",
101 (const gchar
**)users
, g_strv_length(users
));
103 MUTEX_UNLOCK(&rcfile_mutex
);
107 static void reload_rcfile()
110 pth_attr_t attr
= pth_attr_new();
114 pth_attr_set(attr
, PTH_ATTR_JOINABLE
, 0);
115 tid
= pth_spawn(attr
, reload_rcfile_thread
, NULL
);
116 rc
= gpg_error_from_syserror();
117 pth_attr_destroy(attr
);
120 log_write("%s(%i): pth_spawn(): %s", __FILE__
, __LINE__
,
124 gpg_error_t
send_error(assuan_context_t ctx
, gpg_error_t e
)
126 gpg_err_code_t n
= gpg_err_code(e
);
127 gpg_error_t code
= gpg_err_make(PWMD_ERR_SOURCE
, n
);
128 struct client_s
*client
= assuan_get_pointer(ctx
);
134 return assuan_process_done(ctx
, 0);
137 log_write("%s", pwmd_strerror(e
));
141 if (n
== EPWMD_LIBXML_ERROR
) {
142 xmlErrorPtr xe
= client
->xml_error
;
145 xe
= xmlGetLastError();
147 e
= assuan_process_done(ctx
, assuan_set_error(ctx
, code
, xe
->message
));
148 log_write("%s", xe
->message
);
150 if (xe
== client
->xml_error
)
155 client
->xml_error
= NULL
;
159 return assuan_process_done(ctx
, assuan_set_error(ctx
, code
, pwmd_strerror(e
)));
162 void log_write(const gchar
*fmt
, ...)
172 pth_t tid
= pth_self();
175 if ((!logfile
&& !isatty(STDERR_FILENO
) && log_syslog
== FALSE
) || !fmt
)
178 if (!cmdline
&& logfile
) {
179 if ((fd
= open(logfile
, O_WRONLY
|O_CREAT
|O_APPEND
, 0600)) == -1) {
189 if (g_vasprintf(&args
, fmt
, ap
) == -1) {
190 if (logfile
&& fd
!= -1)
200 fprintf(stderr
, "%s\n", args
);
206 attr
= pth_attr_of(tid
);
208 if (pth_attr_get(attr
, PTH_ATTR_NAME
, &name
) == FALSE
)
211 pth_attr_destroy(attr
);
212 name
= print_fmt(buf
, sizeof(buf
), "%s(%p): ", name
, tid
);
214 if (!cmdline
&& log_syslog
== TRUE
)
215 syslog(LOG_INFO
, "%s%s", name
, args
);
218 tm
= localtime(&now
);
219 strftime(tbuf
, sizeof(tbuf
), "%b %d %Y %H:%M:%S ", tm
);
220 tbuf
[sizeof(tbuf
) - 1] = 0;
222 if (args
[strlen(args
)-1] == '\n')
223 args
[strlen(args
)-1] = 0;
225 line
= g_strdup_printf("%s %i %s%s\n", tbuf
, getpid(), name
, args
);
229 if (logfile
&& fd
!= -1)
235 if (logfile
&& fd
!= -1) {
236 pth_write(fd
, line
, strlen(line
));
241 if (isatty(STDERR_FILENO
)) {
242 fprintf(stderr
, "%s", line
);
249 static void setup_gcrypt()
251 gcry_control(GCRYCTL_SET_THREAD_CBS
, &gcry_threads_pth
);
253 if (!gcry_check_version("1.3.1"))
254 errx(EXIT_FAILURE
, _("gcry_check_version(): Incompatible libgcrypt. Wanted %s, got %s."), GCRYPT_VERSION
, gcry_check_version(NULL
));
256 gcry_set_allocation_handler(g_malloc
, g_malloc
, NULL
, g_realloc
, g_free
);
259 static gpg_error_t
validate_peer(struct client_s
*cl
)
262 gboolean allowed
= FALSE
;
266 gpg_error_t rc
= assuan_get_peercred(cl
->ctx
, &pid
, &uid
, &gid
);
271 users
= g_key_file_get_string_list(keyfileh
, "global", "allowed", NULL
, NULL
);
274 for (gchar
**p
= users
; *p
; p
++) {
275 struct passwd pw
, *result
;
276 struct group gr
, *gresult
;
280 size_t len
= sysconf(_SC_GETGR_R_SIZE_MAX
);
289 return GPG_ERR_ENOMEM
;
292 if (!getgrnam_r(*(p
)+1, &gr
, buf
, len
, &gresult
) && gresult
) {
293 if (gresult
->gr_gid
== gid
) {
299 len
= sysconf(_SC_GETPW_R_SIZE_MAX
);
304 gchar
*tbuf
= g_malloc(len
);
306 for (gchar
**t
= gresult
->gr_mem
; *t
; t
++) {
307 if (!getpwnam_r(*t
, &pw
, tbuf
, len
, &result
) && result
) {
308 if (result
->pw_uid
== uid
) {
323 size_t len
= sysconf(_SC_GETPW_R_SIZE_MAX
);
332 return GPG_ERR_ENOMEM
;
335 if (!getpwnam_r(*p
, &pw
, buf
, len
, &result
) && result
) {
336 if (result
->pw_uid
== uid
) {
350 log_write("peer %s: uid=%i, gid=%i, pid=%i",
351 allowed
? _("accepted") : _("rejected"), uid
, gid
,pid
);
352 return allowed
? 0 : GPG_ERR_INV_USER_ID
;
355 static gboolean
new_connection(struct client_s
*cl
)
361 rc
= assuan_init_socket_server_ext(&cl
->ctx
, cl
->thd
->fd
, 2);
366 assuan_set_pointer(cl
->ctx
, cl
);
367 ver
= g_strdup_printf("%s", PACKAGE_STRING
);
368 assuan_set_hello_line(cl
->ctx
, ver
);
370 rc
= register_commands(cl
->ctx
);
375 rc
= assuan_accept(cl
->ctx
);
380 rc
= validate_peer(cl
);
382 /* May not be implemented on all platforms. */
383 if (rc
&& gpg_err_code(rc
) != GPG_ERR_ASS_GENERAL
)
386 str
= get_key_file_string("global", "debug_file");
389 assuan_set_log_stream(cl
->ctx
, debugfp
);
397 log_write("%s", pwmd_strerror(rc
));
401 static void xml_error_cb(void *data
, xmlErrorPtr e
)
403 struct client_s
*client
= data
;
406 * Keep the first reported error as the one to show in the error
407 * description. Reset in send_error().
409 if (client
->xml_error
)
412 xmlCopyError(e
, client
->xml_error
);
415 void close_file_header(file_header_internal_t
*fh
)
420 if (fh
->fd
!= -1 || (cmdline
== TRUE
&& fh
->fd
!= STDOUT_FILENO
))
429 void cleanup_crypto(struct crypto_s
**c
)
431 struct crypto_s
*cr
= *c
;
452 gcry_free(cr
->tkey2
);
457 gcry_free(cr
->inbuf
);
462 gcry_free(cr
->outbuf
);
466 close_file_header(cr
->fh
);
470 gcry_cipher_close(cr
->gh
);
478 * This is called after a client_thread terminates. Set with
479 * pth_cleanup_push().
481 static void cleanup_cb(void *arg
)
483 struct client_thread_s
*cn
= arg
;
484 struct client_s
*cl
= cn
->cl
;
486 MUTEX_LOCK(&cn_mutex
);
487 cn_thread_list
= g_slist_remove(cn_thread_list
, cn
);
488 MUTEX_UNLOCK(&cn_mutex
);
491 MUTEX_LOCK(&cn
->mp_mutex
);
492 pth_cancel(cn
->msg_tid
);
493 MUTEX_UNLOCK(&cn
->mp_mutex
);
497 while (pth_msgport_pending(cn
->mp
)) {
498 pth_message_t
*msg
= pth_msgport_get(cn
->mp
);
504 pth_msgport_destroy(cn
->mp
);
518 assuan_deinit_server(cl
->ctx
);
519 else if (cl
->thd
&& cl
->thd
->fd
!= -1)
524 cleanup_pinentry(cl
->pinentry
);
528 cleanup_crypto(&cl
->crypto
);
532 log_write(_("exiting, fd=%i"), cn
->fd
);
534 send_status_all(STATUS_CLIENTS
);
538 * Called every time a connection is made from init_new_connection(). This is
539 * the thread entry point.
541 static void *client_thread(void *data
)
543 struct client_thread_s
*thd
= data
;
544 struct client_s
*cl
= g_malloc0(sizeof(struct client_s
));
549 * Prevent a race condition with init_new_connection() if this thread
550 * fails (returns) for some reason before init_new_connection() releases
553 MUTEX_LOCK(&cn_mutex
);
554 MUTEX_UNLOCK(&cn_mutex
);
555 pth_cleanup_push(cleanup_cb
, thd
);
558 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
562 attr
= pth_attr_of(pth_self());
563 pth_attr_set(attr
, PTH_ATTR_NAME
, __FUNCTION__
);
564 pth_attr_destroy(attr
);
568 if (!new_connection(cl
))
572 cl
->pinentry
= pinentry_init();
575 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
580 thd
->mp
= pth_msgport_create(NULL
);
581 pth_mutex_init(&thd
->mp_mutex
);
582 thd
->msg_tid
= pth_spawn(NULL
, client_msg_thread
, thd
);
583 rc
= gpg_error_from_syserror();
586 log_write("%s(%i): pth_spawn(): %s", __FILE__
, __LINE__
,
591 pth_yield(thd
->msg_tid
);
592 rc
= send_status(cl
->ctx
, STATUS_CACHE
, NULL
);
595 log_write("%s", pwmd_strerror(rc
));
599 send_status_all(STATUS_CLIENTS
);
600 xmlSetStructuredErrorFunc(cl
, xml_error_cb
);
604 pth_event_t pev
= NULL
;
606 pth_status_t st
, wst
;
607 pth_event_t wev
= NULL
;
608 pth_event_t rev
= pth_event(PTH_EVENT_FD
|PTH_UNTIL_FD_READABLE
,
610 pth_event_t ev
= rev
;
613 if (cl
->pinentry
->status
== PINENTRY_RUNNING
) {
614 pev
= pth_event(PTH_EVENT_FD
|PTH_UNTIL_FD_READABLE
, cl
->pinentry
->fd
);
615 ev
= pth_event_concat(ev
, pev
, NULL
);
619 if (cl
->inquire_status
== INQUIRE_BUSY
) {
620 wev
= pth_event(PTH_EVENT_FD
|PTH_UNTIL_FD_WRITEABLE
, cl
->thd
->fd
);
621 ev
= pth_event_concat(ev
, wev
, NULL
);
624 pth_cleanup_push(cleanup_ev_cb
, ev
);
626 st
= pth_event_status(rev
);
627 wst
= pth_event_status(wev
);
629 if (st
== PTH_STATUS_OCCURRED
|| wst
== PTH_STATUS_OCCURRED
) {
630 rc
= assuan_process_next(cl
->ctx
);
633 cl
->inquire_status
= INQUIRE_INIT
;
636 if (gpg_err_code(rc
) == GPG_ERR_EOF
)
639 log_write("assuan_process_next(): %s", pwmd_strerror(rc
));
640 rc
= send_error(cl
->ctx
, gpg_err_make(PWMD_ERR_SOURCE
, rc
));
643 log_write("assuan_process_done(): %s", pwmd_strerror(rc
));
649 if (cl
->pinentry
->pid
&& cl
->pinentry
->status
== PINENTRY_INIT
)
650 cl
->pinentry
->status
= PINENTRY_RUNNING
;
653 switch (cl
->inquire_status
) {
658 cl
->inquire_status
= INQUIRE_INIT
;
659 rc
= assuan_process_done(cl
->ctx
, 0);
667 st
= pth_event_status(pev
);
669 rc
= pinentry_iterate(cl
,
670 pev
&& cl
->pinentry
->fd
!= -1 && st
== PTH_STATUS_OCCURRED
);
676 * Client cleanup (including XML data) is done in cleanup_cb().
680 pth_exit(PTH_CANCELED
);
684 static gchar
*do_read_password(const gchar
*prompt
)
686 gchar buf
[LINE_MAX
] = {0}, *p
;
687 struct termios told
, tnew
;
690 if (tcgetattr(STDIN_FILENO
, &told
) == -1) {
691 log_write("tcgetattr(): %s", pwmd_strerror(gpg_error_from_syserror()));
695 memcpy(&tnew
, &told
, sizeof(struct termios
));
696 tnew
.c_lflag
&= ~(ECHO
);
697 tnew
.c_lflag
|= ICANON
|ECHONL
;
699 if (tcsetattr(STDIN_FILENO
, TCSANOW
, &tnew
) == -1) {
700 log_write("tcsetattr(): %s", pwmd_strerror(gpg_error_from_syserror()));
701 tcsetattr(STDIN_FILENO
, TCSANOW
, &told
);
705 fprintf(stderr
, "%s", prompt
);
707 if ((p
= fgets(buf
, sizeof(buf
), stdin
)) == NULL
) {
708 tcsetattr(STDIN_FILENO
, TCSANOW
, &told
);
712 tcsetattr(STDIN_FILENO
, TCSANOW
, &told
);
713 p
[strlen(p
) - 1] = 0;
716 key
= gcry_malloc(1);
720 key
= gcry_malloc(strlen(p
) + 1);
721 sprintf(key
, "%s", p
);
724 memset(&buf
, 0, sizeof(buf
));
728 /* Only used when "enable_pinentry" is "false" or -P. */
729 static gpg_error_t
read_password(const gchar
*filename
,
730 struct crypto_s
*crypto
, guchar
*key
, pinentry_cmd_t which
)
734 if (which
== PINENTRY_SAVE
) {
735 prompt
= g_strdup_printf(_("New passphrase for file %s: "), filename
);
736 crypto
->tkey
= do_read_password(prompt
);
740 log_write(_("%s: Skipping file"), filename
);
741 return GPG_ERR_BAD_PASSPHRASE
;
744 prompt
= g_strdup_printf(_("Repeat passphrase: "));
745 crypto
->tkey2
= do_read_password(prompt
);
748 if (!crypto
->tkey2
) {
749 log_write(_("%s: Skipping file"), filename
);
750 return GPG_ERR_BAD_PASSPHRASE
;
753 if (g_strcmp0(crypto
->tkey
, crypto
->tkey2
)) {
754 log_write(_("%s: Passphrase mismatch"), filename
);
755 return GPG_ERR_INV_PASSPHRASE
;
758 gcry_md_hash_buffer(GCRY_MD_SHA256
, key
, crypto
->tkey
,
759 strlen(crypto
->tkey
) ? strlen(crypto
->tkey
) : 1);
763 prompt
= g_strdup_printf(_("Passphrase required for %s: "), filename
);
765 if ((crypto
->tkey
= do_read_password(prompt
)) == NULL
) {
766 log_write(_("%s: Skipping file"), filename
);
768 return GPG_ERR_BAD_PASSPHRASE
;
771 gcry_md_hash_buffer(GCRY_MD_SHA256
, key
, crypto
->tkey
,
772 strlen(crypto
->tkey
) ? strlen(crypto
->tkey
) : 1);
778 * inbuf must have been allocated with gcry_malloc().
780 gpg_error_t
export_common(const gchar
*filename
, struct crypto_s
*crypto
,
781 gpointer inbuf
, gulong insize
)
788 rc
= update_save_flags(NULL
, crypto
);
793 level
= get_key_file_integer(filename
, "compression_level");
798 rc
= do_compress(NULL
, level
, inbuf
, insize
, &outbuf
, &outsize
);
803 crypto
->inbuf
= outbuf
;
804 crypto
->insize
= outsize
;
805 rc
= do_xml_encrypt(NULL
, crypto
, filename
);
809 static gpg_error_t
get_password(const gchar
*filename
,
810 struct crypto_s
*crypto
, guchar
*md5file
, guchar
*key
,
811 pinentry_cmd_t which
)
816 if (g_key_file_get_boolean(keyfileh
, "global", "enable_pinentry", NULL
)
819 return read_password(filename
, crypto
, key
, which
);
823 gchar
*result
= NULL
;
824 struct pinentry_s
*pin
= g_malloc0(sizeof(struct pinentry_s
));
826 pth_mutex_init(&pin
->status_mutex
);
827 set_pinentry_defaults(pin
);
829 pin
->filename
= g_strdup(filename
);
830 rc
= pinentry_getpin(pin
, &result
);
837 gcry_md_hash_buffer(GCRY_MD_SHA256
, key
, result
, result
? strlen(result
) : 1);
839 cleanup_pinentry(pin
);
847 static gboolean
xml_import(const gchar
*filename
, const gchar
*outfile
,
848 const gchar
*keyfile
, guint64 iter
)
857 struct crypto_s
*crypto
;
858 guint hashlen
= gcry_md_get_algo_dlen(GCRY_MD_SHA256
);
860 if (g_stat(filename
, &st
) == -1) {
861 log_write("%s: %s", filename
, pwmd_strerror(gpg_error_from_syserror()));
865 crypto
= init_client_crypto();
870 crypto
->key
= gcry_malloc(hashlen
);
871 memset(crypto
->key
, 0, hashlen
);
874 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
878 log_write(_("Importing XML from '%s'. Output will be written to '%s' ..."),
881 if (iter
&& keyfile
) {
882 rc
= parse_rcfile_keyfile(crypto
, keyfile
, TRUE
);
887 gcry_md_hash_buffer(GCRY_MD_SHA256
, crypto
->key
, crypto
->tkey
,
891 rc
= get_password(outfile
, crypto
, NULL
, crypto
->key
, PINENTRY_SAVE
);
893 if (rc
== GPG_ERR_ASSUAN_SERVER_FAULT
) {
894 log_write(_("%s. Maybe disabling pinentry (-P) will help?"),
899 log_write("%s", pwmd_strerror(rc
));
904 if ((fd
= open(filename
, O_RDONLY
)) == -1) {
905 log_write("%s: %s", filename
, pwmd_strerror(gpg_error_from_syserror()));
909 if ((xmlbuf
= gcry_malloc(st
.st_size
+1)) == NULL
) {
911 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
915 if (pth_read(fd
, xmlbuf
, st
.st_size
) == -1) {
916 rc
= gpg_error_from_syserror();
918 log_write("%s: %s", filename
, pwmd_strerror(rc
));
923 xmlbuf
[st
.st_size
] = 0;
926 * Make sure the document validates.
928 if ((doc
= xmlReadDoc(xmlbuf
, NULL
, "UTF-8", XML_PARSE_NOBLANKS
)) == NULL
) {
929 log_write("xmlReadDoc() failed");
935 xmlNodePtr n
= xmlDocGetRootElement(doc
);
936 rc
= validate_import(n
? n
->children
: n
);
939 log_write("%s", pwmd_strerror(rc
));
944 xmlDocDumpMemory(doc
, &xml
, &len
);
948 memset(crypto
->key
, '!', hashlen
);
950 crypto
->fh
= g_malloc0(sizeof(file_header_internal_t
));
953 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
957 crypto
->fh
->ver
.fh2
.iter
= iter
;
958 rc
= export_common(outfile
, crypto
, xml
, len
);
962 send_error(NULL
, rc
);
966 cleanup_crypto(&crypto
);
970 cleanup_crypto(&crypto
);
974 gboolean
do_cache_push(const gchar
*filename
, const void *password
,
979 const gchar
*p
= filename
;
980 struct crypto_s
*crypto
;
982 guint hashlen
= gcry_md_get_algo_dlen(GCRY_MD_SHA256
);
990 if (valid_filename(p
) == FALSE
) {
991 log_write(_("%s: Invalid characters in filename"), p
);
995 gcry_md_hash_buffer(GCRY_MD_MD5
, md5file
, p
, strlen(p
));
997 if (cache_iscached(md5file
)) {
998 log_write(_("%s: already cached, skipping"), p
);
1002 if (access(p
, R_OK
|W_OK
) != 0) {
1003 log_write("%s: %s", p
, pwmd_strerror(gpg_error_from_syserror()));
1007 crypto
= init_client_crypto();
1012 crypto
->fh
= read_file_header(filename
, FALSE
, &rc
);
1015 log_write("%s: %s", p
, pwmd_strerror(rc
));
1016 cleanup_crypto(&crypto
);
1020 crypto
->key
= gcry_malloc(hashlen
);
1023 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
1024 cleanup_crypto(&crypto
);
1028 log_write(_("Adding '%s' to the file cache ..."), filename
);
1030 if (crypto
->fh
->ver
.fh2
.iter
<= 0ULL) {
1031 memset(crypto
->key
, '!', hashlen
);
1036 rc
= get_password(p
, crypto
, md5file
, crypto
->key
, PINENTRY_OPEN
);
1039 send_error(NULL
, rc
);
1040 cleanup_crypto(&crypto
);
1044 gcry_free(crypto
->fh
->doc
);
1045 crypto
->fh
->doc
= NULL
;
1048 gcry_md_hash_buffer(GCRY_MD_SHA256
, crypto
->key
, password
, len
);
1051 rc
= init_client_crypto2(filename
, crypto
);
1054 send_error(NULL
, rc
);
1055 cleanup_crypto(&crypto
);
1059 rc
= try_xml_decrypt(NULL
, crypto
, NULL
, NULL
);
1062 log_write("%s: %s", filename
, pwmd_strerror(rc
));
1063 cleanup_crypto(&crypto
);
1067 if (cache_update_key(md5file
, crypto
->key
) == FALSE
) {
1068 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
1069 cleanup_crypto(&crypto
);
1073 timeout
= get_key_file_integer(p
, "cache_timeout");
1074 cache_set_timeout(md5file
, timeout
);
1075 log_write(_("File '%s' now cached"), filename
);
1076 cleanup_crypto(&crypto
);
1080 static void init_new_connection(gint fd
)
1083 struct client_thread_s
*new;
1086 new = g_malloc0(sizeof(struct client_thread_s
));
1089 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
1094 MUTEX_LOCK(&cn_mutex
);
1096 attr
= pth_attr_new();
1097 pth_attr_init(attr
);
1098 pth_attr_set(attr
, PTH_ATTR_JOINABLE
, FALSE
);
1099 new->tid
= pth_spawn(attr
, client_thread
, new);
1100 rc
= gpg_error_from_syserror();
1101 pth_attr_destroy(attr
);
1106 log_write("%s(%i): pth_spawn(): %s", __FILE__
, __LINE__
,
1108 MUTEX_UNLOCK(&cn_mutex
);
1112 cn_thread_list
= g_slist_append(cn_thread_list
, new);
1113 MUTEX_UNLOCK(&cn_mutex
);
1114 log_write(_("new connection: tid=%p, fd=%i"), new->tid
, fd
);
1117 static void *accept_thread(void *arg
)
1119 gint sockfd
= *(gint
*)arg
;
1120 pth_attr_t attr
= pth_attr_of(pth_self());
1122 pth_attr_set(attr
, PTH_ATTR_NAME
, __FUNCTION__
);
1123 pth_attr_destroy(attr
);
1126 socklen_t slen
= sizeof(struct sockaddr_un
);
1127 struct sockaddr_un raddr
;
1130 fd
= pth_accept(sockfd
, (struct sockaddr
*)&raddr
, &slen
);
1133 if (errno
!= EAGAIN
) {
1134 if (!quit
) // probably EBADF
1135 log_write("accept(): %s", pwmd_strerror(gpg_error_from_syserror()));
1143 init_new_connection(fd
);
1146 /* Just in case accept() failed for some reason other than EBADF */
1148 pth_exit(PTH_CANCELED
);
1152 static void *adjust_cache_timer_thread(void *arg
)
1154 pth_attr_t attr
= pth_attr_of(pth_self());
1156 pth_attr_set(attr
, PTH_ATTR_NAME
, __FUNCTION__
);
1157 pth_attr_destroy(attr
);
1162 cache_adjust_timer();
1169 void cleanup_mutex_cb(void *arg
)
1171 pth_mutex_t
*m
= arg
;
1176 void cleanup_ev_cb(void *arg
)
1178 pth_event_t ev
= arg
;
1180 pth_event_free(ev
, PTH_FREE_ALL
);
1183 void cleanup_fd_cb(void *arg
)
1185 gint fd
= *(gint
*)arg
;
1190 void cleanup_unlink_cb(void *arg
)
1197 void cleanup_cancel_cb(void *arg
)
1203 attr
= pth_attr_of(tid
);
1204 pth_attr_get(attr
, PTH_ATTR_JOINABLE
, &join
);
1215 static gboolean
waiting_for_exit()
1218 pth_event_t evs
= NULL
;
1220 MUTEX_LOCK(&cn_mutex
);
1222 for (t
= g_slist_length(cn_thread_list
), i
= 0; i
< t
; i
++) {
1223 struct client_thread_s
*thd
= g_slist_nth_data(cn_thread_list
, i
);
1224 pth_event_t ev
= pth_event(PTH_EVENT_TID
|PTH_UNTIL_TID_DEAD
, thd
->tid
);
1227 evs
= pth_event_concat(evs
, ev
, NULL
);
1232 MUTEX_UNLOCK(&cn_mutex
);
1238 MUTEX_LOCK(&cn_mutex
);
1239 i
= g_slist_length(cn_thread_list
);
1240 MUTEX_UNLOCK(&cn_mutex
);
1241 pth_event_free(evs
, PTH_FREE_ALL
);
1242 return i
? TRUE
: FALSE
;
1245 static void catch_sigabrt(int sig
)
1247 cache_clear(NULL
, 2);
1253 static void server_loop(gint sockfd
, gchar
**socketpath
)
1259 pth_t cache_timeout_tid
= NULL
;
1263 sigemptyset(&sigset
);
1266 sigaddset(&sigset
, SIGTERM
);
1267 sigaddset(&sigset
, SIGINT
);
1269 /* Clears the file cache. */
1270 sigaddset(&sigset
, SIGUSR1
);
1272 /* Configuration file reloading. */
1273 sigaddset(&sigset
, SIGHUP
);
1275 /* Clears the cache and exits when something bad happens. */
1276 signal(SIGABRT
, catch_sigabrt
);
1277 sigaddset(&sigset
, SIGABRT
);
1279 /* Ignored everywhere. When a client disconnects abnormally this signal
1280 * gets raised. It isn't needed though because client_thread() will check
1281 * for rcs even after the client disconnects. */
1282 signal(SIGPIPE
, SIG_IGN
);
1283 sigprocmask(SIG_BLOCK
, &sigset
, NULL
);
1285 log_write(_("%s started for user %s"), PACKAGE_STRING
, g_get_user_name());
1286 log_write(_("Listening on %s"), *socketpath
);
1287 #ifndef HAVE_SO_PEERCRED
1288 log_write(_("Peer credential checking is NOT supported on this OS."));
1290 attr
= pth_attr_new();
1291 pth_attr_init(attr
);
1292 accept_tid
= pth_spawn(attr
, accept_thread
, &sockfd
);
1293 rc
= gpg_error_from_syserror();
1296 log_write("%s(%i): pth_spawn(): %s", __FILE__
, __LINE__
,
1298 pth_attr_destroy(attr
);
1302 pth_yield(accept_tid
);
1303 pth_attr_set(attr
, PTH_ATTR_JOINABLE
, FALSE
);
1304 cache_timeout_tid
= pth_spawn(attr
, adjust_cache_timer_thread
, NULL
);
1305 rc
= gpg_error_from_syserror();
1307 if (!cache_timeout_tid
) {
1308 log_write("%s(%i): pth_spawn(): %s", __FILE__
, __LINE__
,
1310 pth_attr_destroy(attr
);
1314 pth_yield(cache_timeout_tid
);
1315 pth_attr_destroy(attr
);
1318 gchar
*str
= get_key_file_string("global", "debug_file");
1321 gchar
*f
= expand_homedir(str
);
1324 debugfp
= fopen(f
, "w");
1327 log_write("%s: %s", f
, pwmd_strerror(gpg_error_from_syserror()));
1329 assuan_set_assuan_log_stream(debugfp
);
1338 pth_sigwait(&sigset
, &sig
);
1339 log_write(_("caught signal %i (%s)"), sig
, strsignal(sig
));
1341 /* Caught a signal. */
1347 // not really handled here.
1348 catch_sigabrt(SIGABRT
);
1352 log_write(_("clearing file cache"));
1353 cache_clear(NULL
, 2);
1364 * We're out of the main server loop. This happens when a signal was sent
1365 * to terminate the daemon. We'll wait for all clients to disconnect
1366 * before exiting and ignore any following signals.
1368 shutdown(sockfd
, SHUT_RDWR
);
1370 pth_cancel(accept_tid
);
1371 pth_join(accept_tid
, NULL
);
1372 unlink(*socketpath
);
1373 g_free(*socketpath
);
1375 MUTEX_LOCK(&cn_mutex
);
1376 n
= g_slist_length(cn_thread_list
);
1377 MUTEX_UNLOCK(&cn_mutex
);
1380 log_write(_("waiting for all clients to disconnect"));
1383 MUTEX_LOCK(&cn_mutex
);
1384 n
= g_slist_length(cn_thread_list
);
1385 MUTEX_UNLOCK(&cn_mutex
);
1386 log_write(_("%i clients remain"), n
);
1387 } while (waiting_for_exit());
1390 pth_cancel(cache_timeout_tid
);
1396 * Only called from pinentry_fork() in the child process.
1398 void free_client_list()
1400 gint i
, t
= g_slist_length(cn_thread_list
);
1402 for (i
= 0; i
< t
; i
++) {
1403 struct client_thread_s
*cn
= g_slist_nth_data(cn_thread_list
, i
);
1405 free_client(cn
->cl
);
1411 static guint
pwmd_cipher_to_gcrypt(guint64 flags
)
1413 if (flags
& PWMD_CIPHER_AES128
)
1414 return GCRY_CIPHER_AES128
;
1415 else if (flags
& PWMD_CIPHER_AES192
)
1416 return GCRY_CIPHER_AES192
;
1417 else if (flags
& PWMD_CIPHER_AES256
)
1418 return GCRY_CIPHER_AES256
;
1419 else if (flags
& PWMD_CIPHER_SERPENT128
)
1420 return GCRY_CIPHER_SERPENT128
;
1421 else if (flags
& PWMD_CIPHER_SERPENT192
)
1422 return GCRY_CIPHER_SERPENT192
;
1423 else if (flags
& PWMD_CIPHER_SERPENT256
)
1424 return GCRY_CIPHER_SERPENT256
;
1425 else if (flags
& PWMD_CIPHER_CAMELLIA128
)
1426 return GCRY_CIPHER_CAMELLIA128
;
1427 else if (flags
& PWMD_CIPHER_CAMELLIA192
)
1428 return GCRY_CIPHER_CAMELLIA192
;
1429 else if (flags
& PWMD_CIPHER_CAMELLIA256
)
1430 return GCRY_CIPHER_CAMELLIA256
;
1431 else if (flags
& PWMD_CIPHER_BLOWFISH
)
1432 return GCRY_CIPHER_BLOWFISH
;
1433 else if (flags
& PWMD_CIPHER_3DES
)
1434 return GCRY_CIPHER_3DES
;
1435 else if (flags
& PWMD_CIPHER_CAST5
)
1436 return GCRY_CIPHER_CAST5
;
1437 else if (flags
& PWMD_CIPHER_TWOFISH
)
1438 return GCRY_CIPHER_TWOFISH
;
1439 else if (flags
& PWMD_CIPHER_TWOFISH128
)
1440 return GCRY_CIPHER_TWOFISH128
;
1442 /* For backwards compatibility (no flags). */
1443 return GCRY_CIPHER_AES256
;
1446 guint
pwmd_cipher_str_to_cipher(const gchar
*str
)
1450 if (!g_strcasecmp(str
, "aes128"))
1451 flags
= PWMD_CIPHER_AES128
;
1452 else if (!g_strcasecmp(str
, "aes192"))
1453 flags
= PWMD_CIPHER_AES192
;
1454 else if (!g_strcasecmp(str
, "aes256"))
1455 flags
= PWMD_CIPHER_AES256
;
1456 if (!g_strcasecmp(str
, "serpent128"))
1457 flags
= PWMD_CIPHER_SERPENT128
;
1458 else if (!g_strcasecmp(str
, "serpent192"))
1459 flags
= PWMD_CIPHER_SERPENT192
;
1460 else if (!g_strcasecmp(str
, "serpent256"))
1461 flags
= PWMD_CIPHER_SERPENT256
;
1462 if (!g_strcasecmp(str
, "camellia128"))
1463 flags
= PWMD_CIPHER_CAMELLIA128
;
1464 else if (!g_strcasecmp(str
, "camellia192"))
1465 flags
= PWMD_CIPHER_CAMELLIA192
;
1466 else if (!g_strcasecmp(str
, "camellia256"))
1467 flags
= PWMD_CIPHER_CAMELLIA256
;
1468 else if (!g_strcasecmp(str
, "blowfish"))
1469 flags
= PWMD_CIPHER_BLOWFISH
;
1470 else if (!g_strcasecmp(str
, "cast5"))
1471 flags
= PWMD_CIPHER_CAST5
;
1472 else if (!g_strcasecmp(str
, "3des"))
1473 flags
= PWMD_CIPHER_3DES
;
1474 else if (!g_strcasecmp(str
, "twofish256"))
1475 flags
= PWMD_CIPHER_TWOFISH
;
1476 else if (!g_strcasecmp(str
, "twofish128"))
1477 flags
= PWMD_CIPHER_TWOFISH128
;
1482 const gchar
*pwmd_cipher_to_str(guint64 flags
)
1484 if (flags
& PWMD_CIPHER_AES128
)
1486 else if (flags
& PWMD_CIPHER_AES192
)
1488 else if (flags
& PWMD_CIPHER_AES256
)
1490 else if (flags
& PWMD_CIPHER_SERPENT128
)
1491 return "serpent128";
1492 else if (flags
& PWMD_CIPHER_SERPENT192
)
1493 return "serpent192";
1494 else if (flags
& PWMD_CIPHER_SERPENT256
)
1495 return "serpent256";
1496 else if (flags
& PWMD_CIPHER_CAMELLIA128
)
1497 return "camellia128";
1498 else if (flags
& PWMD_CIPHER_CAMELLIA192
)
1499 return "camellia192";
1500 else if (flags
& PWMD_CIPHER_CAMELLIA256
)
1501 return "camellia256";
1502 else if (flags
& PWMD_CIPHER_BLOWFISH
)
1504 else if (flags
& PWMD_CIPHER_CAST5
)
1506 else if (flags
& PWMD_CIPHER_3DES
)
1508 else if (flags
& PWMD_CIPHER_TWOFISH
)
1509 return "twofish256";
1510 else if (flags
& PWMD_CIPHER_TWOFISH128
)
1511 return "twofish128";
1516 /* To be called after read_file_header(). This sets the wanted algorithm from
1518 gpg_error_t
init_client_crypto2(const char *filename
,
1519 struct crypto_s
*crypto
)
1524 /* New file or conversion. */
1526 algo
= pwmd_cipher_to_gcrypt(PWMD_CIPHER_AES256
);
1527 else if (!crypto
->fh
->ver
.fh2
.flags
) {
1528 gchar
*tmp
= get_key_file_string(filename
? filename
: "global", "cipher");
1531 flags
= pwmd_cipher_str_to_cipher(tmp
);
1533 algo
= pwmd_cipher_to_gcrypt(flags
);
1534 crypto
->fh
->ver
.fh2
.flags
= flags
;
1537 algo
= pwmd_cipher_to_gcrypt(crypto
->fh
->ver
.fh2
.flags
);
1539 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_TEST_ALGO
, NULL
, NULL
);
1544 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_KEYLEN
, NULL
,
1550 rc
= gcry_cipher_algo_info(algo
, GCRYCTL_GET_BLKLEN
, NULL
,
1551 &crypto
->blocksize
);
1557 gcry_cipher_close(crypto
->gh
);
1559 return gcry_cipher_open(&crypto
->gh
, algo
, GCRY_CIPHER_MODE_CBC
, 0);
1562 struct crypto_s
*init_client_crypto()
1564 struct crypto_s
*new = g_malloc0(sizeof(struct crypto_s
));
1567 log_write("%s(%i): %s", __FILE__
, __LINE__
, pwmd_strerror(GPG_ERR_ENOMEM
));
1574 static gpg_error_t
convert_file(const gchar
*filename
, const gchar
*keyfile
,
1575 const gchar
*outfile
)
1578 guchar md5file
[gcry_md_get_algo_dlen(GCRY_MD_MD5
)];
1580 struct crypto_s
*crypto
= init_client_crypto();
1581 guint hashlen
= gcry_md_get_algo_dlen(GCRY_MD_SHA256
);
1584 return GPG_ERR_ENOMEM
;
1586 crypto
->key
= gcry_malloc(hashlen
);
1589 cleanup_crypto(&crypto
);
1590 return GPG_ERR_ENOMEM
;
1593 log_write(_("Converting version 1 data file '%s' to version 2 ..."),
1595 crypto
->fh
= read_file_header(filename
, TRUE
, &rc
);
1600 gcry_md_hash_buffer(GCRY_MD_MD5
, md5file
, filename
, strlen(filename
));
1602 /* The header in version 1 had a bug where the iterations were off-by-one.
1603 * So 0 iterations was really -1 in the header. This is fixed in v2 of the
1606 if (crypto
->fh
->ver
.fh1
.iter
!= -1) {
1608 rc
= parse_rcfile_keyfile(crypto
, keyfile
, TRUE
);
1613 gcry_md_hash_buffer(GCRY_MD_SHA256
, crypto
->key
, crypto
->tkey
,
1615 gcry_free(crypto
->tkey
);
1616 crypto
->tkey
= NULL
;
1619 rc
= get_password(filename
, crypto
, md5file
, crypto
->key
,
1627 rc
= init_client_crypto2(NULL
, crypto
);
1632 rc
= try_xml_decrypt(NULL
, crypto
, &crypto
->fh
->doc
, &crypto
->fh
->len
);
1637 rc
= convert_xml((gchar
**)&crypto
->fh
->doc
, &crypto
->fh
->len
);
1640 log_write("%s: %s", filename
, pwmd_strerror(rc
));
1644 crypto
->fh
->v1
= FALSE
;
1646 iter
= crypto
->fh
->ver
.fh1
.iter
+1;
1647 memset(&crypto
->fh
->ver
.fh2
, 0, sizeof(crypto
->fh
->ver
.fh2
));
1648 /* Keep the iterations and key from the original file. */
1649 crypto
->fh
->ver
.fh2
.iter
= iter
;
1650 rc
= export_common(outfile
, crypto
, crypto
->fh
->doc
, crypto
->fh
->len
);
1654 send_error(NULL
, rc
);
1656 /* fh->doc is freed from do_xml_decrypt() via the inbuf pointer. */
1657 cleanup_crypto(&crypto
);
1661 static void startup_failure()
1663 log_write(_("Failed to add a file to the cache. Use --ignore to force startup. Exiting."));
1664 cache_clear(NULL
, 2);
1667 int main(int argc
, char *argv
[])
1669 struct sockaddr_un addr
;
1670 gchar buf
[PATH_MAX
];
1671 gchar
*socketpath
= NULL
, *socketdir
, *socketname
= NULL
;
1672 gchar
*socketarg
= NULL
;
1673 gchar
*datadir
= NULL
;
1676 gchar
**cache_push
= NULL
;
1677 gchar
*import
= NULL
, *keyfile
= NULL
;
1678 gint64 cmd_iterations
= -1;
1679 gboolean rcfile_spec
= FALSE
;
1680 gint estatus
= EXIT_FAILURE
;
1682 gchar
*outfile
= NULL
;
1683 GMemVTable mtable
= { xmalloc
, xrealloc
, xfree
, xcalloc
, NULL
, NULL
};
1685 gboolean secure
= FALSE
;
1686 gboolean nofork
= FALSE
;
1687 gchar
*convert
= NULL
;
1688 gint show_version
= 0;
1689 gboolean force
= FALSE
;
1690 #ifdef WITH_PINENTRY
1691 gboolean disable_pinentry
= FALSE
;
1693 GError
*error
= NULL
;
1694 GOptionContext
*context
;
1695 GOptionEntry options
[] =
1697 #ifdef WITH_PINENTRY
1698 { "no-pinentry", 'P', 0, G_OPTION_ARG_NONE
, &disable_pinentry
,
1699 "disable pinentry", NULL
},
1701 { "version", 0, 0, G_OPTION_ARG_NONE
, &show_version
,
1702 "version information", NULL
},
1703 { "no-fork", 'n', 0, G_OPTION_ARG_NONE
, &nofork
,
1704 "run as a foreground process", NULL
},
1705 { "disable-dump", 'D', 0, G_OPTION_ARG_NONE
, &secure
,
1706 "disable the LIST, XPATH and DUMP commands", NULL
},
1707 { "rcfile", 'f', 0, G_OPTION_ARG_FILENAME
, &rcfile
,
1708 "load the specified rcfile (~/.pwmd/config)", "filename" },
1709 { "ignore", 0, 0, G_OPTION_ARG_NONE
, &force
,
1710 "ignore cache failures on startup", NULL
},
1711 { "outfile", 'o', 0, G_OPTION_ARG_FILENAME
, &outfile
,
1712 "output file when importing (- for stdout)", "filename" },
1713 { "convert", 'C', 0, G_OPTION_ARG_FILENAME
, &convert
,
1714 "convert a version 1 data file to version 2", "filename" },
1715 { "key-file", 'k', 0, G_OPTION_ARG_FILENAME
, &keyfile
,
1716 "for decryption when converting", "filename" },
1717 { "import", 'I', 0, G_OPTION_ARG_FILENAME
, &import
,
1718 "import an XML file", "filename" },
1719 { "iterations", 'i', 0, G_OPTION_ARG_INT64
, &cmd_iterations
,
1720 "when importing or converting", "N" },
1725 #ifdef HAVE_SETRLIMIT
1728 rl
.rlim_cur
= rl
.rlim_max
= 0;
1730 if (setrlimit(RLIMIT_CORE
, &rl
) != 0)
1731 err(EXIT_FAILURE
, "setrlimit()");
1737 setlocale(LC_ALL
, "");
1738 bindtextdomain("pwmd", LOCALEDIR
);
1748 assuan_set_assuan_err_source(GPG_ERR_SOURCE_DEFAULT
);
1749 g_mem_set_vtable(&mtable
);
1750 assuan_set_malloc_hooks(g_malloc
, g_realloc
, g_free
);
1751 xmlMemSetup(g_free
, g_malloc
, g_realloc
, g_strdup
);
1756 g_snprintf(buf
, sizeof(buf
), "%s/.pwmd", g_get_home_dir());
1758 if (mkdir(buf
, 0700) == -1 && errno
!= EEXIST
)
1759 err(EXIT_FAILURE
, "%s", buf
);
1761 g_snprintf(buf
, sizeof(buf
), "%s/.pwmd/data", g_get_home_dir());
1763 if (mkdir(buf
, 0700) == -1 && errno
!= EEXIST
)
1764 err(EXIT_FAILURE
, "%s", buf
);
1767 context
= g_option_context_new("- Password Manager Daemon");
1768 g_option_context_add_main_entries(context
, options
, NULL
);
1769 if (!g_option_context_parse(context
, &argc
, &argv
, &error
))
1771 g_print("Option parsing failed: %s\n", error
->message
);
1776 printf(_("%s\nCopyright (C) 2006-2011 %s\nReleased under the terms of the GPL v2. Use at your own risk.\n\nCompile time features:\n%s"), PACKAGE_STRING
,
1778 #ifdef WITH_PINENTRY
1812 pth_mutex_init(&cn_mutex
);
1813 pth_mutex_init(&cache_mutex
);
1814 pth_mutex_init(&rcfile_mutex
);
1815 #ifdef WITH_PINENTRY
1816 pth_mutex_init(&pin_mutex
);
1820 rcfile
= g_strdup_printf("%s/.pwmd/config", g_get_home_dir());
1822 if ((keyfileh
= parse_rcfile(rcfile_spec
)) == NULL
)
1825 #ifdef WITH_PINENTRY
1826 if (disable_pinentry
== TRUE
)
1827 g_key_file_set_boolean(keyfileh
, "global", "enable_pinentry", FALSE
);
1830 if (g_key_file_has_key(keyfileh
, "global", "syslog", NULL
) == TRUE
)
1831 log_syslog
= g_key_file_get_boolean(keyfileh
, "global", "syslog", NULL
);
1833 if (log_syslog
== TRUE
)
1834 openlog("pwmd", LOG_NDELAY
|LOG_PID
, LOG_DAEMON
);
1836 if (g_key_file_has_key(keyfileh
, "global", "priority", NULL
)) {
1837 n
= g_key_file_get_integer(keyfileh
, "global", "priority", NULL
);
1840 if (setpriority(PRIO_PROCESS
, 0, n
) == -1) {
1841 log_write("setpriority(): %s", pwmd_strerror(gpg_error_from_syserror()));
1846 #ifdef HAVE_MLOCKALL
1847 if (disable_mlock
== FALSE
&& mlockall(MCL_CURRENT
|MCL_FUTURE
) == -1) {
1848 log_write("mlockall(): %s", pwmd_strerror(gpg_error_from_syserror()));
1855 gchar
*tmp
= g_option_context_get_help(context
, TRUE
, NULL
);
1857 fprintf(stderr
, "%s", tmp
);
1862 n
= convert_file(convert
, keyfile
, outfile
);
1863 g_key_file_free(keyfileh
);
1865 exit(n
? EXIT_FAILURE
: EXIT_SUCCESS
);
1870 gchar
*tmp
= g_option_context_get_help(context
, TRUE
, NULL
);
1872 fprintf(stderr
, "%s", tmp
);
1877 if (cmd_iterations
== -1)
1878 cmd_iterations
= get_key_file_uint64("global", "iterations");
1880 gboolean b
= xml_import(import
, outfile
, keyfile
, cmd_iterations
);
1881 g_key_file_free(keyfileh
);
1883 exit(!b
? EXIT_FAILURE
: EXIT_SUCCESS
);
1886 g_option_context_free(context
);
1888 if ((p
= g_key_file_get_string(keyfileh
, "global", "socket_path", NULL
)) == NULL
)
1889 errx(EXIT_FAILURE
, _("%s: socket_path not defined"), rcfile
);
1891 socketarg
= expand_homedir(p
);
1894 if ((p
= g_key_file_get_string(keyfileh
, "global", "data_directory", NULL
)) == NULL
)
1895 errx(EXIT_FAILURE
, _("%s: data_directory not defined"), rcfile
);
1897 datadir
= expand_homedir(p
);
1900 if (secure
== FALSE
&& g_key_file_has_key(keyfileh
, "global", "disable_list_and_dump", NULL
) == TRUE
) {
1901 n
= g_key_file_get_boolean(keyfileh
, "global", "disable_list_and_dump", NULL
);
1902 disable_list_and_dump
= n
;
1905 disable_list_and_dump
= secure
;
1907 setup_logging(keyfileh
);
1909 if (g_key_file_has_key(keyfileh
, "global", "cache_push", NULL
) == TRUE
)
1910 cache_push
= g_key_file_get_string_list(keyfileh
, "global", "cache_push", NULL
, NULL
);
1912 for (n
= 1; n
< argc
; n
++) {
1913 if (strv_printf(&cache_push
, "%s", argv
[n
]) == FALSE
)
1914 errx(EXIT_FAILURE
, "%s", pwmd_strerror(GPG_ERR_ENOMEM
));
1917 if (strchr(socketarg
, '/') == NULL
) {
1918 socketdir
= g_get_current_dir();
1919 socketname
= g_strdup(socketarg
);
1920 socketpath
= g_strdup_printf("%s/%s", socketdir
, socketname
);
1923 socketname
= g_strdup(strrchr(socketarg
, '/'));
1925 socketarg
[strlen(socketarg
) - strlen(socketname
) -1] = 0;
1926 socketdir
= g_strdup(socketarg
);
1927 socketpath
= g_strdup_printf("%s/%s", socketdir
, socketname
);
1930 if (chdir(datadir
)) {
1931 log_write("%s: %s", datadir
, pwmd_strerror(gpg_error_from_syserror()));
1936 if (parse_rcfile_keys(!force
) == FALSE
) {
1938 estatus
= EXIT_FAILURE
;
1942 clear_rcfile_keys();
1945 * Set the cache entry for a file. Prompts for the password.
1948 for (n
= 0; cache_push
[n
]; n
++) {
1949 if (!do_cache_push(cache_push
[n
], NULL
, 0) && !force
) {
1950 g_strfreev(cache_push
);
1952 estatus
= EXIT_FAILURE
;
1957 g_strfreev(cache_push
);
1958 log_write(!nofork
? _("Done. Daemonizing...") : _("Done. Waiting for connections..."));
1962 * bind() doesn't like the full pathname of the socket or any non alphanum
1963 * characters so change to the directory where the socket is wanted then
1964 * create it then change to datadir.
1966 if (chdir(socketdir
)) {
1967 log_write("%s: %s", socketdir
, pwmd_strerror(gpg_error_from_syserror()));
1973 if ((sockfd
= socket(PF_UNIX
, SOCK_STREAM
, 0)) == -1) {
1974 log_write("socket(): %s", pwmd_strerror(gpg_error_from_syserror()));
1978 addr
.sun_family
= AF_UNIX
;
1979 g_snprintf(addr
.sun_path
, sizeof(addr
.sun_path
), "%s", socketname
);
1981 if (bind(sockfd
, (struct sockaddr
*)&addr
, sizeof(struct sockaddr
)) == -1) {
1982 log_write("bind(): %s", pwmd_strerror(gpg_error_from_syserror()));
1984 if (errno
== EADDRINUSE
)
1985 log_write(_("Either there is another pwmd running or '%s' is a \n"
1986 "stale socket. Please remove it manually."), socketpath
);
1992 if (g_key_file_has_key(keyfileh
, "global", "socket_perms", NULL
) == TRUE
) {
1993 gchar
*t
= g_key_file_get_string(keyfileh
, "global", "socket_perms", NULL
);
1994 mode_t mode
= strtol(t
, NULL
, 8);
1995 mode_t mask
= umask(0);
1999 if (chmod(socketname
, mode
) == -1) {
2000 log_write("%s: %s", socketname
, pwmd_strerror(gpg_error_from_syserror()));
2010 g_free(--socketname
);
2012 if (chdir(datadir
)) {
2013 log_write("%s: %s", datadir
, pwmd_strerror(gpg_error_from_syserror()));
2021 if (listen(sockfd
, 0) == -1) {
2022 log_write("listen(): %s", pwmd_strerror(gpg_error_from_syserror()));
2027 unsetenv("DISPLAY");
2033 log_write("fork(): %s", pwmd_strerror(gpg_error_from_syserror()));
2042 _exit(EXIT_SUCCESS
);
2046 server_loop(sockfd
, &socketpath
);
2047 estatus
= EXIT_SUCCESS
;
2050 if (socketpath
&& do_unlink
) {
2056 g_key_file_free(keyfileh
);
2059 xmlCleanupGlobals();
2061 if (estatus
== EXIT_SUCCESS
)
2062 log_write(_("pwmd exiting normally"));
2064 #if defined(DEBUG) && !defined(MEM_DEBUG)