2 Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011, 2012, 2013, 2014, 2015
3 Ben Kibbey <bjk@luxsci.net>
5 This file is part of libpwmd.
7 Libpwmd is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 2 of the License, or
10 (at your option) any later version.
12 Libpwmd is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 GNU General Public License for more details.
17 You should have received a copy of the GNU General Public License
18 along with Libpwmd. If not, see <http://www.gnu.org/licenses/>.
31 #include <sys/types.h>
32 #include <sys/socket.h>
42 #include <sys/select.h>
62 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
63 #include <sys/types.h>
64 #include <sys/socket.h>
66 #include <netinet/in.h>
69 #define FINISH(rc) (gpg_err_source(rc) == GPG_ERR_SOURCE_UNKNOWN) \
79 hook_read (assuan_context_t ctx
, assuan_fd_t fd
, void *data
, size_t len
)
81 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
82 pwm_t
*pwm
= assuan_get_pointer (ctx
);
85 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->ssh
)
86 return read_hook_ssh (pwm
->tcp
->ssh
, fd
, data
, len
);
89 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->tls
)
90 return read_hook_tls (pwm
, fd
, data
, len
);
94 return read ((int) fd
, data
, len
);
98 hook_write (assuan_context_t ctx
, assuan_fd_t fd
, const void *data
,
102 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
103 pwm_t
*pwm
= assuan_get_pointer (ctx
);
106 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->ssh
)
107 return write_hook_ssh (pwm
->tcp
->ssh
, fd
, data
, len
);
110 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->tls
)
111 return write_hook_tls (pwm
, fd
, data
, len
);
115 /* libassuan cannot handle EAGAIN when doing writes. */
118 wrote
= write ((int) fd
, data
, len
);
119 if (wrote
== -1 && errno
== EAGAIN
)
122 while (wrote
== -1 && errno
== EAGAIN
);
128 hook_waitpid (assuan_context_t ctx
, pid_t pid
, int action
, int *status
,
131 return waitpid (pid
, status
, options
);
137 static int initialized
;
140 // May be called more than once.
141 gnutls_global_init ();
151 bindtextdomain ("libpwmd", LOCALEDIR
);
165 gnutls_global_deinit ();
170 _connect_finalize (pwm_t
* pwm
)
175 int n
= assuan_get_active_fds (pwm
->ctx
, 0, active
, N_ARRAY (active
));
178 return GPG_ERR_EBADFD
;
182 pwm
->pinentry_pid
= -1;
185 rc
= pwmd_command (pwm
, &result
, NULL
, NULL
, NULL
, "GETINFO VERSION");
188 pwm
->version
= strtoul (result
, NULL
, 16);
192 if (!rc
&& pwm
->name
)
193 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION NAME=%s",
200 connect_uds (pwm_t
* pwm
, const char *path
)
202 char *socketpath
= NULL
;
208 return GPG_ERR_INV_ARG
;
210 pwbuf
= _getpwuid (&pw
);
212 return gpg_error_from_syserror ();
215 socketpath
= pwmd_strdup_printf ("%s/.pwmd/socket", pw
.pw_dir
);
217 socketpath
= _expand_homedir ((char *) path
, &pw
);
221 return GPG_ERR_ENOMEM
;
223 rc
= assuan_socket_connect (pwm
->ctx
, socketpath
, ASSUAN_INVALID_FD
, 0);
224 pwmd_free (socketpath
);
225 return rc
? rc
: _connect_finalize (pwm
);
229 init_handle (pwm_t
* pwm
)
232 static struct assuan_malloc_hooks mhooks
= {
233 pwmd_malloc
, pwmd_realloc
, pwmd_free
235 static struct assuan_system_hooks shooks
= {
236 ASSUAN_SYSTEM_HOOKS_VERSION
,
244 NULL
, //sendmsg both are used for FD passing
252 rc
= assuan_new_ext (&pwm
->ctx
, GPG_ERR_SOURCE_DEFAULT
, &mhooks
, NULL
,
257 assuan_set_pointer (pwm
->ctx
, pwm
);
258 assuan_ctx_set_system_hooks (pwm
->ctx
, &shooks
);
262 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
264 free_tcp (pwm_t
*pwm
)
266 struct tcp_s
*tcp
= pwm
->tcp
;
272 _free_ssh_conn (tcp
->ssh
);
278 pwmd_free (tcp
->host
);
281 freeaddrinfo (tcp
->addrs
);
290 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
292 tcp_connect_common (pwm_t
* pwm
)
294 struct addrinfo hints
= { 0 };
302 hints
.ai_family
= AF_UNSPEC
;
305 hints
.ai_family
= AF_INET
;
308 hints
.ai_family
= AF_INET6
;
312 hints
.ai_socktype
= SOCK_STREAM
;
313 snprintf (portstr
, sizeof (portstr
), "%i", pwm
->tcp
->port
);
314 n
= getaddrinfo (pwm
->tcp
->host
, portstr
, &hints
, &pwm
->tcp
->addrs
);
317 fprintf (stderr
, "%s\n", gai_strerror (n
));
318 return GPG_ERR_UNKNOWN_HOST
; //FIXME
321 for (pwm
->tcp
->addr
= pwm
->tcp
->addrs
; pwm
->tcp
->addr
;
322 pwm
->tcp
->addr
= pwm
->tcp
->addrs
->ai_next
)
324 pwm
->fd
= socket (pwm
->tcp
->addr
->ai_family
, SOCK_STREAM
, 0);
327 rc
= gpg_error_from_syserror ();
328 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
)
333 if (fcntl (pwm
->fd
, F_SETFL
, O_NONBLOCK
) == -1)
335 rc
= gpg_error_from_syserror ();
339 if (connect (pwm
->fd
, pwm
->tcp
->addr
->ai_addr
,
340 pwm
->tcp
->addr
->ai_family
== AF_INET6
341 ? sizeof (struct sockaddr_in6
)
342 : sizeof (struct sockaddr
)) == -1)
347 unsigned elapsed
= 0;
349 rc
= gpg_error_from_syserror ();
350 if (gpg_err_code (rc
) != GPG_ERR_EINPROGRESS
)
354 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
)
363 FD_SET (pwm
->fd
, &wfds
);
364 n
= select (pwm
->fd
+1, NULL
, &wfds
, NULL
, &tv
);
366 if (!n
|| pwm
->cancel
)
369 rc
= gpg_error (GPG_ERR_CANCELED
);
370 else if (++elapsed
>= pwm
->socket_timeout
)
371 rc
= gpg_error (GPG_ERR_ETIMEDOUT
);
377 socklen_t len
= sizeof(int);
379 getsockopt (pwm
->fd
, SOL_SOCKET
, SO_ERROR
, &n
, &len
);
381 rc
= gpg_error_from_errno (n
);
384 rc
= gpg_error_from_syserror ();
390 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
391 || gpg_err_code (rc
) == GPG_ERR_ETIMEDOUT
403 if (fcntl (pwm
->fd
, F_SETFL
, 0) == -1)
404 rc
= gpg_error_from_syserror ();
411 command_start (pwm_t
*pwm
)
417 pwmd_connect (pwm_t
* pwm
, const char *url
, ...)
423 return FINISH (GPG_ERR_INV_ARG
);
426 rc
= init_handle (pwm
);
433 if (!(pwm
->opts
& OPT_SIGPIPE
))
434 signal (SIGPIPE
, SIG_IGN
);
439 rc
= GPG_ERR_UNSUPPORTED_PROTOCOL
;
441 if (p
&& (*p
== '/' || *p
== '~'))
442 rc
= connect_uds (pwm
, p
);
443 else if (!p
|| !strncmp (p
, "file://", 7))
447 #ifdef DEFAULT_PWMD_SOCKET
449 p
= DEFAULT_PWMD_SOCKET
;
451 rc
= connect_uds (pwm
, p
);
453 else if (!strncmp (p
, "ssh://", 6) || !strncmp (p
, "ssh6://", 7) ||
454 !strncmp (p
, "ssh4://", 7))
457 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
461 char *username
= NULL
;
463 if (!strncmp (p
, "ssh6://", 7))
465 pwm
->prot
= PWMD_IPV6
;
468 else if (!strncmp (p
, "ssh4://", 7))
470 pwm
->prot
= PWMD_IPV4
;
475 pwm
->prot
= PWMD_IP_ANY
;
479 rc
= _parse_ssh_url (p
, &host
, &port
, &username
);
483 char *identity
= NULL
;
484 char *knownhosts
= NULL
;
487 identity
= va_arg (ap
, char *);
489 if (!identity
&& !pwm
->use_agent
)
490 rc
= GPG_ERR_INV_ARG
;
492 knownhosts
= va_arg (ap
, char *);
497 rc
= _do_ssh_connect (pwm
, host
, port
, identity
, username
,
501 rc
= _connect_finalize (pwm
);
508 pwmd_free (username
);
509 pwm
->local_pinentry
= 1;
512 else if (!strncmp (p
, "tls://", 6) || !strncmp (p
, "tls6://", 7) ||
513 !strncmp (p
, "tls4://", 7))
516 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
521 if (!strncmp (p
, "tls6://", 7))
523 pwm
->prot
= PWMD_IPV6
;
526 else if (!strncmp (p
, "tls4://", 7))
528 pwm
->prot
= PWMD_IPV4
;
533 pwm
->prot
= PWMD_IP_ANY
;
537 rc
= _parse_tls_url (p
, &host
, &port
);
541 char *clientcert
= NULL
;
542 char *clientkey
= NULL
;
545 char *server_fp
= NULL
;
548 clientcert
= va_arg (ap
, char *);
551 rc
= GPG_ERR_INV_ARG
;
554 clientkey
= va_arg (ap
, char *);
556 rc
= GPG_ERR_INV_ARG
;
559 cacert
= va_arg (ap
, char *);
561 rc
= GPG_ERR_INV_ARG
;
564 prio
= va_arg (ap
, char *);
565 server_fp
= va_arg (ap
, char *);
573 rc
= _do_tls_connect (pwm
, host
, port
, clientcert
, clientkey
,
574 cacert
, prio
, server_fp
, pwm
->tls_verify
);
577 rc
= _connect_finalize (pwm
);
584 pwm
->local_pinentry
= 1;
595 disconnect (pwm_t
* pwm
)
601 assuan_release (pwm
->ctx
);
603 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
612 pwmd_close (pwm_t
* pwm
)
618 pwmd_free (pwm
->pinentry_error
);
619 pwmd_free (pwm
->pinentry_desc
);
620 pwmd_free (pwm
->pinentry_prompt
);
621 pwmd_free (pwm
->pinentry_tty
);
622 pwmd_free (pwm
->pinentry_display
);
623 pwmd_free (pwm
->pinentry_term
);
624 pwmd_free (pwm
->pinentry_lcctype
);
625 pwmd_free (pwm
->pinentry_lcmessages
);
626 pwmd_free (pwm
->filename
);
627 pwmd_free (pwm
->name
);
628 pwmd_free (pwm
->passphrase_info
);
629 pwmd_free (pwm
->passphrase_hint
);
633 _pinentry_disconnect (pwm
);
640 inquire_realloc_cb (void *data
, const void *buffer
, size_t len
)
642 membuf_t
*mem
= (membuf_t
*) data
;
648 if ((p
= pwmd_realloc (mem
->buf
, mem
->len
+ len
)) == NULL
)
649 return gpg_error (GPG_ERR_ENOMEM
);
652 memcpy ((char *) mem
->buf
+ mem
->len
, buffer
, len
);
658 get_password (pwm_t
* pwm
, char **result
, size_t * len
,
659 pwmd_pinentry_t w
, int echo
)
661 char buf
[LINE_MAX
] = { 0 }, *p
;
662 struct termios told
, tnew
;
671 if (!isatty (STDIN_FILENO
))
673 fprintf (stderr
, N_("Input is not from a terminal! Failing.\n"));
674 return GPG_ERR_ENOTTY
;
679 if (tcgetattr (STDIN_FILENO
, &told
) == -1)
680 return gpg_error_from_syserror ();
682 memcpy (&tnew
, &told
, sizeof (struct termios
));
683 tnew
.c_lflag
&= ~(ECHO
);
684 tnew
.c_lflag
|= ICANON
| ECHONL
;
686 if (tcsetattr (STDIN_FILENO
, TCSANOW
, &tnew
) == -1)
690 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
691 return gpg_error_from_errno (n
);
697 case PWMD_PINENTRY_OPEN
:
698 fprintf (stderr
, N_("Password for %s: "), pwm
->filename
);
700 case PWMD_PINENTRY_OPEN_FAILED
:
701 fprintf (stderr
, N_("Invalid password. Password for %s: "),
704 case PWMD_PINENTRY_SAVE
:
705 fprintf (stderr
, N_("New password for %s: "), pwm
->filename
);
707 case PWMD_PINENTRY_SAVE_CONFIRM
:
708 fprintf (stderr
, N_("Confirm password: "));
714 if ((p
= fgets (buf
, sizeof (buf
), stdin
)) == NULL
)
717 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
722 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
727 return GPG_ERR_CANCELED
;
730 /* Strip the newline character. */
731 p
[strlen (p
) - 1] = 0;
735 key
= pwmd_strdup_printf ("%s", p
);
736 memset (buf
, 0, sizeof (buf
));
738 return GPG_ERR_ENOMEM
;
749 *result
= pwmd_strdup ("");
759 pwmd_password (pwm_t
* pwm
, const char *keyword
, char **data
, size_t * size
)
762 int new_password
= 0;
763 char *password
= NULL
, *newpass
= NULL
;
774 if (!strcmp (keyword
, "NEW_PASSPHRASE"))
777 if (!new_password
&& pwm
->pinentry_try
)
781 if (pwm
->disable_pinentry
)
783 rc
= get_password (pwm
, &password
, size
,
784 new_password
? PWMD_PINENTRY_SAVE
:
785 error
? PWMD_PINENTRY_OPEN_FAILED
:
786 PWMD_PINENTRY_OPEN
, 0);
787 if (!rc
&& new_password
)
788 rc
= get_password (pwm
, &newpass
, size
, PWMD_PINENTRY_SAVE_CONFIRM
,
793 pwmd_pinentry_t which
;
797 ? PWMD_PINENTRY_SAVE_FAILED
: PWMD_PINENTRY_OPEN_FAILED
;
799 which
= new_password
? PWMD_PINENTRY_SAVE
: PWMD_PINENTRY_OPEN
;
801 rc
= pwmd_getpin (pwm
, pwm
->filename
, &password
, size
, which
);
802 if (!rc
&& new_password
)
803 rc
= pwmd_getpin (pwm
, pwm
->filename
, &newpass
, size
,
804 PWMD_PINENTRY_SAVE_CONFIRM
);
807 if (!rc
&& new_password
)
809 if ((!password
&& newpass
) || (!newpass
&& password
)
810 || (newpass
&& password
&& strcmp (newpass
, password
)))
812 if (pwm
->disable_pinentry
)
813 fprintf (stderr
, N_("Passphrases do not match.\n"));
815 pwmd_free (password
);
817 password
= newpass
= NULL
;
823 (void) pwmd_getpin (pwm
, pwm
->filename
, NULL
, NULL
, PWMD_PINENTRY_CLOSE
);
832 inquire_cb (void *data
, const char *keyword
)
834 pwm_t
*pwm
= (pwm_t
*) data
;
839 int new_password
= 0;
841 if (!strcmp (keyword
, "PASSPHRASE"))
843 else if (!strcmp (keyword
, "NEW_PASSPHRASE") || !strcmp (keyword
, "GENKEY"))
846 /* Shouldn't get this far without a callback. */
847 if (!pwm
->override_inquire
&& !pwm
->inquire_func
848 && !is_password
&& !new_password
)
849 return gpg_error (GPG_ERR_ASS_NO_INQUIRE_CB
);
858 if (!pwm
->override_inquire
&& (is_password
|| new_password
))
861 rc
= pwmd_password (data
, keyword
, &result
, &len
);
866 rc
= pwm
->inquire_func (pwm
->inquire_data
, keyword
, rc
, &result
,
869 /* gpg will truncate a passphrase at the first nil byte which may be bad
870 * for generated key files. */
871 if ((!rc
|| gpg_err_code (rc
) == GPG_ERR_EOF
)
872 && (is_password
|| new_password
))
874 if (len
&& result
&& *result
)
876 for (size_t n
= 0; n
< len
; n
++)
878 if (result
[n
] == 0 && n
+1 != len
)
879 rc
= GPG_ERR_INV_PASSPHRASE
;
885 if (rc
&& gpg_err_code (rc
) != GPG_ERR_EOF
)
887 #ifndef LIBASSUAN_2_1_0
888 gpg_error_t trc
= rc
;
890 /* Cancel this inquire. */
891 rc
= assuan_send_data (pwm
->ctx
, NULL
, 1);
897 /* There is a bug (or feature?) in assuan_send_data() that
898 * when cancelling an inquire the next read from the server is
899 * not done until the next command making the next command
900 * fail with GPG_ERR_ASS_UNEXPECTED_CMD.
902 rc
= assuan_read_line (pwm
->ctx
, &line
, &len
);
904 /* Restore the original error. This differs from the error
905 * returned from the pwmd command (GPG_ERR_CANCELED). This
906 * error is returned to the calling function.
915 if (gpg_err_code (rc
) == GPG_ERR_EOF
|| !rc
)
917 if (len
<= 0 && !result
)
922 else if ((len
<= 0 && result
) || (len
&& !result
))
924 rc
= gpg_error (GPG_ERR_INV_ARG
);
928 if (pwm
->inquire_maxlen
929 && pwm
->inquire_sent
+ len
> pwm
->inquire_maxlen
)
931 rc
= gpg_error (GPG_ERR_TOO_LARGE
);
933 rc
= pwm
->inquire_func (pwm
->inquire_data
, keyword
, rc
,
938 arc
= assuan_send_data (pwm
->ctx
, result
, len
);
939 if (gpg_err_code (rc
) == GPG_ERR_EOF
)
952 pwm
->inquire_sent
+= len
;
954 if (pwm
->status_func
)
956 char buf
[ASSUAN_LINELENGTH
];
958 snprintf (buf
, sizeof (buf
), "XFER %zu %zu", pwm
->inquire_sent
,
960 rc
= pwm
->status_func (pwm
->status_data
, buf
);
974 parse_assuan_line (pwm_t
* pwm
)
980 rc
= assuan_read_line (pwm
->ctx
, &line
, &len
);
983 if (line
[0] == 'O' && line
[1] == 'K' &&
984 (line
[2] == 0 || line
[2] == ' '))
987 else if (line
[0] == '#')
990 else if (line
[0] == 'S' && (line
[1] == 0 || line
[1] == ' '))
992 if (pwm
->status_func
)
994 rc
= pwm
->status_func (pwm
->status_data
,
995 line
[1] == 0 ? line
+ 1 : line
+ 2);
998 else if (line
[0] == 'E' && line
[1] == 'R' && line
[2] == 'R' &&
999 (line
[3] == 0 || line
[3] == ' '))
1002 rc
= strtol (line
, NULL
, 10);
1010 reset_handle (pwm_t
*pwm
)
1014 pwm
->pinentry_disabled
= 0;
1015 #ifdef WITH_PINENTRY
1017 _pinentry_disconnect (pwm
);
1019 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1030 pwmd_disconnect (pwm_t
* pwm
)
1033 return FINISH (GPG_ERR_INV_ARG
);
1035 command_start (pwm
);
1038 return FINISH (GPG_ERR_INV_STATE
);
1045 /* Note that this should only be called when not in a command. */
1047 pwmd_process (pwm_t
* pwm
)
1051 struct timeval tv
= { 0, 0 };
1054 if (!pwm
|| pwm
->fd
== -1)
1055 return FINISH (GPG_ERR_INV_ARG
);
1057 return FINISH (GPG_ERR_INV_STATE
);
1060 FD_SET (pwm
->fd
, &fds
);
1061 n
= select (pwm
->fd
+ 1, &fds
, NULL
, NULL
, &tv
);
1064 return FINISH (gpg_error_from_syserror ());
1068 if (FD_ISSET (pwm
->fd
, &fds
))
1069 rc
= parse_assuan_line (pwm
);
1072 while (!rc
&& assuan_pending_line (pwm
->ctx
))
1073 rc
= parse_assuan_line (pwm
);
1075 #if defined (WITH_SSH) || defined (WITH_GNUTLS)
1076 if (gpg_err_code (rc
) == GPG_ERR_EOF
&& pwm
->tcp
)
1087 status_cb (void *data
, const char *line
)
1091 if (!strncmp (line
, "INQUIRE_MAXLEN ", 15))
1092 pwm
->inquire_maxlen
= strtol (line
+ 15, NULL
, 10);
1093 else if (!strncmp (line
, "PASSPHRASE_HINT ", 16))
1095 pwmd_free (pwm
->passphrase_hint
);
1096 pwm
->passphrase_hint
= pwmd_strdup (line
+16);
1098 else if (!strncmp (line
, "PASSPHRASE_INFO ", 16))
1100 pwmd_free (pwm
->passphrase_info
);
1101 pwm
->passphrase_info
= pwmd_strdup (line
+16);
1104 if (pwm
->status_func
)
1105 return pwm
->status_func (pwm
->status_data
, line
);
1111 _assuan_command (pwm_t
* pwm
, assuan_context_t ctx
,
1112 char **result
, size_t * len
, const char *cmd
)
1118 return FINISH (GPG_ERR_INV_ARG
);
1120 if (strlen (cmd
) >= ASSUAN_LINELENGTH
+ 1)
1121 return FINISH (GPG_ERR_LINE_TOO_LONG
);
1125 rc
= assuan_transact (ctx
, cmd
, inquire_realloc_cb
, &data
,
1127 pwm
->pctx
== ctx
? pwm
->_inquire_func
: inquire_cb
,
1128 pwm
->pctx
== ctx
? pwm
->_inquire_data
: pwm
,
1138 pwmd_free (data
.buf
);
1146 inquire_realloc_cb (&data
, "", 1);
1149 *result
= (char *) data
.buf
;
1151 pwmd_free (data
.buf
);
1158 pwm
->inquire_maxlen
= 0;
1163 pwmd_command_ap (pwm_t
* pwm
, char **result
, size_t * rlen
,
1164 pwmd_inquire_cb_t func
, void *user
, const char *cmd
,
1171 command_start (pwm
);
1180 return FINISH (GPG_ERR_INV_ARG
);
1182 return FINISH (GPG_ERR_INV_STATE
);
1185 * C99 allows the dst pointer to be null which will calculate the length
1186 * of the would-be result and return it.
1189 len
= vsnprintf (NULL
, 0, cmd
, ap
) + 1;
1190 buf
= (char *) pwmd_malloc (len
);
1194 return FINISH (GPG_ERR_ENOMEM
);
1197 len
= vsnprintf (buf
, len
, cmd
, ap2
);
1200 if (buf
[strlen (buf
) - 1] == '\n')
1201 buf
[strlen (buf
) - 1] = 0;
1202 if (buf
[strlen (buf
) - 1] == '\r')
1203 buf
[strlen (buf
) - 1] = 0;
1205 pwm
->inquire_func
= func
;
1206 pwm
->inquire_data
= user
;
1207 pwm
->inquire_sent
= 0;
1208 gpg_error_t rc
= _assuan_command (pwm
, pwm
->ctx
, result
, rlen
, buf
);
1214 pwmd_command (pwm_t
* pwm
, char **result
, size_t * len
,
1215 pwmd_inquire_cb_t func
, void *user
, const char *cmd
, ...)
1226 return FINISH (GPG_ERR_INV_ARG
);
1228 return FINISH (GPG_ERR_INV_STATE
);
1231 gpg_error_t rc
= pwmd_command_ap (pwm
, result
, len
, func
, user
, cmd
, ap
);
1237 send_pinentry_timeout (pwm_t
*pwm
)
1241 if ((pwm
->pinentry_timeout
>= 0
1242 && pwm
->pinentry_timeout
!= pwm
->current_pinentry_timeout
)
1243 || (pwm
->pinentry_timeout
== -1
1244 && pwm
->pinentry_timeout
!= pwm
->current_pinentry_timeout
))
1246 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
,
1247 "OPTION pinentry-timeout=%i",
1248 pwm
->pinentry_timeout
);
1250 pwm
->current_pinentry_timeout
= pwm
->pinentry_timeout
;
1257 send_pinentry_options (pwm_t
* pwm
)
1261 // Pwmd >= 3.1 uses gpgme to do the pinentry settings.
1262 if (pwm
->version
&& pwm
->version
>= 0x030100)
1265 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
,
1266 "OPTION disable-pinentry=0");
1267 if (!rc
&& pwm
->pinentry_tty
)
1268 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION TTYNAME=%s",
1271 if (!rc
&& pwm
->pinentry_term
)
1272 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION TTYTYPE=%s",
1273 pwm
->pinentry_term
);
1275 if (!rc
&& pwm
->pinentry_display
)
1276 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION DISPLAY=%s",
1277 pwm
->pinentry_display
);
1279 if (!rc
&& pwm
->pinentry_desc
)
1280 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION DESC=%s",
1281 pwm
->pinentry_desc
);
1283 if (!rc
&& pwm
->pinentry_lcctype
)
1284 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION LC_CTYPE=%s",
1285 pwm
->pinentry_lcctype
);
1287 if (!rc
&& pwm
->pinentry_lcmessages
)
1288 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION LC_MESSAGES=%s",
1289 pwm
->pinentry_lcmessages
);
1292 rc
= send_pinentry_timeout (pwm
);
1298 pwmd_socket_type (pwm_t
* pwm
, pwmd_socket_t
* result
)
1300 if (!pwm
|| !result
)
1301 return FINISH (GPG_ERR_INV_ARG
);
1303 *result
= PWMD_SOCKET_LOCAL
;
1306 return FINISH (GPG_ERR_INV_STATE
);
1308 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1310 if (pwm
->tcp
&& pwm
->tcp
->ssh
)
1311 *result
= PWMD_SOCKET_SSH
;
1314 if (pwm
->tcp
&& pwm
->tcp
->tls
)
1315 *result
= PWMD_SOCKET_TLS
;
1322 disable_pinentry (pwm_t
*pwm
, int *disable
)
1325 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1326 int no_pinentry
= pwm
->disable_pinentry
|| pwm
->tcp
|| pwm
->local_pinentry
;
1328 int no_pinentry
= pwm
->disable_pinentry
|| pwm
->local_pinentry
;
1332 *disable
= no_pinentry
;
1334 if (pwm
->pinentry_disabled
&& no_pinentry
)
1336 else if (!pwm
->pinentry_disabled
&& !no_pinentry
)
1339 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION disable-pinentry=%i",
1342 pwm
->pinentry_disabled
= no_pinentry
;
1348 pwmd_open (pwm_t
* pwm
, const char *filename
, pwmd_inquire_cb_t cb
,
1352 int no_pinentry
= 0;
1354 if (!pwm
|| !filename
|| !*filename
)
1355 return FINISH (GPG_ERR_INV_ARG
);
1358 return FINISH (GPG_ERR_INV_STATE
);
1360 command_start (pwm
);
1361 rc
= disable_pinentry (pwm
, &no_pinentry
);
1362 if (!rc
&& !no_pinentry
)
1363 rc
= send_pinentry_options (pwm
);
1367 pwm
->pinentry_try
= 0;
1368 pwmd_free (pwm
->filename
);
1369 pwm
->filename
= pwmd_strdup (filename
);
1373 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
, "OPEN %s%s",
1374 (pwm
->opts
& OPT_LOCK_ON_OPEN
) ? "--lock " : "",
1377 while (gpg_err_code (rc
) == GPG_ERR_BAD_PASSPHRASE
1378 && pwm
->pinentry_disabled
1379 && ++pwm
->pinentry_try
< pwm
->pinentry_tries
);
1381 pwm
->pinentry_try
= 0;
1385 pwmd_free (pwm
->filename
);
1386 pwm
->filename
= NULL
;
1394 do_pwmd_save_passwd (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
,
1395 void *data
, int save
)
1400 return FINISH (GPG_ERR_INV_ARG
);
1402 return FINISH (GPG_ERR_INV_STATE
);
1404 command_start (pwm
);
1405 rc
= disable_pinentry (pwm
, NULL
);
1407 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
,
1408 save
? "SAVE %s" : "PASSWD %s", args
? args
: "");
1414 pwmd_passwd (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
, void *data
)
1416 return do_pwmd_save_passwd (pwm
, args
, cb
, data
, 0);
1420 pwmd_save (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
, void *data
)
1422 return do_pwmd_save_passwd (pwm
, args
, cb
, data
, 1);
1426 pwmd_get_set_opt (pwm_t
*pwm
, pwmd_option_t opt
, int get
, va_list ap
)
1430 char *arg1
, **charpp
;
1434 return GPG_ERR_INV_ARG
;
1436 command_start (pwm
);
1439 case PWMD_OPTION_SERVER_VERSION
:
1441 return GPG_ERR_NOT_SUPPORTED
;
1444 rc
= GPG_ERR_INV_ARG
;
1446 rc
= GPG_ERR_INV_STATE
;
1449 unsigned *u
= va_arg (ap
, unsigned *);
1454 case PWMD_OPTION_SIGPIPE
:
1457 intp
= va_arg (ap
, int *);
1458 *intp
= pwm
->opts
& OPT_SIGPIPE
? 1 : 0;
1462 n
= va_arg (ap
, int);
1464 rc
= GPG_ERR_INV_VALUE
;
1467 pwm
->opts
|= OPT_SIGPIPE
;
1469 pwm
->opts
&= ~OPT_SIGPIPE
;
1472 case PWMD_OPTION_LOCK_ON_OPEN
:
1475 intp
= va_arg (ap
, int *);
1476 *intp
= pwm
->opts
& OPT_LOCK_ON_OPEN
? 1 : 0;
1480 n
= va_arg (ap
, int);
1483 rc
= GPG_ERR_INV_VALUE
;
1486 pwm
->opts
|= OPT_LOCK_ON_OPEN
;
1488 pwm
->opts
&= ~OPT_LOCK_ON_OPEN
;
1491 case PWMD_OPTION_INQUIRE_TOTAL
:
1494 sizetp
= va_arg (ap
, size_t *);
1495 *sizetp
= pwm
->inquire_total
;
1499 pwm
->inquire_total
= va_arg (ap
, size_t);
1501 case PWMD_OPTION_STATUS_CB
:
1504 pwmd_status_cb_t
*cb
= va_arg (ap
, pwmd_status_cb_t
*);
1506 *cb
= pwm
->status_func
;
1510 pwm
->status_func
= va_arg (ap
, pwmd_status_cb_t
);
1512 case PWMD_OPTION_STATUS_DATA
:
1515 void **data
= va_arg (ap
, void **);
1517 *data
= pwm
->status_data
;
1521 pwm
->status_data
= va_arg (ap
, void *);
1523 case PWMD_OPTION_NO_PINENTRY
:
1526 intp
= va_arg (ap
, int *);
1527 *intp
= pwm
->disable_pinentry
;
1531 n
= va_arg (ap
, int);
1534 rc
= GPG_ERR_INV_VALUE
;
1536 pwm
->disable_pinentry
= n
;
1538 case PWMD_OPTION_LOCAL_PINENTRY
:
1541 intp
= va_arg (ap
, int *);
1542 *intp
= pwm
->local_pinentry
;
1546 n
= va_arg (ap
, int);
1549 rc
= GPG_ERR_INV_VALUE
;
1551 pwm
->local_pinentry
= n
;
1554 case PWMD_OPTION_PINENTRY_TIMEOUT
:
1557 intp
= va_arg (ap
, int *);
1558 *intp
= pwm
->pinentry_timeout
;
1562 n
= va_arg (ap
, int);
1565 rc
= GPG_ERR_INV_VALUE
;
1567 pwm
->pinentry_timeout
= n
;
1569 case PWMD_OPTION_PINENTRY_TRIES
:
1572 intp
= va_arg (ap
, int *);
1573 *intp
= pwm
->pinentry_tries
;
1577 n
= va_arg (ap
, int);
1578 pwm
->pinentry_tries
= n
;
1580 case PWMD_OPTION_PINENTRY_PATH
:
1583 charpp
= va_arg (ap
, char **);
1584 *charpp
= pwm
->pinentry_path
;
1588 arg1
= va_arg (ap
, char *);
1589 pwmd_free (pwm
->pinentry_path
);
1590 pwm
->pinentry_path
= arg1
? _expand_homedir (arg1
, NULL
) : NULL
;
1592 case PWMD_OPTION_PINENTRY_TTY
:
1595 charpp
= va_arg (ap
, char **);
1596 *charpp
= pwm
->pinentry_tty
;
1600 arg1
= va_arg (ap
, char *);
1601 pwmd_free (pwm
->pinentry_tty
);
1602 pwm
->pinentry_tty
= arg1
? pwmd_strdup (arg1
) : NULL
;
1604 case PWMD_OPTION_PINENTRY_DISPLAY
:
1607 charpp
= va_arg (ap
, char **);
1608 *charpp
= pwm
->pinentry_display
;
1612 arg1
= va_arg (ap
, char *);
1613 pwmd_free (pwm
->pinentry_display
);
1614 pwm
->pinentry_display
= arg1
? pwmd_strdup (arg1
) : NULL
;
1616 case PWMD_OPTION_PINENTRY_TERM
:
1619 charpp
= va_arg (ap
, char **);
1620 *charpp
= pwm
->pinentry_term
;
1624 arg1
= va_arg (ap
, char *);
1625 pwmd_free (pwm
->pinentry_term
);
1626 pwm
->pinentry_term
= arg1
? pwmd_strdup (arg1
) : NULL
;
1628 case PWMD_OPTION_PINENTRY_ERROR
:
1631 charpp
= va_arg (ap
, char **);
1632 *charpp
= pwm
->pinentry_error
;
1636 arg1
= va_arg (ap
, char *);
1637 pwmd_free (pwm
->pinentry_error
);
1638 pwm
->pinentry_error
= arg1
? _percent_escape (arg1
) : NULL
;
1640 case PWMD_OPTION_PINENTRY_PROMPT
:
1643 charpp
= va_arg (ap
, char **);
1644 *charpp
= pwm
->pinentry_prompt
;
1648 arg1
= va_arg (ap
, char *);
1649 pwmd_free (pwm
->pinentry_prompt
);
1650 pwm
->pinentry_prompt
= arg1
? _percent_escape (arg1
) : NULL
;
1652 case PWMD_OPTION_PINENTRY_DESC
:
1655 charpp
= va_arg (ap
, char **);
1656 *charpp
= pwm
->pinentry_desc
;
1660 arg1
= va_arg (ap
, char *);
1661 pwmd_free (pwm
->pinentry_desc
);
1662 pwm
->pinentry_desc
= arg1
? _percent_escape (arg1
) : NULL
;
1664 case PWMD_OPTION_PINENTRY_LC_CTYPE
:
1667 charpp
= va_arg (ap
, char **);
1668 *charpp
= pwm
->pinentry_lcctype
;
1672 arg1
= va_arg (ap
, char *);
1673 pwmd_free (pwm
->pinentry_lcctype
);
1674 pwm
->pinentry_lcctype
= arg1
? pwmd_strdup (arg1
) : NULL
;
1676 case PWMD_OPTION_PINENTRY_LC_MESSAGES
:
1679 charpp
= va_arg (ap
, char **);
1680 *charpp
= pwm
->pinentry_lcmessages
;
1684 arg1
= va_arg (ap
, char *);
1685 pwmd_free (pwm
->pinentry_lcmessages
);
1686 pwm
->pinentry_lcmessages
= arg1
? pwmd_strdup (arg1
) : NULL
;
1688 case PWMD_OPTION_KNOWNHOST_CB
:
1691 pwmd_knownhost_cb_t
*cb
= va_arg (ap
, pwmd_knownhost_cb_t
*);
1697 pwm
->kh_cb
= va_arg (ap
, pwmd_knownhost_cb_t
);
1699 case PWMD_OPTION_KNOWNHOST_DATA
:
1702 void **data
= va_arg (ap
, void **);
1704 *data
= pwm
->kh_data
;
1708 pwm
->kh_data
= va_arg (ap
, void *);
1710 case PWMD_OPTION_SSH_AGENT
:
1713 intp
= va_arg (ap
, int *);
1714 *intp
= pwm
->use_agent
;
1718 pwm
->use_agent
= va_arg (ap
, int);
1720 if (pwm
->use_agent
< 0 || pwm
->use_agent
> 1)
1723 rc
= GPG_ERR_INV_VALUE
;
1726 case PWMD_OPTION_TLS_VERIFY
:
1729 intp
= va_arg (ap
, int *);
1730 *intp
= pwm
->tls_verify
;
1734 pwm
->tls_verify
= va_arg (ap
, int);
1736 if (pwm
->tls_verify
< 0 || pwm
->tls_verify
> 1)
1738 pwm
->tls_verify
= 0;
1739 rc
= GPG_ERR_INV_VALUE
;
1742 case PWMD_OPTION_SOCKET_TIMEOUT
:
1745 intp
= va_arg (ap
, int *);
1746 *intp
= pwm
->socket_timeout
;
1750 pwm
->socket_timeout
= va_arg (ap
, int);
1751 if (pwm
->socket_timeout
< 0)
1753 pwm
->socket_timeout
= 0;
1754 rc
= GPG_ERR_INV_VALUE
;
1758 if (pwm
->tcp
&& pwm
->tcp
->ssh
&& pwm
->tcp
->ssh
->session
)
1760 pwm
->tcp
->ssh
->timeout
= pwm
->socket_timeout
;
1761 libssh2_session_set_timeout (pwm
->tcp
->ssh
->session
,
1762 pwm
->socket_timeout
* 1000);
1766 if (pwm
->tcp
&& pwm
->tcp
->tls
&& pwm
->tcp
->tls
->session
)
1767 pwm
->tcp
->tls
->timeout
= pwm
->socket_timeout
;
1770 case PWMD_OPTION_OVERRIDE_INQUIRE
:
1773 intp
= va_arg (ap
, int *);
1774 *intp
= pwm
->override_inquire
;
1778 pwm
->override_inquire
= va_arg (ap
, int);
1780 if (pwm
->override_inquire
< 0 || pwm
->override_inquire
> 1)
1782 pwm
->override_inquire
= 0;
1783 rc
= GPG_ERR_INV_VALUE
;
1787 rc
= GPG_ERR_UNKNOWN_OPTION
;
1795 pwmd_setopt (pwm_t
* pwm
, pwmd_option_t opt
, ...)
1801 rc
= pwmd_get_set_opt (pwm
, opt
, 0, ap
);
1807 pwmd_getopt (pwm_t
*pwm
, pwmd_option_t opt
, ...)
1813 rc
= pwmd_get_set_opt (pwm
, opt
, 1, ap
);
1819 pwmd_new (const char *name
, pwm_t
** pwm
)
1821 pwm_t
*h
= pwmd_calloc (1, sizeof (pwm_t
));
1825 return FINISH (GPG_ERR_ENOMEM
);
1829 h
->name
= pwmd_strdup (name
);
1833 return FINISH (GPG_ERR_ENOMEM
);
1838 h
->pinentry_timeout
= -1;
1839 h
->current_pinentry_timeout
= -1;
1840 h
->pinentry_tries
= 3;
1841 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1842 h
->prot
= PWMD_IP_ANY
;
1845 if (ttyname (STDOUT_FILENO
))
1849 ttyname_r (STDOUT_FILENO
, buf
, sizeof (buf
));
1850 h
->pinentry_tty
= pwmd_strdup (buf
);
1851 if (!h
->pinentry_tty
)
1853 rc
= GPG_ERR_ENOMEM
;
1858 if (getenv ("TERM") && h
->pinentry_tty
)
1860 h
->pinentry_term
= pwmd_strdup (getenv ("TERM"));
1861 if (!h
->pinentry_term
)
1863 rc
= GPG_ERR_ENOMEM
;
1868 if (getenv ("DISPLAY"))
1870 h
->pinentry_display
= pwmd_strdup (getenv ("DISPLAY"));
1871 if (!h
->pinentry_display
)
1873 rc
= GPG_ERR_ENOMEM
;
1878 update_pinentry_settings (h
);
1888 pwmd_free (void *ptr
)
1894 pwmd_malloc (size_t size
)
1896 return _xmalloc (size
);
1900 pwmd_calloc (size_t nmemb
, size_t size
)
1902 return _xcalloc (nmemb
, size
);
1906 pwmd_realloc (void *ptr
, size_t size
)
1908 return _xrealloc (ptr
, size
);
1912 pwmd_strdup (const char *str
)
1919 t
= _xmalloc ((len
+ 1) * sizeof (char));
1923 for (c
= 0; c
< len
; c
++)
1931 pwmd_strdup_printf (const char *fmt
, ...)
1942 len
= vsnprintf (NULL
, 0, fmt
, ap
);
1944 buf
= pwmd_malloc (++len
);
1946 vsnprintf (buf
, len
, fmt
, ap2
);
1953 pwmd_getpin (pwm_t
* pwm
, const char *filename
, char **result
,
1954 size_t * len
, pwmd_pinentry_t which
)
1956 #ifndef WITH_PINENTRY
1957 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
1959 command_start (pwm
);
1960 gpg_error_t rc
= _pwmd_getpin (pwm
, filename
, result
, len
, which
);
1969 return LIBPWMD_VERSION_STR
;
1977 #ifdef WITH_PINENTRY
1978 n
|= PWMD_FEATURE_PINENTRY
;
1981 n
|= PWMD_FEATURE_SSH
;
1984 n
|= PWMD_FEATURE_CRACK
;
1987 n
|= PWMD_FEATURE_GNUTLS
;
1993 pwmd_fd (pwm_t
* pwm
, int *fd
)
1996 return FINISH (GPG_ERR_INV_ARG
);
1999 return FINISH (GPG_ERR_INV_STATE
);
2006 pwmd_set_pointer (pwm_t
*pwm
, void *data
)
2008 pwm
->user_data
= data
;
2012 pwmd_get_pointer (pwm_t
*pwm
)
2014 return pwm
->user_data
;
2018 pwmd_tls_error (pwm_t
*pwm
)
2023 return pwm
? pwm
->tls_error
: 0;
2028 pwmd_cancel (pwm_t
*pwm
)
2031 return FINISH (GPG_ERR_INV_ARG
);
2034 return FINISH (GPG_ERR_INV_STATE
);
2036 /* Can only cancel the connection for the time being. */
2038 return FINISH (GPG_ERR_INV_STATE
);