2 Copyright (C) 2006-2016 Ben Kibbey <bjk@luxsci.net>
4 This file is part of libpwmd.
6 This library is free software; you can redistribute it and/or
7 modify it under the terms of the GNU Lesser General Public
8 License as published by the Free Software Foundation; either
9 version 2.1 of the License, or (at your option) any later version.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301
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>
81 #define FINISH(rc) (gpg_err_source(rc) == GPG_ERR_SOURCE_UNKNOWN) \
90 static gpg_error_t
status_cb (void *data
, const char *line
);
93 hook_read (assuan_context_t ctx
, assuan_fd_t fd
, void *data
, size_t len
)
95 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
96 pwm_t
*pwm
= assuan_get_pointer (ctx
);
99 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->ssh
)
100 return read_hook_ssh (pwm
->tcp
->ssh
, fd
, data
, len
);
103 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->tls
)
104 return tls_read_hook (pwm
, fd
, data
, len
);
110 return read ((int) fd
, data
, len
);
114 hook_write (assuan_context_t ctx
, assuan_fd_t fd
, const void *data
,
118 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
119 pwm_t
*pwm
= assuan_get_pointer (ctx
);
122 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->ssh
)
123 return write_hook_ssh (pwm
->tcp
->ssh
, fd
, data
, len
);
126 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->tls
)
127 return tls_write_hook (pwm
, fd
, data
, len
);
133 /* libassuan cannot handle EAGAIN when doing writes. */
136 wrote
= write ((int) fd
, data
, len
);
137 if (wrote
== -1 && errno
== EAGAIN
)
140 while (wrote
== -1 && errno
== EAGAIN
);
146 hook_waitpid (assuan_context_t ctx
, pid_t pid
, int action
, int *status
,
151 return waitpid (pid
, status
, options
);
157 static int initialized
;
160 // May be called more than once.
161 gnutls_global_init ();
168 bindtextdomain ("libpwmd", LOCALEDIR
);
174 //gpgrt_set_alloc_func (_xrealloc_gpgrt);
188 gnutls_global_deinit ();
196 _connect_finalize (pwm_t
* pwm
)
201 int n
= assuan_get_active_fds (pwm
->ctx
, 0, active
, N_ARRAY (active
));
204 return GPG_ERR_EBADFD
;
208 pwm
->pinentry_pid
= -1;
211 rc
= pwmd_command (pwm
, &result
, NULL
, NULL
, NULL
, "GETINFO VERSION");
214 pwm
->version
= strtoul (result
, NULL
, 16);
218 if (!rc
&& pwm
->name
)
219 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION NAME=%s",
226 connect_uds (pwm_t
* pwm
, const char *path
)
228 char *socketpath
= NULL
;
234 return GPG_ERR_INV_ARG
;
236 pwbuf
= _getpwuid (&pw
);
238 return gpg_error_from_syserror ();
241 socketpath
= pwmd_strdup_printf ("%s/.pwmd/socket", pw
.pw_dir
);
243 socketpath
= _expand_homedir ((char *) path
, &pw
);
247 return GPG_ERR_ENOMEM
;
249 rc
= assuan_socket_connect (pwm
->ctx
, socketpath
, ASSUAN_INVALID_FD
, 0);
250 pwmd_free (socketpath
);
251 return rc
? rc
: _connect_finalize (pwm
);
255 init_handle (pwm_t
* pwm
)
258 static struct assuan_malloc_hooks mhooks
= {
259 pwmd_malloc
, pwmd_realloc
, pwmd_free
261 static struct assuan_system_hooks shooks
= {
262 ASSUAN_SYSTEM_HOOKS_VERSION
,
270 NULL
, //sendmsg both are used for FD passing
278 rc
= assuan_new_ext (&pwm
->ctx
, GPG_ERR_SOURCE_DEFAULT
, &mhooks
, NULL
,
283 assuan_set_pointer (pwm
->ctx
, pwm
);
284 assuan_ctx_set_system_hooks (pwm
->ctx
, &shooks
);
288 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
290 free_tcp (pwm_t
*pwm
)
292 struct tcp_s
*tcp
= pwm
->tcp
;
298 _free_ssh_conn (tcp
->ssh
);
304 pwmd_free (tcp
->host
);
307 freeaddrinfo (tcp
->addrs
);
311 pthread_cond_destroy (&tcp
->dns_cond
);
312 pthread_mutex_destroy (&tcp
->dns_mutex
);
318 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
320 resolve_host_thread (void *arg
)
323 struct addrinfo hints
= { 0 };
329 hints
.ai_family
= AF_UNSPEC
;
332 hints
.ai_family
= AF_INET
;
335 hints
.ai_family
= AF_INET6
;
339 hints
.ai_socktype
= SOCK_STREAM
;
340 snprintf (portstr
, sizeof (portstr
), "%i", pwm
->tcp
->port
);
341 int *n
= pwmd_malloc (sizeof (int));
342 pthread_cleanup_push (pwmd_free
, n
);
343 *n
= getaddrinfo (pwm
->tcp
->host
, portstr
, &hints
, &pwm
->tcp
->addrs
);
344 pthread_cleanup_pop (0);
345 pthread_cond_broadcast (&pwm
->tcp
->dns_cond
);
351 tcp_connect_common (pwm_t
* pwm
)
353 #define TS_TIMEOUT 50000000L
360 n
= pthread_create (&tid
, NULL
, resolve_host_thread
, pwm
);
362 return gpg_error_from_errno (n
);
364 pthread_mutex_lock (&pwm
->tcp
->dns_mutex
);
371 clock_gettime (CLOCK_REALTIME
, &ts
);
372 if (ts
.tv_nsec
+ TS_TIMEOUT
>= 1000000000LL) {
377 ts
.tv_nsec
+= TS_TIMEOUT
;
381 #ifdef HAVE_PTHREAD_CANCEL
382 pthread_cancel (tid
);
383 pthread_join (tid
, NULL
);
385 pthread_join (tid
, (void **)&result
);
388 return GPG_ERR_CANCELED
;
391 n
= pthread_cond_timedwait (&pwm
->tcp
->dns_cond
, &pwm
->tcp
->dns_mutex
,
395 if (pwm
->socket_timeout
&& ts
.tv_sec
- now
>= pwm
->socket_timeout
)
397 #ifdef HAVE_PTHREAD_CANCEL
398 pthread_cancel (tid
);
399 pthread_join (tid
, NULL
);
401 pthread_join (tid
, (void **)&result
);
404 return GPG_ERR_ETIMEDOUT
;
411 #ifdef HAVE_PTHREAD_CANCEL
412 pthread_cancel (tid
);
413 pthread_join (tid
, NULL
);
415 pthread_join (tid
, (void **)&result
);
418 return gpg_error_from_errno (n
);
421 pthread_join (tid
, (void **)&result
);
428 return GPG_ERR_UNKNOWN_HOST
; //FIXME
430 for (pwm
->tcp
->addr
= pwm
->tcp
->addrs
; pwm
->tcp
->addr
;
431 pwm
->tcp
->addr
= pwm
->tcp
->addrs
->ai_next
)
433 pwm
->fd
= socket (pwm
->tcp
->addr
->ai_family
, SOCK_STREAM
, 0);
436 rc
= gpg_error_from_syserror ();
437 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
)
442 if (fcntl (pwm
->fd
, F_SETFL
, O_NONBLOCK
) == -1)
444 rc
= gpg_error_from_syserror ();
448 if (connect (pwm
->fd
, pwm
->tcp
->addr
->ai_addr
,
449 pwm
->tcp
->addr
->ai_family
== AF_INET6
450 ? sizeof (struct sockaddr_in6
)
451 : sizeof (struct sockaddr
)) == -1)
455 unsigned elapsed
= 0;
457 rc
= gpg_error_from_syserror ();
458 if (gpg_err_code (rc
) != GPG_ERR_EINPROGRESS
)
462 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
)
471 FD_SET (pwm
->fd
, &wfds
);
472 n
= select (pwm
->fd
+1, NULL
, &wfds
, NULL
, &tv
);
474 if (!n
|| pwm
->cancel
)
477 rc
= gpg_error (GPG_ERR_CANCELED
);
478 else if (++elapsed
>= pwm
->socket_timeout
)
479 rc
= gpg_error (GPG_ERR_ETIMEDOUT
);
485 socklen_t len
= sizeof(int);
487 getsockopt (pwm
->fd
, SOL_SOCKET
, SO_ERROR
, &n
, &len
);
489 rc
= gpg_error_from_errno (n
);
492 rc
= gpg_error_from_syserror ();
498 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
499 || gpg_err_code (rc
) == GPG_ERR_ETIMEDOUT
511 if (fcntl (pwm
->fd
, F_SETFL
, 0) == -1)
512 rc
= gpg_error_from_syserror ();
519 command_start (pwm_t
*pwm
)
525 pwmd_connect (pwm_t
* pwm
, const char *url
, ...)
531 return FINISH (GPG_ERR_INV_ARG
);
534 rc
= init_handle (pwm
);
541 if (!(pwm
->opts
& OPT_SIGPIPE
))
542 signal (SIGPIPE
, SIG_IGN
);
547 rc
= GPG_ERR_UNSUPPORTED_PROTOCOL
;
549 if (p
&& (*p
== '/' || *p
== '~'))
550 rc
= connect_uds (pwm
, p
);
551 else if (!p
|| !strncmp (p
, "file://", 7))
555 #ifdef DEFAULT_PWMD_SOCKET
557 p
= DEFAULT_PWMD_SOCKET
;
559 rc
= connect_uds (pwm
, p
);
561 else if (!strncmp (p
, "ssh://", 6) || !strncmp (p
, "ssh6://", 7) ||
562 !strncmp (p
, "ssh4://", 7))
565 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
569 char *username
= NULL
;
571 if (!strncmp (p
, "ssh6://", 7))
573 pwm
->prot
= PWMD_IPV6
;
576 else if (!strncmp (p
, "ssh4://", 7))
578 pwm
->prot
= PWMD_IPV4
;
583 pwm
->prot
= PWMD_IP_ANY
;
587 rc
= _parse_ssh_url (p
, &host
, &port
, &username
);
591 char *identity
= NULL
;
592 char *knownhosts
= NULL
;
595 identity
= va_arg (ap
, char *);
597 if (!identity
&& !pwm
->use_agent
)
598 rc
= GPG_ERR_INV_ARG
;
600 knownhosts
= va_arg (ap
, char *);
605 rc
= _do_ssh_connect (pwm
, host
, port
, identity
, username
,
609 rc
= _connect_finalize (pwm
);
616 pwmd_free (username
);
617 pwm
->local_pinentry
= 1;
618 pwmd_free (pwm
->ssh_passphrase
);
619 pwm
->ssh_passphrase
= NULL
;
622 else if (!strncmp (p
, "tls://", 6) || !strncmp (p
, "tls6://", 7) ||
623 !strncmp (p
, "tls4://", 7))
626 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
631 if (!strncmp (p
, "tls6://", 7))
633 pwm
->prot
= PWMD_IPV6
;
636 else if (!strncmp (p
, "tls4://", 7))
638 pwm
->prot
= PWMD_IPV4
;
643 pwm
->prot
= PWMD_IP_ANY
;
647 rc
= tls_parse_url (p
, &host
, &port
);
651 char *clientcert
= NULL
;
652 char *clientkey
= NULL
;
654 char *server_fp
= NULL
;
657 clientcert
= va_arg (ap
, char *);
660 rc
= GPG_ERR_INV_ARG
;
663 clientkey
= va_arg (ap
, char *);
665 rc
= GPG_ERR_INV_ARG
;
668 cacert
= va_arg (ap
, char *);
670 rc
= GPG_ERR_INV_ARG
;
672 server_fp
= va_arg (ap
, char *);
679 rc
= tls_connect (pwm
, host
, port
, clientcert
, clientkey
, cacert
,
680 pwm
->tls_priority
, server_fp
, pwm
->tls_verify
);
683 rc
= _connect_finalize (pwm
);
690 pwm
->local_pinentry
= 1;
701 disconnect (pwm_t
* pwm
)
707 assuan_release (pwm
->ctx
);
709 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
718 pwmd_close (pwm_t
* pwm
)
724 pwmd_free (pwm
->pinentry_error
);
725 pwmd_free (pwm
->pinentry_desc
);
726 pwmd_free (pwm
->pinentry_prompt
);
727 pwmd_free (pwm
->pinentry_tty
);
728 pwmd_free (pwm
->pinentry_display
);
729 pwmd_free (pwm
->pinentry_term
);
730 pwmd_free (pwm
->pinentry_lcctype
);
731 pwmd_free (pwm
->pinentry_lcmessages
);
732 pwmd_free (pwm
->filename
);
733 pwmd_free (pwm
->name
);
734 pwmd_free (pwm
->passphrase_info
);
735 pwmd_free (pwm
->passphrase_hint
);
736 pwmd_free (pwm
->ssh_passphrase
);
737 pwmd_free (pwm
->tls_priority
);
741 _pinentry_disconnect (pwm
);
748 inquire_realloc_cb (void *data
, const void *buffer
, size_t len
)
750 membuf_t
*mem
= (membuf_t
*) data
;
756 if ((p
= pwmd_realloc (mem
->buf
, mem
->len
+ len
)) == NULL
)
757 return gpg_error (GPG_ERR_ENOMEM
);
760 memcpy ((char *) mem
->buf
+ mem
->len
, buffer
, len
);
766 get_password (pwm_t
* pwm
, char **result
, size_t * len
,
767 pwmd_pinentry_t w
, int echo
)
769 char buf
[ASSUAN_LINELENGTH
+1] = { 0 }, *p
;
770 struct termios told
, tnew
;
779 if (!isatty (STDIN_FILENO
))
781 fprintf (stderr
, N_("Input is not from a terminal! Failing.\n"));
782 return GPG_ERR_ENOTTY
;
787 if (tcgetattr (STDIN_FILENO
, &told
) == -1)
788 return gpg_error_from_syserror ();
790 memcpy (&tnew
, &told
, sizeof (struct termios
));
791 tnew
.c_lflag
&= ~(ECHO
);
792 tnew
.c_lflag
|= ICANON
| ECHONL
;
794 if (tcsetattr (STDIN_FILENO
, TCSANOW
, &tnew
) == -1)
798 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
799 return gpg_error_from_errno (n
);
803 if (pwm
->passphrase_hint
)
804 fprintf(stderr
, N_("Key info: %s\n"), pwm
->passphrase_hint
);
808 case PWMD_PINENTRY_OPEN
:
809 fprintf (stderr
, N_("Passphrase for %s: "), pwm
->filename
);
811 case PWMD_PINENTRY_OPEN_FAILED
:
812 fprintf (stderr
, N_("Invalid passphrase. Passphrase for %s: "),
815 case PWMD_PINENTRY_SAVE
:
816 fprintf (stderr
, N_("New passphrase for %s: "), pwm
->filename
);
818 case PWMD_PINENTRY_SAVE_CONFIRM
:
819 fprintf (stderr
, N_("Repeat passphrase: "));
821 case PWMD_PINENTRY_CONFIRM
:
822 if (pwm
->pinentry_desc
)
823 fprintf (stderr
, "%s", pwm
->pinentry_desc
);
825 if (pwm
->pinentry_prompt
)
826 fprintf (stderr
, "%s", pwm
->pinentry_prompt
);
828 fprintf(stderr
, N_("Confirm [y/N]:"));
833 p
= fgets (buf
, sizeof (buf
), stdin
);
836 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
838 if (!p
|| feof (stdin
))
841 return GPG_ERR_CANCELED
;
844 /* Strip the newline character. */
845 p
[strlen (p
) - 1] = 0;
849 if (w
== PWMD_PINENTRY_CONFIRM
)
851 if (*p
!= 'y' && *p
!= 'Y')
852 return GPG_ERR_CANCELED
;
856 key
= pwmd_strdup_printf ("%s", p
);
857 wipememory (buf
, 0, sizeof (buf
));
859 return GPG_ERR_ENOMEM
;
869 if (w
== PWMD_PINENTRY_CONFIRM
)
870 return GPG_ERR_CANCELED
;
872 /* To satisfy inquire_cb(). */
874 *result
= pwmd_strdup ("");
884 pwmd_password (pwm_t
* pwm
, const char *keyword
, char **data
, size_t * size
)
887 int new_password
= 0;
888 char *password
= NULL
, *newpass
= NULL
;
899 if (!strcmp (keyword
, "NEW_PASSPHRASE"))
902 if (!new_password
&& pwm
->pinentry_try
)
906 if (pwm
->disable_pinentry
)
908 rc
= get_password (pwm
, &password
, size
,
909 new_password
? PWMD_PINENTRY_SAVE
:
910 error
? PWMD_PINENTRY_OPEN_FAILED
:
911 PWMD_PINENTRY_OPEN
, 0);
912 if (!rc
&& new_password
)
913 rc
= get_password (pwm
, &newpass
, size
, PWMD_PINENTRY_SAVE_CONFIRM
,
918 pwmd_pinentry_t which
;
922 ? PWMD_PINENTRY_SAVE_FAILED
: PWMD_PINENTRY_OPEN_FAILED
;
924 which
= new_password
? PWMD_PINENTRY_SAVE
: PWMD_PINENTRY_OPEN
;
926 rc
= pwmd_getpin (pwm
, pwm
->filename
, &password
, size
, which
);
927 if (!rc
&& new_password
)
928 rc
= pwmd_getpin (pwm
, pwm
->filename
, &newpass
, size
,
929 PWMD_PINENTRY_SAVE_CONFIRM
);
932 if (!rc
&& new_password
)
934 if ((!password
&& newpass
) || (!newpass
&& password
)
935 || (newpass
&& password
&& strcmp (newpass
, password
)))
937 if (pwm
->disable_pinentry
)
938 fprintf (stderr
, N_("Passphrases do not match.\n"));
940 pwmd_free (password
);
942 password
= newpass
= NULL
;
948 (void) pwmd_getpin (pwm
, pwm
->filename
, NULL
, NULL
, PWMD_PINENTRY_CLOSE
);
953 pwmd_free (password
);
959 inquire_cb (void *data
, const char *keyword
)
961 pwm_t
*pwm
= (pwm_t
*) data
;
966 int new_password
= 0;
968 if (!strcmp (keyword
, "PASSPHRASE") || !strcmp (keyword
, "SIGN_PASSPHRASE"))
970 else if (!strcmp (keyword
, "NEW_PASSPHRASE") || !strcmp (keyword
, "GENKEY"))
973 /* Shouldn't get this far without a callback. */
974 if (!pwm
->override_inquire
&& !pwm
->inquire_func
975 && !is_password
&& !new_password
)
976 return gpg_error (GPG_ERR_ASS_NO_INQUIRE_CB
);
985 if (!pwm
->override_inquire
&& (is_password
|| new_password
))
988 rc
= pwmd_password (data
, keyword
, &result
, &len
);
993 rc
= pwm
->inquire_func (pwm
->inquire_data
, keyword
, rc
, &result
,
996 /* gpg will truncate a passphrase at the first nil byte which may be bad
997 * for generated key files. */
998 if ((!rc
|| gpg_err_code (rc
) == GPG_ERR_EOF
)
999 && (is_password
|| new_password
))
1001 if (len
&& result
&& *result
)
1003 for (size_t n
= 0; n
< len
; n
++)
1005 if (result
[n
] == 0 && n
+1 != len
)
1006 rc
= GPG_ERR_INV_PASSPHRASE
;
1012 if (rc
&& gpg_err_code (rc
) != GPG_ERR_EOF
)
1014 #ifndef LIBASSUAN_2_1_0
1015 gpg_error_t trc
= rc
;
1017 /* Cancel this inquire. */
1018 rc
= assuan_send_data (pwm
->ctx
, NULL
, 1);
1024 /* There is a bug (or feature?) in assuan_send_data() that
1025 * when cancelling an inquire the next read from the server is
1026 * not done until the next command making the next command
1027 * fail with GPG_ERR_ASS_UNEXPECTED_CMD.
1029 rc
= assuan_read_line (pwm
->ctx
, &line
, &len
);
1031 /* Restore the original error. This differs from the error
1032 * returned from the pwmd command (GPG_ERR_CANCELED). This
1033 * error is returned to the calling function.
1042 if (gpg_err_code (rc
) == GPG_ERR_EOF
|| !rc
)
1044 if (len
<= 0 && !result
)
1049 else if ((len
<= 0 && result
) || (len
&& !result
))
1051 rc
= gpg_error (GPG_ERR_INV_ARG
);
1055 if (pwm
->inquire_maxlen
1056 && pwm
->inquire_sent
+ len
> pwm
->inquire_maxlen
)
1058 rc
= gpg_error (GPG_ERR_TOO_LARGE
);
1060 rc
= pwm
->inquire_func (pwm
->inquire_data
, keyword
, rc
,
1065 arc
= assuan_send_data (pwm
->ctx
, result
, len
);
1066 if (gpg_err_code (rc
) == GPG_ERR_EOF
)
1079 pwm
->inquire_sent
+= len
;
1081 if (pwm
->status_func
)
1083 char buf
[ASSUAN_LINELENGTH
];
1085 snprintf (buf
, sizeof (buf
), "XFER %zu %zu", pwm
->inquire_sent
,
1086 pwm
->inquire_total
);
1087 rc
= pwm
->status_func (pwm
->status_data
, buf
);
1097 pwm
->inquire_maxlen
= pwm
->inquire_sent
= 0;
1102 parse_assuan_line (pwm_t
* pwm
)
1108 rc
= assuan_read_line (pwm
->ctx
, &line
, &len
);
1111 if (line
[0] == 'O' && line
[1] == 'K' &&
1112 (line
[2] == 0 || line
[2] == ' '))
1115 else if (line
[0] == '#')
1118 else if (line
[0] == 'S' && (line
[1] == 0 || line
[1] == ' '))
1120 rc
= status_cb (pwm
, line
[1] == 0 ? line
+ 1 : line
+ 2);
1122 else if (line
[0] == 'E' && line
[1] == 'R' && line
[2] == 'R' &&
1123 (line
[3] == 0 || line
[3] == ' '))
1126 rc
= strtol (line
, NULL
, 10);
1134 reset_handle (pwm_t
*pwm
)
1138 pwm
->pinentry_disabled
= 0;
1139 #ifdef WITH_PINENTRY
1141 _pinentry_disconnect (pwm
);
1143 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1154 pwmd_disconnect (pwm_t
* pwm
)
1157 return FINISH (GPG_ERR_INV_ARG
);
1159 command_start (pwm
);
1162 return FINISH (GPG_ERR_INV_STATE
);
1169 /* Note that this should only be called when not in a command. */
1171 pwmd_process (pwm_t
* pwm
)
1175 struct timeval tv
= { 0, 0 };
1178 if (!pwm
|| pwm
->fd
== -1)
1179 return FINISH (GPG_ERR_INV_ARG
);
1181 return FINISH (GPG_ERR_INV_STATE
);
1184 FD_SET (pwm
->fd
, &fds
);
1185 n
= select (pwm
->fd
+ 1, &fds
, NULL
, NULL
, &tv
);
1188 return FINISH (gpg_error_from_syserror ());
1192 if (FD_ISSET (pwm
->fd
, &fds
))
1193 rc
= parse_assuan_line (pwm
);
1196 while (!rc
&& assuan_pending_line (pwm
->ctx
))
1197 rc
= parse_assuan_line (pwm
);
1199 #if defined (WITH_SSH) || defined (WITH_GNUTLS)
1200 if (gpg_err_code (rc
) == GPG_ERR_EOF
&& pwm
->tcp
)
1211 status_cb (void *data
, const char *line
)
1215 if (!strncmp (line
, "INQUIRE_MAXLEN ", 15))
1216 pwm
->inquire_maxlen
= strtol (line
+ 15, NULL
, 10);
1217 else if (!strncmp (line
, "PASSPHRASE_HINT ", 16))
1219 pwmd_free (pwm
->passphrase_hint
);
1220 pwm
->passphrase_hint
= pwmd_strdup (line
+16);
1222 else if (!strncmp (line
, "PASSPHRASE_INFO ", 16))
1224 pwmd_free (pwm
->passphrase_info
);
1225 pwm
->passphrase_info
= pwmd_strdup (line
+16);
1228 else if (!strcmp (line
, "REHANDSHAKE"))
1233 ret
= tls_read_hook (pwm
, pwm
->fd
, buf
, sizeof (buf
));
1236 pwm
->tls_error
= ret
;
1237 return GPG_ERR_GENERAL
;
1242 if (pwm
->status_func
)
1243 return pwm
->status_func (pwm
->status_data
, line
);
1249 _assuan_command (pwm_t
* pwm
, assuan_context_t ctx
,
1250 char **result
, size_t * len
, const char *cmd
)
1256 return FINISH (GPG_ERR_INV_ARG
);
1258 if (strlen (cmd
) >= ASSUAN_LINELENGTH
+ 1)
1259 return FINISH (GPG_ERR_LINE_TOO_LONG
);
1263 rc
= assuan_transact (ctx
, cmd
, inquire_realloc_cb
, &data
,
1265 pwm
->pctx
== ctx
? pwm
->_inquire_func
: inquire_cb
,
1266 pwm
->pctx
== ctx
? pwm
->_inquire_data
: pwm
,
1276 pwmd_free (data
.buf
);
1284 inquire_realloc_cb (&data
, "", 1);
1287 *result
= (char *) data
.buf
;
1289 pwmd_free (data
.buf
);
1296 pwm
->inquire_maxlen
= 0;
1301 pwmd_command_ap (pwm_t
* pwm
, char **result
, size_t * rlen
,
1302 pwmd_inquire_cb_t func
, void *user
, const char *cmd
,
1310 return GPG_ERR_INV_ARG
;
1312 command_start (pwm
);
1321 return FINISH (GPG_ERR_INV_ARG
);
1323 return FINISH (GPG_ERR_INV_STATE
);
1326 * C99 allows the dst pointer to be null which will calculate the length
1327 * of the would-be result and return it.
1330 len
= vsnprintf (NULL
, 0, cmd
, ap
) + 1;
1331 buf
= (char *) pwmd_malloc (len
);
1335 return FINISH (GPG_ERR_ENOMEM
);
1338 len
= vsnprintf (buf
, len
, cmd
, ap2
);
1341 if (buf
[strlen (buf
) - 1] == '\n')
1342 buf
[strlen (buf
) - 1] = 0;
1343 if (buf
[strlen (buf
) - 1] == '\r')
1344 buf
[strlen (buf
) - 1] = 0;
1346 pwm
->inquire_func
= func
;
1347 pwm
->inquire_data
= user
;
1348 pwm
->inquire_sent
= 0;
1349 gpg_error_t rc
= _assuan_command (pwm
, pwm
->ctx
, result
, rlen
, buf
);
1355 pwmd_command (pwm_t
* pwm
, char **result
, size_t * len
,
1356 pwmd_inquire_cb_t func
, void *user
, const char *cmd
, ...)
1367 return FINISH (GPG_ERR_INV_ARG
);
1369 return FINISH (GPG_ERR_INV_STATE
);
1372 gpg_error_t rc
= pwmd_command_ap (pwm
, result
, len
, func
, user
, cmd
, ap
);
1378 send_pinentry_timeout (pwm_t
*pwm
)
1382 if ((pwm
->pinentry_timeout
>= 0
1383 && pwm
->pinentry_timeout
!= pwm
->current_pinentry_timeout
)
1384 || (pwm
->pinentry_timeout
== -1
1385 && pwm
->pinentry_timeout
!= pwm
->current_pinentry_timeout
))
1387 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
,
1388 "OPTION pinentry-timeout=%i",
1389 pwm
->pinentry_timeout
);
1391 pwm
->current_pinentry_timeout
= pwm
->pinentry_timeout
;
1398 send_pinentry_options (pwm_t
* pwm
)
1402 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
,
1403 "OPTION disable-pinentry=0");
1404 if (!rc
&& pwm
->pinentry_tty
)
1405 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION TTYNAME=%s",
1408 if (!rc
&& pwm
->pinentry_term
)
1409 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION TTYTYPE=%s",
1410 pwm
->pinentry_term
);
1412 if (!rc
&& pwm
->pinentry_display
)
1413 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION DISPLAY=%s",
1414 pwm
->pinentry_display
);
1416 if (!rc
&& pwm
->pinentry_desc
)
1417 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION DESC=%s",
1418 pwm
->pinentry_desc
);
1420 if (!rc
&& pwm
->pinentry_lcctype
)
1421 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION LC_CTYPE=%s",
1422 pwm
->pinentry_lcctype
);
1424 if (!rc
&& pwm
->pinentry_lcmessages
)
1425 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION LC_MESSAGES=%s",
1426 pwm
->pinentry_lcmessages
);
1429 rc
= send_pinentry_timeout (pwm
);
1435 pwmd_socket_type (pwm_t
* pwm
, pwmd_socket_t
* result
)
1437 if (!pwm
|| !result
)
1438 return FINISH (GPG_ERR_INV_ARG
);
1440 *result
= PWMD_SOCKET_LOCAL
;
1443 return FINISH (GPG_ERR_INV_STATE
);
1445 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1447 if (pwm
->tcp
&& pwm
->tcp
->ssh
)
1448 *result
= PWMD_SOCKET_SSH
;
1451 if (pwm
->tcp
&& pwm
->tcp
->tls
)
1452 *result
= PWMD_SOCKET_TLS
;
1459 disable_pinentry (pwm_t
*pwm
, int *disable
)
1462 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1463 int no_pinentry
= pwm
->disable_pinentry
|| pwm
->tcp
|| pwm
->local_pinentry
;
1465 int no_pinentry
= pwm
->disable_pinentry
|| pwm
->local_pinentry
;
1469 *disable
= no_pinentry
;
1471 if (pwm
->pinentry_disabled
&& no_pinentry
)
1473 else if (!pwm
->pinentry_disabled
&& !no_pinentry
)
1476 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION disable-pinentry=%i",
1479 pwm
->pinentry_disabled
= no_pinentry
;
1485 pwmd_open (pwm_t
* pwm
, const char *filename
, pwmd_inquire_cb_t cb
,
1489 int no_pinentry
= 0;
1491 if (!pwm
|| !filename
|| !*filename
)
1492 return FINISH (GPG_ERR_INV_ARG
);
1495 return FINISH (GPG_ERR_INV_STATE
);
1497 command_start (pwm
);
1498 rc
= disable_pinentry (pwm
, &no_pinentry
);
1499 if (!rc
&& !no_pinentry
)
1500 rc
= send_pinentry_options (pwm
);
1504 pwm
->pinentry_try
= 0;
1505 pwmd_free (pwm
->filename
);
1506 pwm
->filename
= pwmd_strdup (filename
);
1510 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
, "OPEN %s%s",
1511 (pwm
->opts
& OPT_LOCK_ON_OPEN
) ? "--lock " : "",
1514 while (gpg_err_code (rc
) == GPG_ERR_BAD_PASSPHRASE
1515 && pwm
->pinentry_disabled
1516 && ++pwm
->pinentry_try
< pwm
->pinentry_tries
);
1518 pwm
->pinentry_try
= 0;
1522 pwmd_free (pwm
->filename
);
1523 pwm
->filename
= NULL
;
1527 pwmd_free (pwm
->passphrase_hint
);
1528 pwmd_free (pwm
->passphrase_info
);
1529 pwm
->passphrase_info
= pwm
->passphrase_hint
= NULL
;
1534 do_pwmd_save_passwd (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
,
1535 void *data
, int which
)
1538 int no_pinentry
= 0;
1541 return FINISH (GPG_ERR_INV_ARG
);
1543 return FINISH (GPG_ERR_INV_STATE
);
1545 command_start (pwm
);
1546 rc
= disable_pinentry (pwm
, &no_pinentry
);
1547 if (!rc
&& !no_pinentry
)
1548 rc
= send_pinentry_options (pwm
);
1552 if (which
== PWMD_WHICH_SAVE
)
1553 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
, "SAVE %s", args
? args
: "");
1554 else if (which
== PWMD_WHICH_PASSWD
)
1555 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
, "PASSWD %s", args
? args
: "");
1556 else if (which
== PWMD_WHICH_GENKEY
)
1557 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
, "GENKEY %s", args
? args
: "");
1560 pwmd_free (pwm
->passphrase_hint
);
1561 pwmd_free (pwm
->passphrase_info
);
1562 pwm
->passphrase_info
= pwm
->passphrase_hint
= NULL
;
1567 pwmd_passwd (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
, void *data
)
1569 return do_pwmd_save_passwd (pwm
, args
, cb
, data
, PWMD_WHICH_PASSWD
);
1573 pwmd_save (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
, void *data
)
1575 return do_pwmd_save_passwd (pwm
, args
, cb
, data
, PWMD_WHICH_SAVE
);
1579 pwmd_genkey (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
, void *data
)
1581 return do_pwmd_save_passwd (pwm
, args
, cb
, data
, PWMD_WHICH_GENKEY
);
1585 pwmd_get_set_opt (pwm_t
*pwm
, pwmd_option_t opt
, int get
, va_list ap
)
1589 char *arg1
, **charpp
;
1593 return GPG_ERR_INV_ARG
;
1595 command_start (pwm
);
1598 case PWMD_OPTION_SERVER_VERSION
:
1600 return GPG_ERR_NOT_SUPPORTED
;
1603 rc
= GPG_ERR_INV_STATE
;
1606 unsigned *u
= va_arg (ap
, unsigned *);
1611 case PWMD_OPTION_SIGPIPE
:
1614 intp
= va_arg (ap
, int *);
1615 *intp
= pwm
->opts
& OPT_SIGPIPE
? 1 : 0;
1619 n
= va_arg (ap
, int);
1622 rc
= GPG_ERR_INV_VALUE
;
1627 pwm
->opts
|= OPT_SIGPIPE
;
1629 pwm
->opts
&= ~OPT_SIGPIPE
;
1632 case PWMD_OPTION_LOCK_ON_OPEN
:
1635 intp
= va_arg (ap
, int *);
1636 *intp
= pwm
->opts
& OPT_LOCK_ON_OPEN
? 1 : 0;
1640 n
= va_arg (ap
, int);
1643 rc
= GPG_ERR_INV_VALUE
;
1648 pwm
->opts
|= OPT_LOCK_ON_OPEN
;
1650 pwm
->opts
&= ~OPT_LOCK_ON_OPEN
;
1653 case PWMD_OPTION_INQUIRE_TOTAL
:
1656 sizetp
= va_arg (ap
, size_t *);
1657 *sizetp
= pwm
->inquire_total
;
1661 pwm
->inquire_total
= va_arg (ap
, size_t);
1663 case PWMD_OPTION_STATUS_CB
:
1666 pwmd_status_cb_t
*cb
= va_arg (ap
, pwmd_status_cb_t
*);
1668 *cb
= pwm
->status_func
;
1672 pwm
->status_func
= va_arg (ap
, pwmd_status_cb_t
);
1674 case PWMD_OPTION_STATUS_DATA
:
1677 void **data
= va_arg (ap
, void **);
1679 *data
= pwm
->status_data
;
1683 pwm
->status_data
= va_arg (ap
, void *);
1685 case PWMD_OPTION_NO_PINENTRY
:
1688 intp
= va_arg (ap
, int *);
1689 *intp
= pwm
->disable_pinentry
;
1693 n
= va_arg (ap
, int);
1695 rc
= GPG_ERR_INV_VALUE
;
1697 pwm
->disable_pinentry
= n
;
1699 case PWMD_OPTION_LOCAL_PINENTRY
:
1702 intp
= va_arg (ap
, int *);
1703 *intp
= pwm
->local_pinentry
;
1707 n
= va_arg (ap
, int);
1709 rc
= GPG_ERR_INV_VALUE
;
1711 pwm
->local_pinentry
= n
;
1714 case PWMD_OPTION_PINENTRY_TIMEOUT
:
1717 intp
= va_arg (ap
, int *);
1718 *intp
= pwm
->pinentry_timeout
;
1722 n
= va_arg (ap
, int);
1724 rc
= GPG_ERR_INV_VALUE
;
1726 pwm
->pinentry_timeout
= n
;
1728 case PWMD_OPTION_PINENTRY_TRIES
:
1731 intp
= va_arg (ap
, int *);
1732 *intp
= pwm
->pinentry_tries
;
1736 n
= va_arg (ap
, int);
1738 rc
= GPG_ERR_INV_VALUE
;
1740 pwm
->pinentry_tries
= n
;
1742 case PWMD_OPTION_PINENTRY_PATH
:
1745 charpp
= va_arg (ap
, char **);
1746 *charpp
= pwm
->pinentry_path
;
1750 arg1
= va_arg (ap
, char *);
1751 pwmd_free (pwm
->pinentry_path
);
1752 pwm
->pinentry_path
= arg1
? _expand_homedir (arg1
, NULL
) : NULL
;
1754 case PWMD_OPTION_PINENTRY_TTY
:
1757 charpp
= va_arg (ap
, char **);
1758 *charpp
= pwm
->pinentry_tty
;
1762 arg1
= va_arg (ap
, char *);
1763 pwmd_free (pwm
->pinentry_tty
);
1764 pwm
->pinentry_tty
= arg1
? pwmd_strdup (arg1
) : NULL
;
1766 case PWMD_OPTION_PINENTRY_DISPLAY
:
1769 charpp
= va_arg (ap
, char **);
1770 *charpp
= pwm
->pinentry_display
;
1774 arg1
= va_arg (ap
, char *);
1775 pwmd_free (pwm
->pinentry_display
);
1776 pwm
->pinentry_display
= arg1
&& *arg1
? pwmd_strdup (arg1
) : NULL
;
1777 if (!pwm
->pinentry_display
)
1778 unsetenv ("DISPLAY");
1780 case PWMD_OPTION_PINENTRY_TERM
:
1783 charpp
= va_arg (ap
, char **);
1784 *charpp
= pwm
->pinentry_term
;
1788 arg1
= va_arg (ap
, char *);
1789 pwmd_free (pwm
->pinentry_term
);
1790 pwm
->pinentry_term
= arg1
&& *arg1
? pwmd_strdup (arg1
) : NULL
;
1791 if (pwm
->pinentry_term
)
1794 case PWMD_OPTION_PINENTRY_ERROR
:
1797 charpp
= va_arg (ap
, char **);
1798 *charpp
= pwm
->pinentry_error
;
1802 arg1
= va_arg (ap
, char *);
1803 pwmd_free (pwm
->pinentry_error
);
1804 if (pwm
->disable_pinentry
)
1805 pwm
->pinentry_error
= arg1
? pwmd_strdup (arg1
) : NULL
;
1807 pwm
->pinentry_error
= arg1
? _percent_escape (arg1
) : NULL
;
1809 case PWMD_OPTION_PINENTRY_PROMPT
:
1812 charpp
= va_arg (ap
, char **);
1813 *charpp
= pwm
->pinentry_prompt
;
1817 arg1
= va_arg (ap
, char *);
1818 pwmd_free (pwm
->pinentry_prompt
);
1819 if (pwm
->disable_pinentry
)
1820 pwm
->pinentry_prompt
= arg1
? pwmd_strdup (arg1
) : NULL
;
1822 pwm
->pinentry_prompt
= arg1
? _percent_escape (arg1
) : NULL
;
1824 case PWMD_OPTION_PINENTRY_DESC
:
1827 charpp
= va_arg (ap
, char **);
1828 *charpp
= pwm
->pinentry_desc
;
1832 arg1
= va_arg (ap
, char *);
1833 pwmd_free (pwm
->pinentry_desc
);
1834 if (pwm
->disable_pinentry
)
1835 pwm
->pinentry_desc
= arg1
? pwmd_strdup (arg1
) : NULL
;
1837 pwm
->pinentry_desc
= arg1
? _percent_escape (arg1
) : NULL
;
1839 case PWMD_OPTION_PINENTRY_LC_CTYPE
:
1842 charpp
= va_arg (ap
, char **);
1843 *charpp
= pwm
->pinentry_lcctype
;
1847 arg1
= va_arg (ap
, char *);
1848 pwmd_free (pwm
->pinentry_lcctype
);
1849 pwm
->pinentry_lcctype
= arg1
? pwmd_strdup (arg1
) : NULL
;
1851 case PWMD_OPTION_PINENTRY_LC_MESSAGES
:
1854 charpp
= va_arg (ap
, char **);
1855 *charpp
= pwm
->pinentry_lcmessages
;
1859 arg1
= va_arg (ap
, char *);
1860 pwmd_free (pwm
->pinentry_lcmessages
);
1861 pwm
->pinentry_lcmessages
= arg1
? pwmd_strdup (arg1
) : NULL
;
1863 case PWMD_OPTION_KNOWNHOST_CB
:
1866 pwmd_knownhost_cb_t
*cb
= va_arg (ap
, pwmd_knownhost_cb_t
*);
1872 pwm
->kh_cb
= va_arg (ap
, pwmd_knownhost_cb_t
);
1874 case PWMD_OPTION_KNOWNHOST_DATA
:
1877 void **data
= va_arg (ap
, void **);
1879 *data
= pwm
->kh_data
;
1883 pwm
->kh_data
= va_arg (ap
, void *);
1885 case PWMD_OPTION_SSH_AGENT
:
1888 intp
= va_arg (ap
, int *);
1889 *intp
= pwm
->use_agent
;
1893 n
= va_arg (ap
, int);
1895 rc
= GPG_ERR_INV_VALUE
;
1899 case PWMD_OPTION_SSH_PASSPHRASE
:
1901 return GPG_ERR_NOT_SUPPORTED
;
1903 pwmd_free (pwm
->ssh_passphrase
);
1904 pwm
->ssh_passphrase
= NULL
;
1905 arg1
= va_arg (ap
, char *);
1908 pwm
->ssh_passphrase
= pwmd_strdup (arg1
);
1909 if (!pwm
->ssh_passphrase
)
1910 return GPG_ERR_ENOMEM
;
1913 case PWMD_OPTION_SSH_NEEDS_PASSPHRASE
:
1916 intp
= va_arg (ap
, int *);
1917 *intp
= pwm
->needs_passphrase
;
1921 n
= va_arg (ap
, int);
1923 rc
= GPG_ERR_INV_VALUE
;
1925 pwm
->needs_passphrase
= n
;
1927 case PWMD_OPTION_TLS_VERIFY
:
1930 intp
= va_arg (ap
, int *);
1931 *intp
= pwm
->tls_verify
;
1935 n
= va_arg (ap
, int);
1937 rc
= GPG_ERR_INV_VALUE
;
1939 pwm
->tls_verify
= n
;
1941 case PWMD_OPTION_TLS_PRIORITY
:
1944 charpp
= va_arg (ap
, char **);
1945 *charpp
= pwm
->tls_priority
;
1949 pwmd_free (pwm
->tls_priority
);
1950 pwm
->tls_priority
= NULL
;
1951 arg1
= va_arg (ap
, char *);
1954 pwm
->tls_priority
= pwmd_strdup (arg1
);
1955 if (!pwm
->tls_priority
)
1956 rc
= GPG_ERR_ENOMEM
;
1959 case PWMD_OPTION_SOCKET_TIMEOUT
:
1962 intp
= va_arg (ap
, int *);
1963 *intp
= pwm
->socket_timeout
;
1967 n
= va_arg (ap
, int);
1970 rc
= GPG_ERR_INV_VALUE
;
1974 pwm
->socket_timeout
= n
;
1977 if (pwm
->tcp
&& pwm
->tcp
->ssh
&& pwm
->tcp
->ssh
->session
)
1979 pwm
->tcp
->ssh
->timeout
= pwm
->socket_timeout
;
1980 libssh2_session_set_timeout (pwm
->tcp
->ssh
->session
,
1981 pwm
->socket_timeout
* 1000);
1985 if (pwm
->tcp
&& pwm
->tcp
->tls
&& pwm
->tcp
->tls
->session
)
1986 pwm
->tcp
->tls
->timeout
= pwm
->socket_timeout
;
1989 case PWMD_OPTION_OVERRIDE_INQUIRE
:
1992 intp
= va_arg (ap
, int *);
1993 *intp
= pwm
->override_inquire
;
1997 n
= va_arg (ap
, int);
1999 rc
= GPG_ERR_INV_VALUE
;
2001 pwm
->override_inquire
= n
;
2004 rc
= GPG_ERR_UNKNOWN_OPTION
;
2012 pwmd_setopt (pwm_t
* pwm
, int opt
, ...)
2018 rc
= pwmd_get_set_opt (pwm
, opt
, 0, ap
);
2024 pwmd_getopt (pwm_t
*pwm
, int opt
, ...)
2030 rc
= pwmd_get_set_opt (pwm
, opt
, 1, ap
);
2036 set_rcdefaults (pwm_t
*pwm
, char *filename
)
2041 unsigned line_n
= 0;
2044 if (!filename
&& isatty (STDIN_FILENO
))
2047 int err
= ttyname_r (STDOUT_FILENO
, buf
, sizeof (buf
));
2051 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TTY
, buf
);
2055 if (getenv ("TERM"))
2057 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TERM
, getenv ("TERM"));
2064 if (!filename
&& getenv ("DISPLAY"))
2066 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_DISPLAY
, getenv ("DISPLAY"));
2071 f
= _expand_homedir (filename
? filename
: (char *)"~/.config/libpwmd.conf",
2075 line
= pwmd_malloc (LINE_MAX
);
2078 fp
= fopen (f
, "r");
2087 rc
= GPG_ERR_ENOMEM
;
2090 rc
= GPG_ERR_ENOMEM
;
2099 while ((p
= fgets (line
, LINE_MAX
, fp
)))
2101 char name
[32] = {0}, val
[512] = {0};
2108 while (isspace (*p
))
2111 if (!*p
|| *p
== '#')
2114 if (p
[strlen (p
)-1] == '\n')
2115 p
[strlen (p
)-1] = 0;
2117 t
= strchr (p
, '=');
2120 fprintf(stderr
, N_("%s(%u): malformed line\n"), f
, line_n
);
2124 for (np
= name
; p
!= t
; p
++)
2126 if (++len
== sizeof (name
))
2135 while (isspace (*t
))
2138 while (isspace (*t
))
2141 strncpy (val
, t
, sizeof (val
)-1);
2143 if (!strcasecmp (name
, "pinentry-path"))
2144 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_PATH
, val
);
2145 else if (!strcasecmp (name
, "pinentry-tries"))
2146 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TRIES
, atoi (val
));
2147 else if (!strcasecmp (name
, "pinentry-timeout"))
2148 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TIMEOUT
, atoi (val
));
2149 else if (!strcasecmp (name
, "no-pinentry"))
2150 rc
= pwmd_setopt (pwm
, PWMD_OPTION_NO_PINENTRY
, !!(atoi (val
)));
2151 else if (!strcasecmp (name
, "local-pinentry"))
2152 rc
= pwmd_setopt (pwm
, PWMD_OPTION_LOCAL_PINENTRY
, !!(atoi (val
)));
2153 else if (!strcasecmp (name
, "pinentry-display"))
2154 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_DISPLAY
, val
);
2155 else if (!strcasecmp (name
, "pinentry-ttyname"))
2156 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TTY
, val
);
2157 else if (!strcasecmp (name
, "pinentry-ttytype"))
2158 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_TERM
, val
);
2159 else if (!strcasecmp (name
, "pinentry-lc-messages"))
2160 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_LC_MESSAGES
, val
);
2161 else if (!strcasecmp (name
, "pinentry-lc-ctype"))
2162 rc
= pwmd_setopt (pwm
, PWMD_OPTION_PINENTRY_LC_CTYPE
, val
);
2163 else if (!strcasecmp (name
, "no-ssh-agent"))
2164 rc
= pwmd_setopt (pwm
, PWMD_OPTION_SSH_AGENT
, !(atoi (val
)));
2165 else if (!strcasecmp (name
, "no-tls-verify"))
2166 rc
= pwmd_setopt (pwm
, PWMD_OPTION_TLS_VERIFY
, !(atoi (val
)));
2167 else if (!strcasecmp (name
, "tls-priority"))
2168 rc
= pwmd_setopt (pwm
, PWMD_OPTION_TLS_PRIORITY
, val
);
2169 else if (!strcasecmp (name
, "socket-timeout"))
2170 rc
= pwmd_setopt (pwm
, PWMD_OPTION_SOCKET_TIMEOUT
, atoi (val
));
2171 else if (!strcasecmp (name
, "no-lock"))
2172 rc
= pwmd_setopt (pwm
, PWMD_OPTION_LOCK_ON_OPEN
, !(atoi (val
)));
2173 else if (!strcasecmp (name
, "include"))
2174 rc
= set_rcdefaults (pwm
, val
);
2176 fprintf(stderr
, N_("%s(%u): invalid option '%s', ignored.\n"), f
,
2190 pwmd_new (const char *name
, pwm_t
** pwm
)
2192 pwm_t
*h
= pwmd_calloc (1, sizeof (pwm_t
));
2196 return FINISH (GPG_ERR_ENOMEM
);
2200 h
->name
= pwmd_strdup (name
);
2204 return FINISH (GPG_ERR_ENOMEM
);
2209 h
->pinentry_timeout
= -1;
2210 h
->current_pinentry_timeout
= -1;
2211 h
->pinentry_tries
= 3;
2212 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
2213 h
->prot
= PWMD_IP_ANY
;
2214 h
->socket_timeout
= 120;
2217 h
->opts
|= OPT_LOCK_ON_OPEN
;
2219 rc
= set_rcdefaults (h
, NULL
);
2232 pwmd_free (void *ptr
)
2238 pwmd_malloc (size_t size
)
2240 return _xmalloc (size
);
2244 pwmd_calloc (size_t nmemb
, size_t size
)
2246 return _xcalloc (nmemb
, size
);
2250 pwmd_realloc (void *ptr
, size_t size
)
2252 return _xrealloc (ptr
, size
);
2256 pwmd_strdup (const char *str
)
2263 t
= _xmalloc ((len
+ 1) * sizeof (char));
2267 for (c
= 0; c
< len
; c
++)
2275 pwmd_strdup_printf (const char *fmt
, ...)
2286 len
= vsnprintf (NULL
, 0, fmt
, ap
);
2288 buf
= pwmd_malloc (++len
);
2290 vsnprintf (buf
, len
, fmt
, ap2
);
2297 pwmd_getpin (pwm_t
* pwm
, const char *filename
, char **result
,
2298 size_t * len
, pwmd_pinentry_t which
)
2300 #ifndef WITH_PINENTRY
2301 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
2305 command_start (pwm
);
2306 if (which
== PWMD_PINENTRY_CONFIRM
&& pwm
->disable_pinentry
)
2308 rc
= get_password (pwm
, NULL
, NULL
, which
, 1);
2312 rc
= _pwmd_getpin (pwm
, filename
, result
, len
, which
);
2320 return LIBPWMD_VERSION_STR
;
2328 #ifdef WITH_PINENTRY
2329 n
|= PWMD_FEATURE_PINENTRY
;
2332 n
|= PWMD_FEATURE_SSH
;
2335 n
|= PWMD_FEATURE_QUALITY
;
2338 n
|= PWMD_FEATURE_GNUTLS
;
2344 pwmd_fd (pwm_t
* pwm
, int *fd
)
2347 return FINISH (GPG_ERR_INV_ARG
);
2350 return FINISH (GPG_ERR_INV_STATE
);
2357 pwmd_set_pointer (pwm_t
*pwm
, void *data
)
2359 pwm
->user_data
= data
;
2363 pwmd_get_pointer (pwm_t
*pwm
)
2365 return pwm
->user_data
;
2369 pwmd_gnutls_error (pwm_t
*pwm
, const char **str
)
2376 if (str
&& pwm
&& pwm
->tls_error
)
2377 *str
= gnutls_strerror (pwm
->tls_error
);
2379 return pwm
? pwm
->tls_error
: 0;
2384 pwmd_cancel (pwm_t
*pwm
)
2387 return FINISH (GPG_ERR_INV_ARG
);
2389 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
2390 if (pwm
->fd
== -1 && !pwm
->tcp
)
2394 return FINISH (GPG_ERR_INV_STATE
);
2396 /* Can only cancel the connection for the time being. */
2398 return FINISH (GPG_ERR_INV_STATE
);
2405 pwmd_test_quality (const char *str
, double *result
)
2407 #ifndef WITH_QUALITY
2410 return GPG_ERR_NOT_IMPLEMENTED
;
2413 return GPG_ERR_INV_ARG
;
2415 *result
= ZxcvbnMatch (str
, NULL
, NULL
);