2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015,
4 Ben Kibbey <bjk@luxsci.net>
6 This file is part of libpwmd.
8 Libpwmd 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 Libpwmd 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 Libpwmd. If not, see <http://www.gnu.org/licenses/>.
32 #include <sys/types.h>
33 #include <sys/socket.h>
43 #include <sys/select.h>
67 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
68 #include <sys/types.h>
69 #include <sys/socket.h>
71 #include <netinet/in.h>
74 #define FINISH(rc) (gpg_err_source(rc) == GPG_ERR_SOURCE_UNKNOWN) \
83 static gpg_error_t
status_cb (void *data
, const char *line
);
86 hook_read (assuan_context_t ctx
, assuan_fd_t fd
, void *data
, size_t len
)
88 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
89 pwm_t
*pwm
= assuan_get_pointer (ctx
);
92 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->ssh
)
93 return read_hook_ssh (pwm
->tcp
->ssh
, fd
, data
, len
);
96 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->tls
)
97 return tls_read_hook (pwm
, fd
, data
, len
);
103 return read ((int) fd
, data
, len
);
107 hook_write (assuan_context_t ctx
, assuan_fd_t fd
, const void *data
,
111 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
112 pwm_t
*pwm
= assuan_get_pointer (ctx
);
115 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->ssh
)
116 return write_hook_ssh (pwm
->tcp
->ssh
, fd
, data
, len
);
119 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->tls
)
120 return tls_write_hook (pwm
, fd
, data
, len
);
126 /* libassuan cannot handle EAGAIN when doing writes. */
129 wrote
= write ((int) fd
, data
, len
);
130 if (wrote
== -1 && errno
== EAGAIN
)
133 while (wrote
== -1 && errno
== EAGAIN
);
139 hook_waitpid (assuan_context_t ctx
, pid_t pid
, int action
, int *status
,
144 return waitpid (pid
, status
, options
);
150 static int initialized
;
153 // May be called more than once.
154 gnutls_global_init ();
161 bindtextdomain ("libpwmd", LOCALEDIR
);
167 //gpgrt_set_alloc_func (_xrealloc_gpgrt);
181 gnutls_global_deinit ();
189 _connect_finalize (pwm_t
* pwm
)
194 int n
= assuan_get_active_fds (pwm
->ctx
, 0, active
, N_ARRAY (active
));
197 return GPG_ERR_EBADFD
;
201 pwm
->pinentry_pid
= -1;
204 rc
= pwmd_command (pwm
, &result
, NULL
, NULL
, NULL
, "GETINFO VERSION");
207 pwm
->version
= strtoul (result
, NULL
, 16);
211 if (!rc
&& pwm
->name
)
212 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION NAME=%s",
219 connect_uds (pwm_t
* pwm
, const char *path
)
221 char *socketpath
= NULL
;
227 return GPG_ERR_INV_ARG
;
229 pwbuf
= _getpwuid (&pw
);
231 return gpg_error_from_syserror ();
234 socketpath
= pwmd_strdup_printf ("%s/.pwmd/socket", pw
.pw_dir
);
236 socketpath
= _expand_homedir ((char *) path
, &pw
);
240 return GPG_ERR_ENOMEM
;
242 rc
= assuan_socket_connect (pwm
->ctx
, socketpath
, ASSUAN_INVALID_FD
, 0);
243 pwmd_free (socketpath
);
244 return rc
? rc
: _connect_finalize (pwm
);
248 init_handle (pwm_t
* pwm
)
251 static struct assuan_malloc_hooks mhooks
= {
252 pwmd_malloc
, pwmd_realloc
, pwmd_free
254 static struct assuan_system_hooks shooks
= {
255 ASSUAN_SYSTEM_HOOKS_VERSION
,
263 NULL
, //sendmsg both are used for FD passing
271 rc
= assuan_new_ext (&pwm
->ctx
, GPG_ERR_SOURCE_DEFAULT
, &mhooks
, NULL
,
276 assuan_set_pointer (pwm
->ctx
, pwm
);
277 assuan_ctx_set_system_hooks (pwm
->ctx
, &shooks
);
281 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
283 free_tcp (pwm_t
*pwm
)
285 struct tcp_s
*tcp
= pwm
->tcp
;
291 _free_ssh_conn (tcp
->ssh
);
297 pwmd_free (tcp
->host
);
300 freeaddrinfo (tcp
->addrs
);
304 pthread_cond_destroy (&tcp
->dns_cond
);
305 pthread_mutex_destroy (&tcp
->dns_mutex
);
311 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
313 resolve_host_thread (void *arg
)
316 struct addrinfo hints
= { 0 };
322 hints
.ai_family
= AF_UNSPEC
;
325 hints
.ai_family
= AF_INET
;
328 hints
.ai_family
= AF_INET6
;
332 hints
.ai_socktype
= SOCK_STREAM
;
333 snprintf (portstr
, sizeof (portstr
), "%i", pwm
->tcp
->port
);
334 int *n
= pwmd_malloc (sizeof (int));
335 pthread_cleanup_push (pwmd_free
, n
);
336 *n
= getaddrinfo (pwm
->tcp
->host
, portstr
, &hints
, &pwm
->tcp
->addrs
);
337 pthread_cleanup_pop (0);
338 pthread_cond_broadcast (&pwm
->tcp
->dns_cond
);
344 tcp_connect_common (pwm_t
* pwm
)
346 #define TS_TIMEOUT 50000000L
353 n
= pthread_create (&tid
, NULL
, resolve_host_thread
, pwm
);
355 return gpg_error_from_errno (n
);
357 pthread_mutex_lock (&pwm
->tcp
->dns_mutex
);
364 clock_gettime (CLOCK_REALTIME
, &ts
);
365 if (ts
.tv_nsec
+ TS_TIMEOUT
>= 1000000000LL) {
370 ts
.tv_nsec
+= TS_TIMEOUT
;
374 #ifdef HAVE_PTHREAD_CANCEL
375 pthread_cancel (tid
);
376 pthread_join (tid
, NULL
);
378 pthread_join (tid
, (void **)&result
);
381 return GPG_ERR_CANCELED
;
384 n
= pthread_cond_timedwait (&pwm
->tcp
->dns_cond
, &pwm
->tcp
->dns_mutex
,
388 if (pwm
->socket_timeout
&& ts
.tv_sec
- now
>= pwm
->socket_timeout
)
390 #ifdef HAVE_PTHREAD_CANCEL
391 pthread_cancel (tid
);
392 pthread_join (tid
, NULL
);
394 pthread_join (tid
, (void **)&result
);
397 return GPG_ERR_ETIMEDOUT
;
404 #ifdef HAVE_PTHREAD_CANCEL
405 pthread_cancel (tid
);
406 pthread_join (tid
, NULL
);
408 pthread_join (tid
, (void **)&result
);
411 return gpg_error_from_errno (n
);
414 pthread_join (tid
, (void **)&result
);
421 return GPG_ERR_UNKNOWN_HOST
; //FIXME
423 for (pwm
->tcp
->addr
= pwm
->tcp
->addrs
; pwm
->tcp
->addr
;
424 pwm
->tcp
->addr
= pwm
->tcp
->addrs
->ai_next
)
426 pwm
->fd
= socket (pwm
->tcp
->addr
->ai_family
, SOCK_STREAM
, 0);
429 rc
= gpg_error_from_syserror ();
430 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
)
435 if (fcntl (pwm
->fd
, F_SETFL
, O_NONBLOCK
) == -1)
437 rc
= gpg_error_from_syserror ();
441 if (connect (pwm
->fd
, pwm
->tcp
->addr
->ai_addr
,
442 pwm
->tcp
->addr
->ai_family
== AF_INET6
443 ? sizeof (struct sockaddr_in6
)
444 : sizeof (struct sockaddr
)) == -1)
448 unsigned elapsed
= 0;
450 rc
= gpg_error_from_syserror ();
451 if (gpg_err_code (rc
) != GPG_ERR_EINPROGRESS
)
455 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
)
464 FD_SET (pwm
->fd
, &wfds
);
465 n
= select (pwm
->fd
+1, NULL
, &wfds
, NULL
, &tv
);
467 if (!n
|| pwm
->cancel
)
470 rc
= gpg_error (GPG_ERR_CANCELED
);
471 else if (++elapsed
>= pwm
->socket_timeout
)
472 rc
= gpg_error (GPG_ERR_ETIMEDOUT
);
478 socklen_t len
= sizeof(int);
480 getsockopt (pwm
->fd
, SOL_SOCKET
, SO_ERROR
, &n
, &len
);
482 rc
= gpg_error_from_errno (n
);
485 rc
= gpg_error_from_syserror ();
491 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
492 || gpg_err_code (rc
) == GPG_ERR_ETIMEDOUT
504 if (fcntl (pwm
->fd
, F_SETFL
, 0) == -1)
505 rc
= gpg_error_from_syserror ();
512 command_start (pwm_t
*pwm
)
518 pwmd_connect (pwm_t
* pwm
, const char *url
, ...)
524 return FINISH (GPG_ERR_INV_ARG
);
527 rc
= init_handle (pwm
);
534 if (!(pwm
->opts
& OPT_SIGPIPE
))
535 signal (SIGPIPE
, SIG_IGN
);
540 rc
= GPG_ERR_UNSUPPORTED_PROTOCOL
;
542 if (p
&& (*p
== '/' || *p
== '~'))
543 rc
= connect_uds (pwm
, p
);
544 else if (!p
|| !strncmp (p
, "file://", 7))
548 #ifdef DEFAULT_PWMD_SOCKET
550 p
= DEFAULT_PWMD_SOCKET
;
552 rc
= connect_uds (pwm
, p
);
554 else if (!strncmp (p
, "ssh://", 6) || !strncmp (p
, "ssh6://", 7) ||
555 !strncmp (p
, "ssh4://", 7))
558 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
562 char *username
= NULL
;
564 if (!strncmp (p
, "ssh6://", 7))
566 pwm
->prot
= PWMD_IPV6
;
569 else if (!strncmp (p
, "ssh4://", 7))
571 pwm
->prot
= PWMD_IPV4
;
576 pwm
->prot
= PWMD_IP_ANY
;
580 rc
= _parse_ssh_url (p
, &host
, &port
, &username
);
584 char *identity
= NULL
;
585 char *knownhosts
= NULL
;
588 identity
= va_arg (ap
, char *);
590 if (!identity
&& !pwm
->use_agent
)
591 rc
= GPG_ERR_INV_ARG
;
593 knownhosts
= va_arg (ap
, char *);
598 rc
= _do_ssh_connect (pwm
, host
, port
, identity
, username
,
602 rc
= _connect_finalize (pwm
);
609 pwmd_free (username
);
610 pwm
->local_pinentry
= 1;
611 pwmd_free (pwm
->ssh_passphrase
);
612 pwm
->ssh_passphrase
= NULL
;
615 else if (!strncmp (p
, "tls://", 6) || !strncmp (p
, "tls6://", 7) ||
616 !strncmp (p
, "tls4://", 7))
619 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
624 if (!strncmp (p
, "tls6://", 7))
626 pwm
->prot
= PWMD_IPV6
;
629 else if (!strncmp (p
, "tls4://", 7))
631 pwm
->prot
= PWMD_IPV4
;
636 pwm
->prot
= PWMD_IP_ANY
;
640 rc
= tls_parse_url (p
, &host
, &port
);
644 char *clientcert
= NULL
;
645 char *clientkey
= NULL
;
647 char *server_fp
= NULL
;
650 clientcert
= va_arg (ap
, char *);
653 rc
= GPG_ERR_INV_ARG
;
656 clientkey
= va_arg (ap
, char *);
658 rc
= GPG_ERR_INV_ARG
;
661 cacert
= va_arg (ap
, char *);
663 rc
= GPG_ERR_INV_ARG
;
665 server_fp
= va_arg (ap
, char *);
672 rc
= tls_connect (pwm
, host
, port
, clientcert
, clientkey
, cacert
,
673 pwm
->tls_priority
, server_fp
, pwm
->tls_verify
);
676 rc
= _connect_finalize (pwm
);
683 pwm
->local_pinentry
= 1;
694 disconnect (pwm_t
* pwm
)
700 assuan_release (pwm
->ctx
);
702 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
711 pwmd_close (pwm_t
* pwm
)
717 pwmd_free (pwm
->pinentry_error
);
718 pwmd_free (pwm
->pinentry_desc
);
719 pwmd_free (pwm
->pinentry_prompt
);
720 pwmd_free (pwm
->pinentry_tty
);
721 pwmd_free (pwm
->pinentry_display
);
722 pwmd_free (pwm
->pinentry_term
);
723 pwmd_free (pwm
->pinentry_lcctype
);
724 pwmd_free (pwm
->pinentry_lcmessages
);
725 pwmd_free (pwm
->filename
);
726 pwmd_free (pwm
->name
);
727 pwmd_free (pwm
->passphrase_info
);
728 pwmd_free (pwm
->passphrase_hint
);
729 pwmd_free (pwm
->ssh_passphrase
);
730 pwmd_free (pwm
->tls_priority
);
734 _pinentry_disconnect (pwm
);
741 inquire_realloc_cb (void *data
, const void *buffer
, size_t len
)
743 membuf_t
*mem
= (membuf_t
*) data
;
749 if ((p
= pwmd_realloc (mem
->buf
, mem
->len
+ len
)) == NULL
)
750 return gpg_error (GPG_ERR_ENOMEM
);
753 memcpy ((char *) mem
->buf
+ mem
->len
, buffer
, len
);
759 get_password (pwm_t
* pwm
, char **result
, size_t * len
,
760 pwmd_pinentry_t w
, int echo
)
762 char buf
[ASSUAN_LINELENGTH
+1] = { 0 }, *p
;
763 struct termios told
, tnew
;
772 if (!isatty (STDIN_FILENO
))
774 fprintf (stderr
, N_("Input is not from a terminal! Failing.\n"));
775 return GPG_ERR_ENOTTY
;
780 if (tcgetattr (STDIN_FILENO
, &told
) == -1)
781 return gpg_error_from_syserror ();
783 memcpy (&tnew
, &told
, sizeof (struct termios
));
784 tnew
.c_lflag
&= ~(ECHO
);
785 tnew
.c_lflag
|= ICANON
| ECHONL
;
787 if (tcsetattr (STDIN_FILENO
, TCSANOW
, &tnew
) == -1)
791 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
792 return gpg_error_from_errno (n
);
796 if (pwm
->passphrase_hint
)
797 fprintf(stderr
, N_("Key info: %s\n"), pwm
->passphrase_hint
);
801 case PWMD_PINENTRY_OPEN
:
802 fprintf (stderr
, N_("Passphrase for %s: "), pwm
->filename
);
804 case PWMD_PINENTRY_OPEN_FAILED
:
805 fprintf (stderr
, N_("Invalid passphrase. Passphrase for %s: "),
808 case PWMD_PINENTRY_SAVE
:
809 fprintf (stderr
, N_("New passphrase for %s: "), pwm
->filename
);
811 case PWMD_PINENTRY_SAVE_CONFIRM
:
812 fprintf (stderr
, N_("Repeat passphrase: "));
814 case PWMD_PINENTRY_CONFIRM
:
815 if (pwm
->pinentry_desc
)
816 fprintf (stderr
, "%s", pwm
->pinentry_desc
);
818 if (pwm
->pinentry_prompt
)
819 fprintf (stderr
, "%s", pwm
->pinentry_prompt
);
821 fprintf(stderr
, N_("Confirm [y/N]:"));
826 p
= fgets (buf
, sizeof (buf
), stdin
);
829 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
831 if (!p
|| feof (stdin
))
834 return GPG_ERR_CANCELED
;
837 /* Strip the newline character. */
838 p
[strlen (p
) - 1] = 0;
842 if (w
== PWMD_PINENTRY_CONFIRM
)
844 if (*p
!= 'y' && *p
!= 'Y')
845 return GPG_ERR_CANCELED
;
849 key
= pwmd_strdup_printf ("%s", p
);
850 wipememory (buf
, 0, sizeof (buf
));
852 return GPG_ERR_ENOMEM
;
862 if (w
== PWMD_PINENTRY_CONFIRM
)
863 return GPG_ERR_CANCELED
;
865 /* To satisfy inquire_cb(). */
867 *result
= pwmd_strdup ("");
877 pwmd_password (pwm_t
* pwm
, const char *keyword
, char **data
, size_t * size
)
880 int new_password
= 0;
881 char *password
= NULL
, *newpass
= NULL
;
892 if (!strcmp (keyword
, "NEW_PASSPHRASE"))
895 if (!new_password
&& pwm
->pinentry_try
)
899 if (pwm
->disable_pinentry
)
901 rc
= get_password (pwm
, &password
, size
,
902 new_password
? PWMD_PINENTRY_SAVE
:
903 error
? PWMD_PINENTRY_OPEN_FAILED
:
904 PWMD_PINENTRY_OPEN
, 0);
905 if (!rc
&& new_password
)
906 rc
= get_password (pwm
, &newpass
, size
, PWMD_PINENTRY_SAVE_CONFIRM
,
911 pwmd_pinentry_t which
;
915 ? PWMD_PINENTRY_SAVE_FAILED
: PWMD_PINENTRY_OPEN_FAILED
;
917 which
= new_password
? PWMD_PINENTRY_SAVE
: PWMD_PINENTRY_OPEN
;
919 rc
= pwmd_getpin (pwm
, pwm
->filename
, &password
, size
, which
);
920 if (!rc
&& new_password
)
921 rc
= pwmd_getpin (pwm
, pwm
->filename
, &newpass
, size
,
922 PWMD_PINENTRY_SAVE_CONFIRM
);
925 if (!rc
&& new_password
)
927 if ((!password
&& newpass
) || (!newpass
&& password
)
928 || (newpass
&& password
&& strcmp (newpass
, password
)))
930 if (pwm
->disable_pinentry
)
931 fprintf (stderr
, N_("Passphrases do not match.\n"));
933 pwmd_free (password
);
935 password
= newpass
= NULL
;
941 (void) pwmd_getpin (pwm
, pwm
->filename
, NULL
, NULL
, PWMD_PINENTRY_CLOSE
);
946 pwmd_free (password
);
952 inquire_cb (void *data
, const char *keyword
)
954 pwm_t
*pwm
= (pwm_t
*) data
;
959 int new_password
= 0;
961 if (!strcmp (keyword
, "PASSPHRASE") || !strcmp (keyword
, "SIGN_PASSPHRASE"))
963 else if (!strcmp (keyword
, "NEW_PASSPHRASE") || !strcmp (keyword
, "GENKEY"))
966 /* Shouldn't get this far without a callback. */
967 if (!pwm
->override_inquire
&& !pwm
->inquire_func
968 && !is_password
&& !new_password
)
969 return gpg_error (GPG_ERR_ASS_NO_INQUIRE_CB
);
978 if (!pwm
->override_inquire
&& (is_password
|| new_password
))
981 rc
= pwmd_password (data
, keyword
, &result
, &len
);
986 rc
= pwm
->inquire_func (pwm
->inquire_data
, keyword
, rc
, &result
,
989 /* gpg will truncate a passphrase at the first nil byte which may be bad
990 * for generated key files. */
991 if ((!rc
|| gpg_err_code (rc
) == GPG_ERR_EOF
)
992 && (is_password
|| new_password
))
994 if (len
&& result
&& *result
)
996 for (size_t n
= 0; n
< len
; n
++)
998 if (result
[n
] == 0 && n
+1 != len
)
999 rc
= GPG_ERR_INV_PASSPHRASE
;
1005 if (rc
&& gpg_err_code (rc
) != GPG_ERR_EOF
)
1007 #ifndef LIBASSUAN_2_1_0
1008 gpg_error_t trc
= rc
;
1010 /* Cancel this inquire. */
1011 rc
= assuan_send_data (pwm
->ctx
, NULL
, 1);
1017 /* There is a bug (or feature?) in assuan_send_data() that
1018 * when cancelling an inquire the next read from the server is
1019 * not done until the next command making the next command
1020 * fail with GPG_ERR_ASS_UNEXPECTED_CMD.
1022 rc
= assuan_read_line (pwm
->ctx
, &line
, &len
);
1024 /* Restore the original error. This differs from the error
1025 * returned from the pwmd command (GPG_ERR_CANCELED). This
1026 * error is returned to the calling function.
1035 if (gpg_err_code (rc
) == GPG_ERR_EOF
|| !rc
)
1037 if (len
<= 0 && !result
)
1042 else if ((len
<= 0 && result
) || (len
&& !result
))
1044 rc
= gpg_error (GPG_ERR_INV_ARG
);
1048 if (pwm
->inquire_maxlen
1049 && pwm
->inquire_sent
+ len
> pwm
->inquire_maxlen
)
1051 rc
= gpg_error (GPG_ERR_TOO_LARGE
);
1053 rc
= pwm
->inquire_func (pwm
->inquire_data
, keyword
, rc
,
1058 arc
= assuan_send_data (pwm
->ctx
, result
, len
);
1059 if (gpg_err_code (rc
) == GPG_ERR_EOF
)
1072 pwm
->inquire_sent
+= len
;
1074 if (pwm
->status_func
)
1076 char buf
[ASSUAN_LINELENGTH
];
1078 snprintf (buf
, sizeof (buf
), "XFER %zu %zu", pwm
->inquire_sent
,
1079 pwm
->inquire_total
);
1080 rc
= pwm
->status_func (pwm
->status_data
, buf
);
1090 pwm
->inquire_maxlen
= pwm
->inquire_sent
= 0;
1095 parse_assuan_line (pwm_t
* pwm
)
1101 rc
= assuan_read_line (pwm
->ctx
, &line
, &len
);
1104 if (line
[0] == 'O' && line
[1] == 'K' &&
1105 (line
[2] == 0 || line
[2] == ' '))
1108 else if (line
[0] == '#')
1111 else if (line
[0] == 'S' && (line
[1] == 0 || line
[1] == ' '))
1113 rc
= status_cb (pwm
, line
[1] == 0 ? line
+ 1 : line
+ 2);
1115 else if (line
[0] == 'E' && line
[1] == 'R' && line
[2] == 'R' &&
1116 (line
[3] == 0 || line
[3] == ' '))
1119 rc
= strtol (line
, NULL
, 10);
1127 reset_handle (pwm_t
*pwm
)
1131 pwm
->pinentry_disabled
= 0;
1132 #ifdef WITH_PINENTRY
1134 _pinentry_disconnect (pwm
);
1136 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1147 pwmd_disconnect (pwm_t
* pwm
)
1150 return FINISH (GPG_ERR_INV_ARG
);
1152 command_start (pwm
);
1155 return FINISH (GPG_ERR_INV_STATE
);
1162 /* Note that this should only be called when not in a command. */
1164 pwmd_process (pwm_t
* pwm
)
1168 struct timeval tv
= { 0, 0 };
1171 if (!pwm
|| pwm
->fd
== -1)
1172 return FINISH (GPG_ERR_INV_ARG
);
1174 return FINISH (GPG_ERR_INV_STATE
);
1177 FD_SET (pwm
->fd
, &fds
);
1178 n
= select (pwm
->fd
+ 1, &fds
, NULL
, NULL
, &tv
);
1181 return FINISH (gpg_error_from_syserror ());
1185 if (FD_ISSET (pwm
->fd
, &fds
))
1186 rc
= parse_assuan_line (pwm
);
1189 while (!rc
&& assuan_pending_line (pwm
->ctx
))
1190 rc
= parse_assuan_line (pwm
);
1192 #if defined (WITH_SSH) || defined (WITH_GNUTLS)
1193 if (gpg_err_code (rc
) == GPG_ERR_EOF
&& pwm
->tcp
)
1204 status_cb (void *data
, const char *line
)
1208 if (!strncmp (line
, "INQUIRE_MAXLEN ", 15))
1209 pwm
->inquire_maxlen
= strtol (line
+ 15, NULL
, 10);
1210 else if (!strncmp (line
, "PASSPHRASE_HINT ", 16))
1212 pwmd_free (pwm
->passphrase_hint
);
1213 pwm
->passphrase_hint
= pwmd_strdup (line
+16);
1215 else if (!strncmp (line
, "PASSPHRASE_INFO ", 16))
1217 pwmd_free (pwm
->passphrase_info
);
1218 pwm
->passphrase_info
= pwmd_strdup (line
+16);
1221 else if (!strcmp (line
, "REHANDSHAKE"))
1226 ret
= tls_read_hook (pwm
, pwm
->fd
, buf
, sizeof (buf
));
1229 pwm
->tls_error
= ret
;
1230 return GPG_ERR_GENERAL
;
1235 if (pwm
->status_func
)
1236 return pwm
->status_func (pwm
->status_data
, line
);
1242 _assuan_command (pwm_t
* pwm
, assuan_context_t ctx
,
1243 char **result
, size_t * len
, const char *cmd
)
1249 return FINISH (GPG_ERR_INV_ARG
);
1251 if (strlen (cmd
) >= ASSUAN_LINELENGTH
+ 1)
1252 return FINISH (GPG_ERR_LINE_TOO_LONG
);
1256 rc
= assuan_transact (ctx
, cmd
, inquire_realloc_cb
, &data
,
1258 pwm
->pctx
== ctx
? pwm
->_inquire_func
: inquire_cb
,
1259 pwm
->pctx
== ctx
? pwm
->_inquire_data
: pwm
,
1269 pwmd_free (data
.buf
);
1277 inquire_realloc_cb (&data
, "", 1);
1280 *result
= (char *) data
.buf
;
1282 pwmd_free (data
.buf
);
1289 pwm
->inquire_maxlen
= 0;
1294 pwmd_command_ap (pwm_t
* pwm
, char **result
, size_t * rlen
,
1295 pwmd_inquire_cb_t func
, void *user
, const char *cmd
,
1303 return GPG_ERR_INV_ARG
;
1305 command_start (pwm
);
1314 return FINISH (GPG_ERR_INV_ARG
);
1316 return FINISH (GPG_ERR_INV_STATE
);
1319 * C99 allows the dst pointer to be null which will calculate the length
1320 * of the would-be result and return it.
1323 len
= vsnprintf (NULL
, 0, cmd
, ap
) + 1;
1324 buf
= (char *) pwmd_malloc (len
);
1328 return FINISH (GPG_ERR_ENOMEM
);
1331 len
= vsnprintf (buf
, len
, cmd
, ap2
);
1334 if (buf
[strlen (buf
) - 1] == '\n')
1335 buf
[strlen (buf
) - 1] = 0;
1336 if (buf
[strlen (buf
) - 1] == '\r')
1337 buf
[strlen (buf
) - 1] = 0;
1339 pwm
->inquire_func
= func
;
1340 pwm
->inquire_data
= user
;
1341 pwm
->inquire_sent
= 0;
1342 gpg_error_t rc
= _assuan_command (pwm
, pwm
->ctx
, result
, rlen
, buf
);
1348 pwmd_command (pwm_t
* pwm
, char **result
, size_t * len
,
1349 pwmd_inquire_cb_t func
, void *user
, const char *cmd
, ...)
1360 return FINISH (GPG_ERR_INV_ARG
);
1362 return FINISH (GPG_ERR_INV_STATE
);
1365 gpg_error_t rc
= pwmd_command_ap (pwm
, result
, len
, func
, user
, cmd
, ap
);
1371 send_pinentry_timeout (pwm_t
*pwm
)
1375 if ((pwm
->pinentry_timeout
>= 0
1376 && pwm
->pinentry_timeout
!= pwm
->current_pinentry_timeout
)
1377 || (pwm
->pinentry_timeout
== -1
1378 && pwm
->pinentry_timeout
!= pwm
->current_pinentry_timeout
))
1380 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
,
1381 "OPTION pinentry-timeout=%i",
1382 pwm
->pinentry_timeout
);
1384 pwm
->current_pinentry_timeout
= pwm
->pinentry_timeout
;
1391 send_pinentry_options (pwm_t
* pwm
)
1395 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
,
1396 "OPTION disable-pinentry=0");
1397 if (!rc
&& pwm
->pinentry_tty
)
1398 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION TTYNAME=%s",
1401 if (!rc
&& pwm
->pinentry_term
)
1402 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION TTYTYPE=%s",
1403 pwm
->pinentry_term
);
1405 if (!rc
&& pwm
->pinentry_display
)
1406 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION DISPLAY=%s",
1407 pwm
->pinentry_display
);
1409 if (!rc
&& pwm
->pinentry_desc
)
1410 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION DESC=%s",
1411 pwm
->pinentry_desc
);
1413 if (!rc
&& pwm
->pinentry_lcctype
)
1414 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION LC_CTYPE=%s",
1415 pwm
->pinentry_lcctype
);
1417 if (!rc
&& pwm
->pinentry_lcmessages
)
1418 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION LC_MESSAGES=%s",
1419 pwm
->pinentry_lcmessages
);
1422 rc
= send_pinentry_timeout (pwm
);
1428 pwmd_socket_type (pwm_t
* pwm
, pwmd_socket_t
* result
)
1430 if (!pwm
|| !result
)
1431 return FINISH (GPG_ERR_INV_ARG
);
1433 *result
= PWMD_SOCKET_LOCAL
;
1436 return FINISH (GPG_ERR_INV_STATE
);
1438 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1440 if (pwm
->tcp
&& pwm
->tcp
->ssh
)
1441 *result
= PWMD_SOCKET_SSH
;
1444 if (pwm
->tcp
&& pwm
->tcp
->tls
)
1445 *result
= PWMD_SOCKET_TLS
;
1452 disable_pinentry (pwm_t
*pwm
, int *disable
)
1455 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1456 int no_pinentry
= pwm
->disable_pinentry
|| pwm
->tcp
|| pwm
->local_pinentry
;
1458 int no_pinentry
= pwm
->disable_pinentry
|| pwm
->local_pinentry
;
1462 *disable
= no_pinentry
;
1464 if (pwm
->pinentry_disabled
&& no_pinentry
)
1466 else if (!pwm
->pinentry_disabled
&& !no_pinentry
)
1469 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION disable-pinentry=%i",
1472 pwm
->pinentry_disabled
= no_pinentry
;
1478 pwmd_open (pwm_t
* pwm
, const char *filename
, pwmd_inquire_cb_t cb
,
1482 int no_pinentry
= 0;
1484 if (!pwm
|| !filename
|| !*filename
)
1485 return FINISH (GPG_ERR_INV_ARG
);
1488 return FINISH (GPG_ERR_INV_STATE
);
1490 command_start (pwm
);
1491 rc
= disable_pinentry (pwm
, &no_pinentry
);
1492 if (!rc
&& !no_pinentry
)
1493 rc
= send_pinentry_options (pwm
);
1497 pwm
->pinentry_try
= 0;
1498 pwmd_free (pwm
->filename
);
1499 pwm
->filename
= pwmd_strdup (filename
);
1503 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
, "OPEN %s%s",
1504 (pwm
->opts
& OPT_LOCK_ON_OPEN
) ? "--lock " : "",
1507 while (gpg_err_code (rc
) == GPG_ERR_BAD_PASSPHRASE
1508 && pwm
->pinentry_disabled
1509 && ++pwm
->pinentry_try
< pwm
->pinentry_tries
);
1511 pwm
->pinentry_try
= 0;
1515 pwmd_free (pwm
->filename
);
1516 pwm
->filename
= NULL
;
1520 pwmd_free (pwm
->passphrase_hint
);
1521 pwmd_free (pwm
->passphrase_info
);
1522 pwm
->passphrase_info
= pwm
->passphrase_hint
= NULL
;
1527 do_pwmd_save_passwd (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
,
1528 void *data
, int save
)
1531 int no_pinentry
= 0;
1534 return FINISH (GPG_ERR_INV_ARG
);
1536 return FINISH (GPG_ERR_INV_STATE
);
1538 command_start (pwm
);
1539 rc
= disable_pinentry (pwm
, &no_pinentry
);
1540 if (!rc
&& !no_pinentry
)
1541 rc
= send_pinentry_options (pwm
);
1544 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
,
1545 save
? "SAVE %s" : "PASSWD %s", args
? args
: "");
1547 pwmd_free (pwm
->passphrase_hint
);
1548 pwmd_free (pwm
->passphrase_info
);
1549 pwm
->passphrase_info
= pwm
->passphrase_hint
= NULL
;
1554 pwmd_passwd (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
, void *data
)
1556 return do_pwmd_save_passwd (pwm
, args
, cb
, data
, 0);
1560 pwmd_save (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
, void *data
)
1562 return do_pwmd_save_passwd (pwm
, args
, cb
, data
, 1);
1566 pwmd_get_set_opt (pwm_t
*pwm
, pwmd_option_t opt
, int get
, va_list ap
)
1570 char *arg1
, **charpp
;
1574 return GPG_ERR_INV_ARG
;
1576 command_start (pwm
);
1579 case PWMD_OPTION_SERVER_VERSION
:
1581 return GPG_ERR_NOT_SUPPORTED
;
1584 rc
= GPG_ERR_INV_STATE
;
1587 unsigned *u
= va_arg (ap
, unsigned *);
1592 case PWMD_OPTION_SIGPIPE
:
1595 intp
= va_arg (ap
, int *);
1596 *intp
= pwm
->opts
& OPT_SIGPIPE
? 1 : 0;
1600 n
= va_arg (ap
, int);
1603 rc
= GPG_ERR_INV_VALUE
;
1608 pwm
->opts
|= OPT_SIGPIPE
;
1610 pwm
->opts
&= ~OPT_SIGPIPE
;
1613 case PWMD_OPTION_LOCK_ON_OPEN
:
1616 intp
= va_arg (ap
, int *);
1617 *intp
= pwm
->opts
& OPT_LOCK_ON_OPEN
? 1 : 0;
1621 n
= va_arg (ap
, int);
1624 rc
= GPG_ERR_INV_VALUE
;
1629 pwm
->opts
|= OPT_LOCK_ON_OPEN
;
1631 pwm
->opts
&= ~OPT_LOCK_ON_OPEN
;
1634 case PWMD_OPTION_INQUIRE_TOTAL
:
1637 sizetp
= va_arg (ap
, size_t *);
1638 *sizetp
= pwm
->inquire_total
;
1642 pwm
->inquire_total
= va_arg (ap
, size_t);
1644 case PWMD_OPTION_STATUS_CB
:
1647 pwmd_status_cb_t
*cb
= va_arg (ap
, pwmd_status_cb_t
*);
1649 *cb
= pwm
->status_func
;
1653 pwm
->status_func
= va_arg (ap
, pwmd_status_cb_t
);
1655 case PWMD_OPTION_STATUS_DATA
:
1658 void **data
= va_arg (ap
, void **);
1660 *data
= pwm
->status_data
;
1664 pwm
->status_data
= va_arg (ap
, void *);
1666 case PWMD_OPTION_NO_PINENTRY
:
1669 intp
= va_arg (ap
, int *);
1670 *intp
= pwm
->disable_pinentry
;
1674 n
= va_arg (ap
, int);
1676 rc
= GPG_ERR_INV_VALUE
;
1678 pwm
->disable_pinentry
= n
;
1680 case PWMD_OPTION_LOCAL_PINENTRY
:
1683 intp
= va_arg (ap
, int *);
1684 *intp
= pwm
->local_pinentry
;
1688 n
= va_arg (ap
, int);
1690 rc
= GPG_ERR_INV_VALUE
;
1692 pwm
->local_pinentry
= n
;
1695 case PWMD_OPTION_PINENTRY_TIMEOUT
:
1698 intp
= va_arg (ap
, int *);
1699 *intp
= pwm
->pinentry_timeout
;
1703 n
= va_arg (ap
, int);
1705 rc
= GPG_ERR_INV_VALUE
;
1707 pwm
->pinentry_timeout
= n
;
1709 case PWMD_OPTION_PINENTRY_TRIES
:
1712 intp
= va_arg (ap
, int *);
1713 *intp
= pwm
->pinentry_tries
;
1717 n
= va_arg (ap
, int);
1719 rc
= GPG_ERR_INV_VALUE
;
1721 pwm
->pinentry_tries
= n
;
1723 case PWMD_OPTION_PINENTRY_PATH
:
1726 charpp
= va_arg (ap
, char **);
1727 *charpp
= pwm
->pinentry_path
;
1731 arg1
= va_arg (ap
, char *);
1732 pwmd_free (pwm
->pinentry_path
);
1733 pwm
->pinentry_path
= arg1
? _expand_homedir (arg1
, NULL
) : NULL
;
1735 case PWMD_OPTION_PINENTRY_TTY
:
1738 charpp
= va_arg (ap
, char **);
1739 *charpp
= pwm
->pinentry_tty
;
1743 arg1
= va_arg (ap
, char *);
1744 pwmd_free (pwm
->pinentry_tty
);
1745 pwm
->pinentry_tty
= arg1
? pwmd_strdup (arg1
) : NULL
;
1747 case PWMD_OPTION_PINENTRY_DISPLAY
:
1750 charpp
= va_arg (ap
, char **);
1751 *charpp
= pwm
->pinentry_display
;
1755 arg1
= va_arg (ap
, char *);
1756 pwmd_free (pwm
->pinentry_display
);
1757 pwm
->pinentry_display
= arg1
&& *arg1
? pwmd_strdup (arg1
) : NULL
;
1758 if (!pwm
->pinentry_display
)
1759 unsetenv ("DISPLAY");
1761 case PWMD_OPTION_PINENTRY_TERM
:
1764 charpp
= va_arg (ap
, char **);
1765 *charpp
= pwm
->pinentry_term
;
1769 arg1
= va_arg (ap
, char *);
1770 pwmd_free (pwm
->pinentry_term
);
1771 pwm
->pinentry_term
= arg1
&& *arg1
? pwmd_strdup (arg1
) : NULL
;
1772 if (pwm
->pinentry_term
)
1775 case PWMD_OPTION_PINENTRY_ERROR
:
1778 charpp
= va_arg (ap
, char **);
1779 *charpp
= pwm
->pinentry_error
;
1783 arg1
= va_arg (ap
, char *);
1784 pwmd_free (pwm
->pinentry_error
);
1785 if (pwm
->disable_pinentry
)
1786 pwm
->pinentry_error
= arg1
? pwmd_strdup (arg1
) : NULL
;
1788 pwm
->pinentry_error
= arg1
? _percent_escape (arg1
) : NULL
;
1790 case PWMD_OPTION_PINENTRY_PROMPT
:
1793 charpp
= va_arg (ap
, char **);
1794 *charpp
= pwm
->pinentry_prompt
;
1798 arg1
= va_arg (ap
, char *);
1799 pwmd_free (pwm
->pinentry_prompt
);
1800 if (pwm
->disable_pinentry
)
1801 pwm
->pinentry_prompt
= arg1
? pwmd_strdup (arg1
) : NULL
;
1803 pwm
->pinentry_prompt
= arg1
? _percent_escape (arg1
) : NULL
;
1805 case PWMD_OPTION_PINENTRY_DESC
:
1808 charpp
= va_arg (ap
, char **);
1809 *charpp
= pwm
->pinentry_desc
;
1813 arg1
= va_arg (ap
, char *);
1814 pwmd_free (pwm
->pinentry_desc
);
1815 if (pwm
->disable_pinentry
)
1816 pwm
->pinentry_desc
= arg1
? pwmd_strdup (arg1
) : NULL
;
1818 pwm
->pinentry_desc
= arg1
? _percent_escape (arg1
) : NULL
;
1820 case PWMD_OPTION_PINENTRY_LC_CTYPE
:
1823 charpp
= va_arg (ap
, char **);
1824 *charpp
= pwm
->pinentry_lcctype
;
1828 arg1
= va_arg (ap
, char *);
1829 pwmd_free (pwm
->pinentry_lcctype
);
1830 pwm
->pinentry_lcctype
= arg1
? pwmd_strdup (arg1
) : NULL
;
1832 case PWMD_OPTION_PINENTRY_LC_MESSAGES
:
1835 charpp
= va_arg (ap
, char **);
1836 *charpp
= pwm
->pinentry_lcmessages
;
1840 arg1
= va_arg (ap
, char *);
1841 pwmd_free (pwm
->pinentry_lcmessages
);
1842 pwm
->pinentry_lcmessages
= arg1
? pwmd_strdup (arg1
) : NULL
;
1844 case PWMD_OPTION_KNOWNHOST_CB
:
1847 pwmd_knownhost_cb_t
*cb
= va_arg (ap
, pwmd_knownhost_cb_t
*);
1853 pwm
->kh_cb
= va_arg (ap
, pwmd_knownhost_cb_t
);
1855 case PWMD_OPTION_KNOWNHOST_DATA
:
1858 void **data
= va_arg (ap
, void **);
1860 *data
= pwm
->kh_data
;
1864 pwm
->kh_data
= va_arg (ap
, void *);
1866 case PWMD_OPTION_SSH_AGENT
:
1869 intp
= va_arg (ap
, int *);
1870 *intp
= pwm
->use_agent
;
1874 n
= va_arg (ap
, int);
1876 rc
= GPG_ERR_INV_VALUE
;
1880 case PWMD_OPTION_SSH_PASSPHRASE
:
1882 return GPG_ERR_NOT_SUPPORTED
;
1884 pwmd_free (pwm
->ssh_passphrase
);
1885 pwm
->ssh_passphrase
= NULL
;
1886 arg1
= va_arg (ap
, char *);
1889 pwm
->ssh_passphrase
= pwmd_strdup (arg1
);
1890 if (!pwm
->ssh_passphrase
)
1891 return GPG_ERR_ENOMEM
;
1894 case PWMD_OPTION_SSH_NEEDS_PASSPHRASE
:
1897 intp
= va_arg (ap
, int *);
1898 *intp
= pwm
->needs_passphrase
;
1902 n
= va_arg (ap
, int);
1904 rc
= GPG_ERR_INV_VALUE
;
1906 pwm
->needs_passphrase
= n
;
1908 case PWMD_OPTION_TLS_VERIFY
:
1911 intp
= va_arg (ap
, int *);
1912 *intp
= pwm
->tls_verify
;
1916 n
= va_arg (ap
, int);
1918 rc
= GPG_ERR_INV_VALUE
;
1920 pwm
->tls_verify
= n
;
1922 case PWMD_OPTION_TLS_PRIORITY
:
1925 charpp
= va_arg (ap
, char **);
1926 *charpp
= pwm
->tls_priority
;
1930 pwmd_free (pwm
->tls_priority
);
1931 pwm
->tls_priority
= NULL
;
1932 arg1
= va_arg (ap
, char *);
1935 pwm
->tls_priority
= pwmd_strdup (arg1
);
1936 if (!pwm
->tls_priority
)
1937 rc
= GPG_ERR_ENOMEM
;
1940 case PWMD_OPTION_SOCKET_TIMEOUT
:
1943 intp
= va_arg (ap
, int *);
1944 *intp
= pwm
->socket_timeout
;
1948 n
= va_arg (ap
, int);
1951 rc
= GPG_ERR_INV_VALUE
;
1955 pwm
->socket_timeout
= n
;
1958 if (pwm
->tcp
&& pwm
->tcp
->ssh
&& pwm
->tcp
->ssh
->session
)
1960 pwm
->tcp
->ssh
->timeout
= pwm
->socket_timeout
;
1961 libssh2_session_set_timeout (pwm
->tcp
->ssh
->session
,
1962 pwm
->socket_timeout
* 1000);
1966 if (pwm
->tcp
&& pwm
->tcp
->tls
&& pwm
->tcp
->tls
->session
)
1967 pwm
->tcp
->tls
->timeout
= pwm
->socket_timeout
;
1970 case PWMD_OPTION_OVERRIDE_INQUIRE
:
1973 intp
= va_arg (ap
, int *);
1974 *intp
= pwm
->override_inquire
;
1978 n
= va_arg (ap
, int);
1980 rc
= GPG_ERR_INV_VALUE
;
1982 pwm
->override_inquire
= n
;
1985 rc
= GPG_ERR_UNKNOWN_OPTION
;
1993 pwmd_setopt (pwm_t
* pwm
, int opt
, ...)
1999 rc
= pwmd_get_set_opt (pwm
, opt
, 0, ap
);
2005 pwmd_getopt (pwm_t
*pwm
, int opt
, ...)
2011 rc
= pwmd_get_set_opt (pwm
, opt
, 1, ap
);
2017 set_rcdefaults (pwm_t
*pwm
, char *filename
)
2022 unsigned line_n
= 0;
2025 if (!filename
&& isatty (STDIN_FILENO
))
2028 int err
= ttyname_r (STDOUT_FILENO
, buf
, sizeof (buf
));
2032 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TTY
, buf
);
2036 if (getenv ("TERM"))
2038 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TERM
, getenv ("TERM"));
2045 if (!filename
&& getenv ("DISPLAY"))
2047 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_DISPLAY
, getenv ("DISPLAY"));
2052 f
= _expand_homedir (filename
? filename
: (char *)"~/.config/libpwmd.conf",
2056 line
= pwmd_malloc (LINE_MAX
);
2059 fp
= fopen (f
, "r");
2068 rc
= GPG_ERR_ENOMEM
;
2071 rc
= GPG_ERR_ENOMEM
;
2080 while ((p
= fgets (line
, LINE_MAX
, fp
)))
2082 char name
[32] = {0}, val
[512] = {0};
2089 while (isspace (*p
))
2092 if (!*p
|| *p
== '#')
2095 if (p
[strlen (p
)-1] == '\n')
2096 p
[strlen (p
)-1] = 0;
2098 t
= strchr (p
, '=');
2101 fprintf(stderr
, N_("%s(%u): malformed line\n"), f
, line_n
);
2105 for (np
= name
; p
!= t
; p
++)
2107 if (++len
== sizeof (name
))
2116 while (isspace (*t
))
2119 while (isspace (*t
))
2122 strncpy (val
, t
, sizeof (val
)-1);
2124 if (!strcasecmp (name
, "pinentry-path"))
2125 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_PATH
, val
);
2126 else if (!strcasecmp (name
, "pinentry-tries"))
2127 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TRIES
, atoi (val
));
2128 else if (!strcasecmp (name
, "pinentry-timeout"))
2129 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TIMEOUT
, atoi (val
));
2130 else if (!strcasecmp (name
, "no-pinentry"))
2131 rc
= pwmd_setopt (pwm
, PWMD_OPTION_NO_PINENTRY
, !!(atoi (val
)));
2132 else if (!strcasecmp (name
, "local-pinentry"))
2133 rc
= pwmd_setopt (pwm
, PWMD_OPTION_LOCAL_PINENTRY
, !!(atoi (val
)));
2134 else if (!strcasecmp (name
, "pinentry-display"))
2135 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_DISPLAY
, val
);
2136 else if (!strcasecmp (name
, "pinentry-ttyname"))
2137 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TTY
, val
);
2138 else if (!strcasecmp (name
, "pinentry-ttytype"))
2139 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TERM
, val
);
2140 else if (!strcasecmp (name
, "pinentry-lc-messages"))
2141 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_LC_MESSAGES
, val
);
2142 else if (!strcasecmp (name
, "pinentry-lc-ctype"))
2143 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_LC_CTYPE
, val
);
2144 else if (!strcasecmp (name
, "no-ssh-agent"))
2145 rc
= pwmd_setopt (pwm
, PWMD_OPTION_SSH_AGENT
, !(atoi (val
)));
2146 else if (!strcasecmp (name
, "no-tls-verify"))
2147 rc
= pwmd_setopt (pwm
, PWMD_OPTION_TLS_VERIFY
, !(atoi (val
)));
2148 else if (!strcasecmp (name
, "tls-priority"))
2149 rc
= pwmd_setopt (pwm
, PWMD_OPTION_TLS_PRIORITY
, val
);
2150 else if (!strcasecmp (name
, "socket-timeout"))
2151 rc
= pwmd_setopt (pwm
, PWMD_OPTION_SOCKET_TIMEOUT
, atoi (val
));
2152 else if (!strcasecmp (name
, "no-lock"))
2153 rc
= pwmd_setopt (pwm
, PWMD_OPTION_LOCK_ON_OPEN
, !(atoi (val
)));
2154 else if (!strcasecmp (name
, "include"))
2155 rc
= set_rcdefaults (pwm
, val
);
2157 fprintf(stderr
, N_("%s(%u): invalid option '%s', ignored.\n"), f
,
2171 pwmd_new (const char *name
, pwm_t
** pwm
)
2173 pwm_t
*h
= pwmd_calloc (1, sizeof (pwm_t
));
2177 return FINISH (GPG_ERR_ENOMEM
);
2181 h
->name
= pwmd_strdup (name
);
2185 return FINISH (GPG_ERR_ENOMEM
);
2190 h
->pinentry_timeout
= -1;
2191 h
->current_pinentry_timeout
= -1;
2192 h
->pinentry_tries
= 3;
2193 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
2194 h
->prot
= PWMD_IP_ANY
;
2195 h
->socket_timeout
= 120;
2198 h
->opts
|= OPT_LOCK_ON_OPEN
;
2200 rc
= set_rcdefaults (h
, NULL
);
2213 pwmd_free (void *ptr
)
2219 pwmd_malloc (size_t size
)
2221 return _xmalloc (size
);
2225 pwmd_calloc (size_t nmemb
, size_t size
)
2227 return _xcalloc (nmemb
, size
);
2231 pwmd_realloc (void *ptr
, size_t size
)
2233 return _xrealloc (ptr
, size
);
2237 pwmd_strdup (const char *str
)
2244 t
= _xmalloc ((len
+ 1) * sizeof (char));
2248 for (c
= 0; c
< len
; c
++)
2256 pwmd_strdup_printf (const char *fmt
, ...)
2267 len
= vsnprintf (NULL
, 0, fmt
, ap
);
2269 buf
= pwmd_malloc (++len
);
2271 vsnprintf (buf
, len
, fmt
, ap2
);
2278 pwmd_getpin (pwm_t
* pwm
, const char *filename
, char **result
,
2279 size_t * len
, pwmd_pinentry_t which
)
2281 #ifndef WITH_PINENTRY
2282 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
2286 command_start (pwm
);
2287 if (which
== PWMD_PINENTRY_CONFIRM
&& pwm
->disable_pinentry
)
2289 rc
= get_password (pwm
, NULL
, NULL
, which
, 1);
2293 rc
= _pwmd_getpin (pwm
, filename
, result
, len
, which
);
2301 return LIBPWMD_VERSION_STR
;
2309 #ifdef WITH_PINENTRY
2310 n
|= PWMD_FEATURE_PINENTRY
;
2313 n
|= PWMD_FEATURE_SSH
;
2316 n
|= PWMD_FEATURE_QUALITY
;
2319 n
|= PWMD_FEATURE_GNUTLS
;
2325 pwmd_fd (pwm_t
* pwm
, int *fd
)
2328 return FINISH (GPG_ERR_INV_ARG
);
2331 return FINISH (GPG_ERR_INV_STATE
);
2338 pwmd_set_pointer (pwm_t
*pwm
, void *data
)
2340 pwm
->user_data
= data
;
2344 pwmd_get_pointer (pwm_t
*pwm
)
2346 return pwm
->user_data
;
2350 pwmd_gnutls_error (pwm_t
*pwm
, const char **str
)
2357 if (str
&& pwm
&& pwm
->tls_error
)
2358 *str
= gnutls_strerror (pwm
->tls_error
);
2360 return pwm
? pwm
->tls_error
: 0;
2365 pwmd_cancel (pwm_t
*pwm
)
2368 return FINISH (GPG_ERR_INV_ARG
);
2370 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
2371 if (pwm
->fd
== -1 && !pwm
->tcp
)
2375 return FINISH (GPG_ERR_INV_STATE
);
2377 /* Can only cancel the connection for the time being. */
2379 return FINISH (GPG_ERR_INV_STATE
);
2386 pwmd_test_quality (const char *str
, double *result
)
2388 #ifndef WITH_QUALITY
2391 return GPG_ERR_NOT_IMPLEMENTED
;
2394 return GPG_ERR_INV_ARG
;
2396 *result
= ZxcvbnMatch (str
, NULL
, NULL
);