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
);
101 return read ((int) fd
, data
, len
);
105 hook_write (assuan_context_t ctx
, assuan_fd_t fd
, const void *data
,
109 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
110 pwm_t
*pwm
= assuan_get_pointer (ctx
);
113 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->ssh
)
114 return write_hook_ssh (pwm
->tcp
->ssh
, fd
, data
, len
);
117 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->tls
)
118 return tls_write_hook (pwm
, fd
, data
, len
);
122 /* libassuan cannot handle EAGAIN when doing writes. */
125 wrote
= write ((int) fd
, data
, len
);
126 if (wrote
== -1 && errno
== EAGAIN
)
129 while (wrote
== -1 && errno
== EAGAIN
);
135 hook_waitpid (assuan_context_t ctx
, pid_t pid
, int action
, int *status
,
138 return waitpid (pid
, status
, options
);
144 static int initialized
;
147 // May be called more than once.
148 gnutls_global_init ();
155 bindtextdomain ("libpwmd", LOCALEDIR
);
161 //gpgrt_set_alloc_func (_xrealloc_gpgrt);
175 gnutls_global_deinit ();
183 _connect_finalize (pwm_t
* pwm
)
188 int n
= assuan_get_active_fds (pwm
->ctx
, 0, active
, N_ARRAY (active
));
191 return GPG_ERR_EBADFD
;
195 pwm
->pinentry_pid
= -1;
198 rc
= pwmd_command (pwm
, &result
, NULL
, NULL
, NULL
, "GETINFO VERSION");
201 pwm
->version
= strtoul (result
, NULL
, 16);
205 if (!rc
&& pwm
->name
)
206 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION NAME=%s",
213 connect_uds (pwm_t
* pwm
, const char *path
)
215 char *socketpath
= NULL
;
221 return GPG_ERR_INV_ARG
;
223 pwbuf
= _getpwuid (&pw
);
225 return gpg_error_from_syserror ();
228 socketpath
= pwmd_strdup_printf ("%s/.pwmd/socket", pw
.pw_dir
);
230 socketpath
= _expand_homedir ((char *) path
, &pw
);
234 return GPG_ERR_ENOMEM
;
236 rc
= assuan_socket_connect (pwm
->ctx
, socketpath
, ASSUAN_INVALID_FD
, 0);
237 pwmd_free (socketpath
);
238 return rc
? rc
: _connect_finalize (pwm
);
242 init_handle (pwm_t
* pwm
)
245 static struct assuan_malloc_hooks mhooks
= {
246 pwmd_malloc
, pwmd_realloc
, pwmd_free
248 static struct assuan_system_hooks shooks
= {
249 ASSUAN_SYSTEM_HOOKS_VERSION
,
257 NULL
, //sendmsg both are used for FD passing
265 rc
= assuan_new_ext (&pwm
->ctx
, GPG_ERR_SOURCE_DEFAULT
, &mhooks
, NULL
,
270 assuan_set_pointer (pwm
->ctx
, pwm
);
271 assuan_ctx_set_system_hooks (pwm
->ctx
, &shooks
);
275 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
277 free_tcp (pwm_t
*pwm
)
279 struct tcp_s
*tcp
= pwm
->tcp
;
285 _free_ssh_conn (tcp
->ssh
);
291 pwmd_free (tcp
->host
);
294 freeaddrinfo (tcp
->addrs
);
298 pthread_cond_destroy (&tcp
->dns_cond
);
299 pthread_mutex_destroy (&tcp
->dns_mutex
);
305 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
307 resolve_host_thread (void *arg
)
310 struct addrinfo hints
= { 0 };
316 hints
.ai_family
= AF_UNSPEC
;
319 hints
.ai_family
= AF_INET
;
322 hints
.ai_family
= AF_INET6
;
326 hints
.ai_socktype
= SOCK_STREAM
;
327 snprintf (portstr
, sizeof (portstr
), "%i", pwm
->tcp
->port
);
328 int *n
= pwmd_malloc (sizeof (int));
329 pthread_cleanup_push (pwmd_free
, n
);
330 *n
= getaddrinfo (pwm
->tcp
->host
, portstr
, &hints
, &pwm
->tcp
->addrs
);
331 pthread_cleanup_pop (0);
332 pthread_cond_broadcast (&pwm
->tcp
->dns_cond
);
338 tcp_connect_common (pwm_t
* pwm
)
340 #define TS_TIMEOUT 50000000L
347 n
= pthread_create (&tid
, NULL
, resolve_host_thread
, pwm
);
349 return gpg_error_from_errno (n
);
351 pthread_mutex_lock (&pwm
->tcp
->dns_mutex
);
358 clock_gettime (CLOCK_REALTIME
, &ts
);
359 if (ts
.tv_nsec
+ TS_TIMEOUT
>= 1000000000LL) {
364 ts
.tv_nsec
+= TS_TIMEOUT
;
368 #ifdef HAVE_PTHREAD_CANCEL
369 pthread_cancel (tid
);
370 pthread_join (tid
, NULL
);
372 pthread_join (tid
, (void **)&result
);
375 return GPG_ERR_CANCELED
;
378 n
= pthread_cond_timedwait (&pwm
->tcp
->dns_cond
, &pwm
->tcp
->dns_mutex
,
382 if (pwm
->socket_timeout
&& ts
.tv_sec
- now
>= pwm
->socket_timeout
)
384 #ifdef HAVE_PTHREAD_CANCEL
385 pthread_cancel (tid
);
386 pthread_join (tid
, NULL
);
388 pthread_join (tid
, (void **)&result
);
391 return GPG_ERR_ETIMEDOUT
;
398 #ifdef HAVE_PTHREAD_CANCEL
399 pthread_cancel (tid
);
400 pthread_join (tid
, NULL
);
402 pthread_join (tid
, (void **)&result
);
405 return gpg_error_from_errno (n
);
408 pthread_join (tid
, (void **)&result
);
415 return GPG_ERR_UNKNOWN_HOST
; //FIXME
417 for (pwm
->tcp
->addr
= pwm
->tcp
->addrs
; pwm
->tcp
->addr
;
418 pwm
->tcp
->addr
= pwm
->tcp
->addrs
->ai_next
)
420 pwm
->fd
= socket (pwm
->tcp
->addr
->ai_family
, SOCK_STREAM
, 0);
423 rc
= gpg_error_from_syserror ();
424 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
)
429 if (fcntl (pwm
->fd
, F_SETFL
, O_NONBLOCK
) == -1)
431 rc
= gpg_error_from_syserror ();
435 if (connect (pwm
->fd
, pwm
->tcp
->addr
->ai_addr
,
436 pwm
->tcp
->addr
->ai_family
== AF_INET6
437 ? sizeof (struct sockaddr_in6
)
438 : sizeof (struct sockaddr
)) == -1)
443 unsigned elapsed
= 0;
445 rc
= gpg_error_from_syserror ();
446 if (gpg_err_code (rc
) != GPG_ERR_EINPROGRESS
)
450 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
)
459 FD_SET (pwm
->fd
, &wfds
);
460 n
= select (pwm
->fd
+1, NULL
, &wfds
, NULL
, &tv
);
462 if (!n
|| pwm
->cancel
)
465 rc
= gpg_error (GPG_ERR_CANCELED
);
466 else if (++elapsed
>= pwm
->socket_timeout
)
467 rc
= gpg_error (GPG_ERR_ETIMEDOUT
);
473 socklen_t len
= sizeof(int);
475 getsockopt (pwm
->fd
, SOL_SOCKET
, SO_ERROR
, &n
, &len
);
477 rc
= gpg_error_from_errno (n
);
480 rc
= gpg_error_from_syserror ();
486 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
487 || gpg_err_code (rc
) == GPG_ERR_ETIMEDOUT
499 if (fcntl (pwm
->fd
, F_SETFL
, 0) == -1)
500 rc
= gpg_error_from_syserror ();
507 command_start (pwm_t
*pwm
)
513 pwmd_connect (pwm_t
* pwm
, const char *url
, ...)
519 return FINISH (GPG_ERR_INV_ARG
);
522 rc
= init_handle (pwm
);
529 if (!(pwm
->opts
& OPT_SIGPIPE
))
530 signal (SIGPIPE
, SIG_IGN
);
535 rc
= GPG_ERR_UNSUPPORTED_PROTOCOL
;
537 if (p
&& (*p
== '/' || *p
== '~'))
538 rc
= connect_uds (pwm
, p
);
539 else if (!p
|| !strncmp (p
, "file://", 7))
543 #ifdef DEFAULT_PWMD_SOCKET
545 p
= DEFAULT_PWMD_SOCKET
;
547 rc
= connect_uds (pwm
, p
);
549 else if (!strncmp (p
, "ssh://", 6) || !strncmp (p
, "ssh6://", 7) ||
550 !strncmp (p
, "ssh4://", 7))
553 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
557 char *username
= NULL
;
559 if (!strncmp (p
, "ssh6://", 7))
561 pwm
->prot
= PWMD_IPV6
;
564 else if (!strncmp (p
, "ssh4://", 7))
566 pwm
->prot
= PWMD_IPV4
;
571 pwm
->prot
= PWMD_IP_ANY
;
575 rc
= _parse_ssh_url (p
, &host
, &port
, &username
);
579 char *identity
= NULL
;
580 char *knownhosts
= NULL
;
583 identity
= va_arg (ap
, char *);
585 if (!identity
&& !pwm
->use_agent
)
586 rc
= GPG_ERR_INV_ARG
;
588 knownhosts
= va_arg (ap
, char *);
593 rc
= _do_ssh_connect (pwm
, host
, port
, identity
, username
,
597 rc
= _connect_finalize (pwm
);
604 pwmd_free (username
);
605 pwm
->local_pinentry
= 1;
606 pwmd_free (pwm
->ssh_passphrase
);
607 pwm
->ssh_passphrase
= NULL
;
610 else if (!strncmp (p
, "tls://", 6) || !strncmp (p
, "tls6://", 7) ||
611 !strncmp (p
, "tls4://", 7))
614 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
619 if (!strncmp (p
, "tls6://", 7))
621 pwm
->prot
= PWMD_IPV6
;
624 else if (!strncmp (p
, "tls4://", 7))
626 pwm
->prot
= PWMD_IPV4
;
631 pwm
->prot
= PWMD_IP_ANY
;
635 rc
= tls_parse_url (p
, &host
, &port
);
639 char *clientcert
= NULL
;
640 char *clientkey
= NULL
;
643 char *server_fp
= NULL
;
646 clientcert
= va_arg (ap
, char *);
649 rc
= GPG_ERR_INV_ARG
;
652 clientkey
= va_arg (ap
, char *);
654 rc
= GPG_ERR_INV_ARG
;
657 cacert
= va_arg (ap
, char *);
659 rc
= GPG_ERR_INV_ARG
;
662 prio
= va_arg (ap
, char *);
663 server_fp
= va_arg (ap
, char *);
671 rc
= tls_connect (pwm
, host
, port
, clientcert
, clientkey
, cacert
,
672 prio
, server_fp
, pwm
->tls_verify
);
675 rc
= _connect_finalize (pwm
);
682 pwm
->local_pinentry
= 1;
693 disconnect (pwm_t
* pwm
)
699 assuan_release (pwm
->ctx
);
701 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
710 pwmd_close (pwm_t
* pwm
)
716 pwmd_free (pwm
->pinentry_error
);
717 pwmd_free (pwm
->pinentry_desc
);
718 pwmd_free (pwm
->pinentry_prompt
);
719 pwmd_free (pwm
->pinentry_tty
);
720 pwmd_free (pwm
->pinentry_display
);
721 pwmd_free (pwm
->pinentry_term
);
722 pwmd_free (pwm
->pinentry_lcctype
);
723 pwmd_free (pwm
->pinentry_lcmessages
);
724 pwmd_free (pwm
->filename
);
725 pwmd_free (pwm
->name
);
726 pwmd_free (pwm
->passphrase_info
);
727 pwmd_free (pwm
->passphrase_hint
);
728 pwmd_free (pwm
->ssh_passphrase
);
732 _pinentry_disconnect (pwm
);
739 inquire_realloc_cb (void *data
, const void *buffer
, size_t len
)
741 membuf_t
*mem
= (membuf_t
*) data
;
747 if ((p
= pwmd_realloc (mem
->buf
, mem
->len
+ len
)) == NULL
)
748 return gpg_error (GPG_ERR_ENOMEM
);
751 memcpy ((char *) mem
->buf
+ mem
->len
, buffer
, len
);
757 get_password (pwm_t
* pwm
, char **result
, size_t * len
,
758 pwmd_pinentry_t w
, int echo
)
760 char buf
[ASSUAN_LINELENGTH
+1] = { 0 }, *p
;
761 struct termios told
, tnew
;
770 if (!isatty (STDIN_FILENO
))
772 fprintf (stderr
, N_("Input is not from a terminal! Failing.\n"));
773 return GPG_ERR_ENOTTY
;
778 if (tcgetattr (STDIN_FILENO
, &told
) == -1)
779 return gpg_error_from_syserror ();
781 memcpy (&tnew
, &told
, sizeof (struct termios
));
782 tnew
.c_lflag
&= ~(ECHO
);
783 tnew
.c_lflag
|= ICANON
| ECHONL
;
785 if (tcsetattr (STDIN_FILENO
, TCSANOW
, &tnew
) == -1)
789 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
790 return gpg_error_from_errno (n
);
794 if (pwm
->passphrase_hint
)
795 fprintf(stderr
, N_("Key info: %s\n"), pwm
->passphrase_hint
);
799 case PWMD_PINENTRY_OPEN
:
800 fprintf (stderr
, N_("Passphrase for %s: "), pwm
->filename
);
802 case PWMD_PINENTRY_OPEN_FAILED
:
803 fprintf (stderr
, N_("Invalid passphrase. Passphrase for %s: "),
806 case PWMD_PINENTRY_SAVE
:
807 fprintf (stderr
, N_("New passphrase for %s: "), pwm
->filename
);
809 case PWMD_PINENTRY_SAVE_CONFIRM
:
810 fprintf (stderr
, N_("Repeat passphrase: "));
812 case PWMD_PINENTRY_CONFIRM
:
813 if (pwm
->pinentry_desc
)
814 fprintf (stderr
, "%s", pwm
->pinentry_desc
);
816 if (pwm
->pinentry_prompt
)
817 fprintf (stderr
, "%s", pwm
->pinentry_prompt
);
819 fprintf(stderr
, N_("Confirm [y/N]:"));
824 p
= fgets (buf
, sizeof (buf
), stdin
);
827 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
829 if (!p
|| feof (stdin
))
832 return GPG_ERR_CANCELED
;
835 /* Strip the newline character. */
836 p
[strlen (p
) - 1] = 0;
840 if (w
== PWMD_PINENTRY_CONFIRM
)
842 if (*p
!= 'y' && *p
!= 'Y')
843 return GPG_ERR_CANCELED
;
847 key
= pwmd_strdup_printf ("%s", p
);
848 wipememory (buf
, 0, sizeof (buf
));
850 return GPG_ERR_ENOMEM
;
860 if (w
== PWMD_PINENTRY_CONFIRM
)
861 return GPG_ERR_CANCELED
;
863 /* To satisfy inquire_cb(). */
865 *result
= pwmd_strdup ("");
875 pwmd_password (pwm_t
* pwm
, const char *keyword
, char **data
, size_t * size
)
878 int new_password
= 0;
879 char *password
= NULL
, *newpass
= NULL
;
890 if (!strcmp (keyword
, "NEW_PASSPHRASE"))
893 if (!new_password
&& pwm
->pinentry_try
)
897 if (pwm
->disable_pinentry
)
899 rc
= get_password (pwm
, &password
, size
,
900 new_password
? PWMD_PINENTRY_SAVE
:
901 error
? PWMD_PINENTRY_OPEN_FAILED
:
902 PWMD_PINENTRY_OPEN
, 0);
903 if (!rc
&& new_password
)
904 rc
= get_password (pwm
, &newpass
, size
, PWMD_PINENTRY_SAVE_CONFIRM
,
909 pwmd_pinentry_t which
;
913 ? PWMD_PINENTRY_SAVE_FAILED
: PWMD_PINENTRY_OPEN_FAILED
;
915 which
= new_password
? PWMD_PINENTRY_SAVE
: PWMD_PINENTRY_OPEN
;
917 rc
= pwmd_getpin (pwm
, pwm
->filename
, &password
, size
, which
);
918 if (!rc
&& new_password
)
919 rc
= pwmd_getpin (pwm
, pwm
->filename
, &newpass
, size
,
920 PWMD_PINENTRY_SAVE_CONFIRM
);
923 if (!rc
&& new_password
)
925 if ((!password
&& newpass
) || (!newpass
&& password
)
926 || (newpass
&& password
&& strcmp (newpass
, password
)))
928 if (pwm
->disable_pinentry
)
929 fprintf (stderr
, N_("Passphrases do not match.\n"));
931 pwmd_free (password
);
933 password
= newpass
= NULL
;
939 (void) pwmd_getpin (pwm
, pwm
->filename
, NULL
, NULL
, PWMD_PINENTRY_CLOSE
);
944 pwmd_free (password
);
950 inquire_cb (void *data
, const char *keyword
)
952 pwm_t
*pwm
= (pwm_t
*) data
;
957 int new_password
= 0;
959 if (!strcmp (keyword
, "PASSPHRASE") || !strcmp (keyword
, "SIGN_PASSPHRASE"))
961 else if (!strcmp (keyword
, "NEW_PASSPHRASE") || !strcmp (keyword
, "GENKEY"))
964 /* Shouldn't get this far without a callback. */
965 if (!pwm
->override_inquire
&& !pwm
->inquire_func
966 && !is_password
&& !new_password
)
967 return gpg_error (GPG_ERR_ASS_NO_INQUIRE_CB
);
976 if (!pwm
->override_inquire
&& (is_password
|| new_password
))
979 rc
= pwmd_password (data
, keyword
, &result
, &len
);
984 rc
= pwm
->inquire_func (pwm
->inquire_data
, keyword
, rc
, &result
,
987 /* gpg will truncate a passphrase at the first nil byte which may be bad
988 * for generated key files. */
989 if ((!rc
|| gpg_err_code (rc
) == GPG_ERR_EOF
)
990 && (is_password
|| new_password
))
992 if (len
&& result
&& *result
)
994 for (size_t n
= 0; n
< len
; n
++)
996 if (result
[n
] == 0 && n
+1 != len
)
997 rc
= GPG_ERR_INV_PASSPHRASE
;
1003 if (rc
&& gpg_err_code (rc
) != GPG_ERR_EOF
)
1005 #ifndef LIBASSUAN_2_1_0
1006 gpg_error_t trc
= rc
;
1008 /* Cancel this inquire. */
1009 rc
= assuan_send_data (pwm
->ctx
, NULL
, 1);
1015 /* There is a bug (or feature?) in assuan_send_data() that
1016 * when cancelling an inquire the next read from the server is
1017 * not done until the next command making the next command
1018 * fail with GPG_ERR_ASS_UNEXPECTED_CMD.
1020 rc
= assuan_read_line (pwm
->ctx
, &line
, &len
);
1022 /* Restore the original error. This differs from the error
1023 * returned from the pwmd command (GPG_ERR_CANCELED). This
1024 * error is returned to the calling function.
1033 if (gpg_err_code (rc
) == GPG_ERR_EOF
|| !rc
)
1035 if (len
<= 0 && !result
)
1040 else if ((len
<= 0 && result
) || (len
&& !result
))
1042 rc
= gpg_error (GPG_ERR_INV_ARG
);
1046 if (pwm
->inquire_maxlen
1047 && pwm
->inquire_sent
+ len
> pwm
->inquire_maxlen
)
1049 rc
= gpg_error (GPG_ERR_TOO_LARGE
);
1051 rc
= pwm
->inquire_func (pwm
->inquire_data
, keyword
, rc
,
1056 arc
= assuan_send_data (pwm
->ctx
, result
, len
);
1057 if (gpg_err_code (rc
) == GPG_ERR_EOF
)
1070 pwm
->inquire_sent
+= len
;
1072 if (pwm
->status_func
)
1074 char buf
[ASSUAN_LINELENGTH
];
1076 snprintf (buf
, sizeof (buf
), "XFER %zu %zu", pwm
->inquire_sent
,
1077 pwm
->inquire_total
);
1078 rc
= pwm
->status_func (pwm
->status_data
, buf
);
1088 pwm
->inquire_maxlen
= pwm
->inquire_sent
= 0;
1093 parse_assuan_line (pwm_t
* pwm
)
1099 rc
= assuan_read_line (pwm
->ctx
, &line
, &len
);
1102 if (line
[0] == 'O' && line
[1] == 'K' &&
1103 (line
[2] == 0 || line
[2] == ' '))
1106 else if (line
[0] == '#')
1109 else if (line
[0] == 'S' && (line
[1] == 0 || line
[1] == ' '))
1111 rc
= status_cb (pwm
, line
[1] == 0 ? line
+ 1 : line
+ 2);
1113 else if (line
[0] == 'E' && line
[1] == 'R' && line
[2] == 'R' &&
1114 (line
[3] == 0 || line
[3] == ' '))
1117 rc
= strtol (line
, NULL
, 10);
1125 reset_handle (pwm_t
*pwm
)
1129 pwm
->pinentry_disabled
= 0;
1130 #ifdef WITH_PINENTRY
1132 _pinentry_disconnect (pwm
);
1134 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1145 pwmd_disconnect (pwm_t
* pwm
)
1148 return FINISH (GPG_ERR_INV_ARG
);
1150 command_start (pwm
);
1153 return FINISH (GPG_ERR_INV_STATE
);
1160 /* Note that this should only be called when not in a command. */
1162 pwmd_process (pwm_t
* pwm
)
1166 struct timeval tv
= { 0, 0 };
1169 if (!pwm
|| pwm
->fd
== -1)
1170 return FINISH (GPG_ERR_INV_ARG
);
1172 return FINISH (GPG_ERR_INV_STATE
);
1175 FD_SET (pwm
->fd
, &fds
);
1176 n
= select (pwm
->fd
+ 1, &fds
, NULL
, NULL
, &tv
);
1179 return FINISH (gpg_error_from_syserror ());
1183 if (FD_ISSET (pwm
->fd
, &fds
))
1184 rc
= parse_assuan_line (pwm
);
1187 while (!rc
&& assuan_pending_line (pwm
->ctx
))
1188 rc
= parse_assuan_line (pwm
);
1190 #if defined (WITH_SSH) || defined (WITH_GNUTLS)
1191 if (gpg_err_code (rc
) == GPG_ERR_EOF
&& pwm
->tcp
)
1202 status_cb (void *data
, const char *line
)
1206 if (!strncmp (line
, "INQUIRE_MAXLEN ", 15))
1207 pwm
->inquire_maxlen
= strtol (line
+ 15, NULL
, 10);
1208 else if (!strncmp (line
, "PASSPHRASE_HINT ", 16))
1210 pwmd_free (pwm
->passphrase_hint
);
1211 pwm
->passphrase_hint
= pwmd_strdup (line
+16);
1213 else if (!strncmp (line
, "PASSPHRASE_INFO ", 16))
1215 pwmd_free (pwm
->passphrase_info
);
1216 pwm
->passphrase_info
= pwmd_strdup (line
+16);
1219 else if (!strcmp (line
, "REHANDSHAKE"))
1224 ret
= tls_read_hook (pwm
, pwm
->fd
, buf
, sizeof (buf
));
1227 pwm
->tls_error
= ret
;
1228 return GPG_ERR_GENERAL
;
1233 if (pwm
->status_func
)
1234 return pwm
->status_func (pwm
->status_data
, line
);
1240 _assuan_command (pwm_t
* pwm
, assuan_context_t ctx
,
1241 char **result
, size_t * len
, const char *cmd
)
1247 return FINISH (GPG_ERR_INV_ARG
);
1249 if (strlen (cmd
) >= ASSUAN_LINELENGTH
+ 1)
1250 return FINISH (GPG_ERR_LINE_TOO_LONG
);
1254 rc
= assuan_transact (ctx
, cmd
, inquire_realloc_cb
, &data
,
1256 pwm
->pctx
== ctx
? pwm
->_inquire_func
: inquire_cb
,
1257 pwm
->pctx
== ctx
? pwm
->_inquire_data
: pwm
,
1267 pwmd_free (data
.buf
);
1275 inquire_realloc_cb (&data
, "", 1);
1278 *result
= (char *) data
.buf
;
1280 pwmd_free (data
.buf
);
1287 pwm
->inquire_maxlen
= 0;
1292 pwmd_command_ap (pwm_t
* pwm
, char **result
, size_t * rlen
,
1293 pwmd_inquire_cb_t func
, void *user
, const char *cmd
,
1300 command_start (pwm
);
1309 return FINISH (GPG_ERR_INV_ARG
);
1311 return FINISH (GPG_ERR_INV_STATE
);
1314 * C99 allows the dst pointer to be null which will calculate the length
1315 * of the would-be result and return it.
1318 len
= vsnprintf (NULL
, 0, cmd
, ap
) + 1;
1319 buf
= (char *) pwmd_malloc (len
);
1323 return FINISH (GPG_ERR_ENOMEM
);
1326 len
= vsnprintf (buf
, len
, cmd
, ap2
);
1329 if (buf
[strlen (buf
) - 1] == '\n')
1330 buf
[strlen (buf
) - 1] = 0;
1331 if (buf
[strlen (buf
) - 1] == '\r')
1332 buf
[strlen (buf
) - 1] = 0;
1334 pwm
->inquire_func
= func
;
1335 pwm
->inquire_data
= user
;
1336 pwm
->inquire_sent
= 0;
1337 gpg_error_t rc
= _assuan_command (pwm
, pwm
->ctx
, result
, rlen
, buf
);
1343 pwmd_command (pwm_t
* pwm
, char **result
, size_t * len
,
1344 pwmd_inquire_cb_t func
, void *user
, const char *cmd
, ...)
1355 return FINISH (GPG_ERR_INV_ARG
);
1357 return FINISH (GPG_ERR_INV_STATE
);
1360 gpg_error_t rc
= pwmd_command_ap (pwm
, result
, len
, func
, user
, cmd
, ap
);
1366 send_pinentry_timeout (pwm_t
*pwm
)
1370 if ((pwm
->pinentry_timeout
>= 0
1371 && pwm
->pinentry_timeout
!= pwm
->current_pinentry_timeout
)
1372 || (pwm
->pinentry_timeout
== -1
1373 && pwm
->pinentry_timeout
!= pwm
->current_pinentry_timeout
))
1375 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
,
1376 "OPTION pinentry-timeout=%i",
1377 pwm
->pinentry_timeout
);
1379 pwm
->current_pinentry_timeout
= pwm
->pinentry_timeout
;
1386 send_pinentry_options (pwm_t
* pwm
)
1390 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
,
1391 "OPTION disable-pinentry=0");
1392 if (!rc
&& pwm
->pinentry_tty
)
1393 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION TTYNAME=%s",
1396 if (!rc
&& pwm
->pinentry_term
)
1397 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION TTYTYPE=%s",
1398 pwm
->pinentry_term
);
1400 if (!rc
&& pwm
->pinentry_display
)
1401 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION DISPLAY=%s",
1402 pwm
->pinentry_display
);
1404 if (!rc
&& pwm
->pinentry_desc
)
1405 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION DESC=%s",
1406 pwm
->pinentry_desc
);
1408 if (!rc
&& pwm
->pinentry_lcctype
)
1409 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION LC_CTYPE=%s",
1410 pwm
->pinentry_lcctype
);
1412 if (!rc
&& pwm
->pinentry_lcmessages
)
1413 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION LC_MESSAGES=%s",
1414 pwm
->pinentry_lcmessages
);
1417 rc
= send_pinentry_timeout (pwm
);
1423 pwmd_socket_type (pwm_t
* pwm
, pwmd_socket_t
* result
)
1425 if (!pwm
|| !result
)
1426 return FINISH (GPG_ERR_INV_ARG
);
1428 *result
= PWMD_SOCKET_LOCAL
;
1431 return FINISH (GPG_ERR_INV_STATE
);
1433 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1435 if (pwm
->tcp
&& pwm
->tcp
->ssh
)
1436 *result
= PWMD_SOCKET_SSH
;
1439 if (pwm
->tcp
&& pwm
->tcp
->tls
)
1440 *result
= PWMD_SOCKET_TLS
;
1447 disable_pinentry (pwm_t
*pwm
, int *disable
)
1450 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1451 int no_pinentry
= pwm
->disable_pinentry
|| pwm
->tcp
|| pwm
->local_pinentry
;
1453 int no_pinentry
= pwm
->disable_pinentry
|| pwm
->local_pinentry
;
1457 *disable
= no_pinentry
;
1459 if (pwm
->pinentry_disabled
&& no_pinentry
)
1461 else if (!pwm
->pinentry_disabled
&& !no_pinentry
)
1464 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION disable-pinentry=%i",
1467 pwm
->pinentry_disabled
= no_pinentry
;
1473 pwmd_open (pwm_t
* pwm
, const char *filename
, pwmd_inquire_cb_t cb
,
1477 int no_pinentry
= 0;
1479 if (!pwm
|| !filename
|| !*filename
)
1480 return FINISH (GPG_ERR_INV_ARG
);
1483 return FINISH (GPG_ERR_INV_STATE
);
1485 command_start (pwm
);
1486 rc
= disable_pinentry (pwm
, &no_pinentry
);
1487 if (!rc
&& !no_pinentry
)
1488 rc
= send_pinentry_options (pwm
);
1492 pwm
->pinentry_try
= 0;
1493 pwmd_free (pwm
->filename
);
1494 pwm
->filename
= pwmd_strdup (filename
);
1498 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
, "OPEN %s%s",
1499 (pwm
->opts
& OPT_LOCK_ON_OPEN
) ? "--lock " : "",
1502 while (gpg_err_code (rc
) == GPG_ERR_BAD_PASSPHRASE
1503 && pwm
->pinentry_disabled
1504 && ++pwm
->pinentry_try
< pwm
->pinentry_tries
);
1506 pwm
->pinentry_try
= 0;
1510 pwmd_free (pwm
->filename
);
1511 pwm
->filename
= NULL
;
1515 pwmd_free (pwm
->passphrase_hint
);
1516 pwmd_free (pwm
->passphrase_info
);
1517 pwm
->passphrase_info
= pwm
->passphrase_hint
= NULL
;
1522 do_pwmd_save_passwd (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
,
1523 void *data
, int save
)
1526 int no_pinentry
= 0;
1529 return FINISH (GPG_ERR_INV_ARG
);
1531 return FINISH (GPG_ERR_INV_STATE
);
1533 command_start (pwm
);
1534 rc
= disable_pinentry (pwm
, &no_pinentry
);
1535 if (!rc
&& !no_pinentry
)
1536 rc
= send_pinentry_options (pwm
);
1539 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
,
1540 save
? "SAVE %s" : "PASSWD %s", args
? args
: "");
1542 pwmd_free (pwm
->passphrase_hint
);
1543 pwmd_free (pwm
->passphrase_info
);
1544 pwm
->passphrase_info
= pwm
->passphrase_hint
= NULL
;
1549 pwmd_passwd (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
, void *data
)
1551 return do_pwmd_save_passwd (pwm
, args
, cb
, data
, 0);
1555 pwmd_save (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
, void *data
)
1557 return do_pwmd_save_passwd (pwm
, args
, cb
, data
, 1);
1561 pwmd_get_set_opt (pwm_t
*pwm
, pwmd_option_t opt
, int get
, va_list ap
)
1565 char *arg1
, **charpp
;
1569 return GPG_ERR_INV_ARG
;
1571 command_start (pwm
);
1574 case PWMD_OPTION_SERVER_VERSION
:
1576 return GPG_ERR_NOT_SUPPORTED
;
1579 rc
= GPG_ERR_INV_ARG
;
1581 rc
= GPG_ERR_INV_STATE
;
1584 unsigned *u
= va_arg (ap
, unsigned *);
1589 case PWMD_OPTION_SIGPIPE
:
1592 intp
= va_arg (ap
, int *);
1593 *intp
= pwm
->opts
& OPT_SIGPIPE
? 1 : 0;
1597 n
= va_arg (ap
, int);
1599 rc
= GPG_ERR_INV_VALUE
;
1602 pwm
->opts
|= OPT_SIGPIPE
;
1604 pwm
->opts
&= ~OPT_SIGPIPE
;
1607 case PWMD_OPTION_LOCK_ON_OPEN
:
1610 intp
= va_arg (ap
, int *);
1611 *intp
= pwm
->opts
& OPT_LOCK_ON_OPEN
? 1 : 0;
1615 n
= va_arg (ap
, int);
1618 rc
= GPG_ERR_INV_VALUE
;
1621 pwm
->opts
|= OPT_LOCK_ON_OPEN
;
1623 pwm
->opts
&= ~OPT_LOCK_ON_OPEN
;
1626 case PWMD_OPTION_INQUIRE_TOTAL
:
1629 sizetp
= va_arg (ap
, size_t *);
1630 *sizetp
= pwm
->inquire_total
;
1634 pwm
->inquire_total
= va_arg (ap
, size_t);
1636 case PWMD_OPTION_STATUS_CB
:
1639 pwmd_status_cb_t
*cb
= va_arg (ap
, pwmd_status_cb_t
*);
1641 *cb
= pwm
->status_func
;
1645 pwm
->status_func
= va_arg (ap
, pwmd_status_cb_t
);
1647 case PWMD_OPTION_STATUS_DATA
:
1650 void **data
= va_arg (ap
, void **);
1652 *data
= pwm
->status_data
;
1656 pwm
->status_data
= va_arg (ap
, void *);
1658 case PWMD_OPTION_NO_PINENTRY
:
1661 intp
= va_arg (ap
, int *);
1662 *intp
= pwm
->disable_pinentry
;
1666 n
= va_arg (ap
, int);
1669 rc
= GPG_ERR_INV_VALUE
;
1671 pwm
->disable_pinentry
= n
;
1673 case PWMD_OPTION_LOCAL_PINENTRY
:
1676 intp
= va_arg (ap
, int *);
1677 *intp
= pwm
->local_pinentry
;
1681 n
= va_arg (ap
, int);
1684 rc
= GPG_ERR_INV_VALUE
;
1686 pwm
->local_pinentry
= n
;
1689 case PWMD_OPTION_PINENTRY_TIMEOUT
:
1692 intp
= va_arg (ap
, int *);
1693 *intp
= pwm
->pinentry_timeout
;
1697 n
= va_arg (ap
, int);
1700 rc
= GPG_ERR_INV_VALUE
;
1702 pwm
->pinentry_timeout
= n
;
1704 case PWMD_OPTION_PINENTRY_TRIES
:
1707 intp
= va_arg (ap
, int *);
1708 *intp
= pwm
->pinentry_tries
;
1712 n
= va_arg (ap
, int);
1713 pwm
->pinentry_tries
= n
;
1715 case PWMD_OPTION_PINENTRY_PATH
:
1718 charpp
= va_arg (ap
, char **);
1719 *charpp
= pwm
->pinentry_path
;
1723 arg1
= va_arg (ap
, char *);
1724 pwmd_free (pwm
->pinentry_path
);
1725 pwm
->pinentry_path
= arg1
? _expand_homedir (arg1
, NULL
) : NULL
;
1727 case PWMD_OPTION_PINENTRY_TTY
:
1730 charpp
= va_arg (ap
, char **);
1731 *charpp
= pwm
->pinentry_tty
;
1735 arg1
= va_arg (ap
, char *);
1736 pwmd_free (pwm
->pinentry_tty
);
1737 pwm
->pinentry_tty
= arg1
? pwmd_strdup (arg1
) : NULL
;
1739 case PWMD_OPTION_PINENTRY_DISPLAY
:
1742 charpp
= va_arg (ap
, char **);
1743 *charpp
= pwm
->pinentry_display
;
1747 arg1
= va_arg (ap
, char *);
1748 pwmd_free (pwm
->pinentry_display
);
1749 pwm
->pinentry_display
= arg1
? pwmd_strdup (arg1
) : NULL
;
1751 case PWMD_OPTION_PINENTRY_TERM
:
1754 charpp
= va_arg (ap
, char **);
1755 *charpp
= pwm
->pinentry_term
;
1759 arg1
= va_arg (ap
, char *);
1760 pwmd_free (pwm
->pinentry_term
);
1761 pwm
->pinentry_term
= arg1
? pwmd_strdup (arg1
) : NULL
;
1763 case PWMD_OPTION_PINENTRY_ERROR
:
1766 charpp
= va_arg (ap
, char **);
1767 *charpp
= pwm
->pinentry_error
;
1771 arg1
= va_arg (ap
, char *);
1772 pwmd_free (pwm
->pinentry_error
);
1773 if (pwm
->disable_pinentry
)
1774 pwm
->pinentry_error
= arg1
? pwmd_strdup (arg1
) : NULL
;
1776 pwm
->pinentry_error
= arg1
? _percent_escape (arg1
) : NULL
;
1778 case PWMD_OPTION_PINENTRY_PROMPT
:
1781 charpp
= va_arg (ap
, char **);
1782 *charpp
= pwm
->pinentry_prompt
;
1786 arg1
= va_arg (ap
, char *);
1787 pwmd_free (pwm
->pinentry_prompt
);
1788 if (pwm
->disable_pinentry
)
1789 pwm
->pinentry_prompt
= arg1
? pwmd_strdup (arg1
) : NULL
;
1791 pwm
->pinentry_prompt
= arg1
? _percent_escape (arg1
) : NULL
;
1793 case PWMD_OPTION_PINENTRY_DESC
:
1796 charpp
= va_arg (ap
, char **);
1797 *charpp
= pwm
->pinentry_desc
;
1801 arg1
= va_arg (ap
, char *);
1802 pwmd_free (pwm
->pinentry_desc
);
1803 if (pwm
->disable_pinentry
)
1804 pwm
->pinentry_desc
= arg1
? pwmd_strdup (arg1
) : NULL
;
1806 pwm
->pinentry_desc
= arg1
? _percent_escape (arg1
) : NULL
;
1808 case PWMD_OPTION_PINENTRY_LC_CTYPE
:
1811 charpp
= va_arg (ap
, char **);
1812 *charpp
= pwm
->pinentry_lcctype
;
1816 arg1
= va_arg (ap
, char *);
1817 pwmd_free (pwm
->pinentry_lcctype
);
1818 pwm
->pinentry_lcctype
= arg1
? pwmd_strdup (arg1
) : NULL
;
1820 case PWMD_OPTION_PINENTRY_LC_MESSAGES
:
1823 charpp
= va_arg (ap
, char **);
1824 *charpp
= pwm
->pinentry_lcmessages
;
1828 arg1
= va_arg (ap
, char *);
1829 pwmd_free (pwm
->pinentry_lcmessages
);
1830 pwm
->pinentry_lcmessages
= arg1
? pwmd_strdup (arg1
) : NULL
;
1832 case PWMD_OPTION_KNOWNHOST_CB
:
1835 pwmd_knownhost_cb_t
*cb
= va_arg (ap
, pwmd_knownhost_cb_t
*);
1841 pwm
->kh_cb
= va_arg (ap
, pwmd_knownhost_cb_t
);
1843 case PWMD_OPTION_KNOWNHOST_DATA
:
1846 void **data
= va_arg (ap
, void **);
1848 *data
= pwm
->kh_data
;
1852 pwm
->kh_data
= va_arg (ap
, void *);
1854 case PWMD_OPTION_SSH_AGENT
:
1857 intp
= va_arg (ap
, int *);
1858 *intp
= pwm
->use_agent
;
1862 pwm
->use_agent
= va_arg (ap
, int);
1864 if (pwm
->use_agent
< 0 || pwm
->use_agent
> 1)
1867 rc
= GPG_ERR_INV_VALUE
;
1870 case PWMD_OPTION_SSH_PASSPHRASE
:
1872 return GPG_ERR_NOT_SUPPORTED
;
1873 pwmd_free (pwm
->ssh_passphrase
);
1874 pwm
->ssh_passphrase
= NULL
;
1875 arg1
= va_arg (ap
, char *);
1878 pwm
->ssh_passphrase
= pwmd_strdup (arg1
);
1879 if (!pwm
->ssh_passphrase
)
1880 return GPG_ERR_ENOMEM
;
1883 case PWMD_OPTION_SSH_NEEDS_PASSPHRASE
:
1886 intp
= va_arg (ap
, int *);
1887 *intp
= pwm
->needs_passphrase
;
1891 pwm
->needs_passphrase
= va_arg (ap
, int);
1893 if (pwm
->needs_passphrase
< 0 || pwm
->needs_passphrase
> 1)
1895 pwm
->needs_passphrase
= 0;
1896 rc
= GPG_ERR_INV_VALUE
;
1899 case PWMD_OPTION_TLS_VERIFY
:
1902 intp
= va_arg (ap
, int *);
1903 *intp
= pwm
->tls_verify
;
1907 pwm
->tls_verify
= va_arg (ap
, int);
1909 if (pwm
->tls_verify
< 0 || pwm
->tls_verify
> 1)
1911 pwm
->tls_verify
= 0;
1912 rc
= GPG_ERR_INV_VALUE
;
1915 case PWMD_OPTION_SOCKET_TIMEOUT
:
1918 intp
= va_arg (ap
, int *);
1919 *intp
= pwm
->socket_timeout
;
1923 pwm
->socket_timeout
= va_arg (ap
, int);
1924 if (pwm
->socket_timeout
< 0)
1926 pwm
->socket_timeout
= 0;
1927 rc
= GPG_ERR_INV_VALUE
;
1931 if (pwm
->tcp
&& pwm
->tcp
->ssh
&& pwm
->tcp
->ssh
->session
)
1933 pwm
->tcp
->ssh
->timeout
= pwm
->socket_timeout
;
1934 libssh2_session_set_timeout (pwm
->tcp
->ssh
->session
,
1935 pwm
->socket_timeout
* 1000);
1939 if (pwm
->tcp
&& pwm
->tcp
->tls
&& pwm
->tcp
->tls
->session
)
1940 pwm
->tcp
->tls
->timeout
= pwm
->socket_timeout
;
1943 case PWMD_OPTION_OVERRIDE_INQUIRE
:
1946 intp
= va_arg (ap
, int *);
1947 *intp
= pwm
->override_inquire
;
1951 pwm
->override_inquire
= va_arg (ap
, int);
1953 if (pwm
->override_inquire
< 0 || pwm
->override_inquire
> 1)
1955 pwm
->override_inquire
= 0;
1956 rc
= GPG_ERR_INV_VALUE
;
1960 rc
= GPG_ERR_UNKNOWN_OPTION
;
1968 pwmd_setopt (pwm_t
* pwm
, int opt
, ...)
1974 rc
= pwmd_get_set_opt (pwm
, opt
, 0, ap
);
1980 pwmd_getopt (pwm_t
*pwm
, int opt
, ...)
1986 rc
= pwmd_get_set_opt (pwm
, opt
, 1, ap
);
1992 pwmd_new (const char *name
, pwm_t
** pwm
)
1994 pwm_t
*h
= pwmd_calloc (1, sizeof (pwm_t
));
1998 return FINISH (GPG_ERR_ENOMEM
);
2002 h
->name
= pwmd_strdup (name
);
2006 return FINISH (GPG_ERR_ENOMEM
);
2011 h
->pinentry_timeout
= -1;
2012 h
->current_pinentry_timeout
= -1;
2013 h
->pinentry_tries
= 3;
2014 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
2015 h
->prot
= PWMD_IP_ANY
;
2018 if (isatty (STDOUT_FILENO
))
2021 int err
= ttyname_r (STDOUT_FILENO
, buf
, sizeof (buf
));
2025 h
->pinentry_tty
= pwmd_strdup (buf
);
2026 if (!h
->pinentry_tty
)
2028 rc
= GPG_ERR_ENOMEM
;
2034 if (getenv ("TERM") && h
->pinentry_tty
)
2036 h
->pinentry_term
= pwmd_strdup (getenv ("TERM"));
2037 if (!h
->pinentry_term
)
2039 rc
= GPG_ERR_ENOMEM
;
2044 if (getenv ("DISPLAY"))
2046 h
->pinentry_display
= pwmd_strdup (getenv ("DISPLAY"));
2047 if (!h
->pinentry_display
)
2049 rc
= GPG_ERR_ENOMEM
;
2054 update_pinentry_settings (h
);
2064 pwmd_free (void *ptr
)
2070 pwmd_malloc (size_t size
)
2072 return _xmalloc (size
);
2076 pwmd_calloc (size_t nmemb
, size_t size
)
2078 return _xcalloc (nmemb
, size
);
2082 pwmd_realloc (void *ptr
, size_t size
)
2084 return _xrealloc (ptr
, size
);
2088 pwmd_strdup (const char *str
)
2095 t
= _xmalloc ((len
+ 1) * sizeof (char));
2099 for (c
= 0; c
< len
; c
++)
2107 pwmd_strdup_printf (const char *fmt
, ...)
2118 len
= vsnprintf (NULL
, 0, fmt
, ap
);
2120 buf
= pwmd_malloc (++len
);
2122 vsnprintf (buf
, len
, fmt
, ap2
);
2129 pwmd_getpin (pwm_t
* pwm
, const char *filename
, char **result
,
2130 size_t * len
, pwmd_pinentry_t which
)
2132 #ifndef WITH_PINENTRY
2133 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
2137 command_start (pwm
);
2138 if (which
== PWMD_PINENTRY_CONFIRM
&& pwm
->disable_pinentry
)
2140 rc
= get_password (pwm
, NULL
, NULL
, which
, 1);
2144 rc
= _pwmd_getpin (pwm
, filename
, result
, len
, which
);
2152 return LIBPWMD_VERSION_STR
;
2160 #ifdef WITH_PINENTRY
2161 n
|= PWMD_FEATURE_PINENTRY
;
2164 n
|= PWMD_FEATURE_SSH
;
2167 n
|= PWMD_FEATURE_QUALITY
;
2170 n
|= PWMD_FEATURE_GNUTLS
;
2176 pwmd_fd (pwm_t
* pwm
, int *fd
)
2179 return FINISH (GPG_ERR_INV_ARG
);
2182 return FINISH (GPG_ERR_INV_STATE
);
2189 pwmd_set_pointer (pwm_t
*pwm
, void *data
)
2191 pwm
->user_data
= data
;
2195 pwmd_get_pointer (pwm_t
*pwm
)
2197 return pwm
->user_data
;
2201 pwmd_gnutls_error (pwm_t
*pwm
, const char **str
)
2206 if (str
&& pwm
&& pwm
->tls_error
)
2207 *str
= gnutls_strerror (pwm
->tls_error
);
2209 return pwm
? pwm
->tls_error
: 0;
2214 pwmd_cancel (pwm_t
*pwm
)
2217 return FINISH (GPG_ERR_INV_ARG
);
2219 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
2220 if (pwm
->fd
== -1 && !pwm
->tcp
)
2224 return FINISH (GPG_ERR_INV_STATE
);
2226 /* Can only cancel the connection for the time being. */
2228 return FINISH (GPG_ERR_INV_STATE
);
2235 pwmd_test_quality (const char *str
, double *result
)
2237 #ifndef WITH_QUALITY
2238 return GPG_ERR_NOT_IMPLEMENTED
;
2241 return GPG_ERR_INV_ARG
;
2243 *result
= ZxcvbnMatch (str
, NULL
, NULL
);