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>
63 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
64 #include <sys/types.h>
65 #include <sys/socket.h>
67 #include <netinet/in.h>
70 #define FINISH(rc) (gpg_err_source(rc) == GPG_ERR_SOURCE_UNKNOWN) \
80 hook_read (assuan_context_t ctx
, assuan_fd_t fd
, void *data
, size_t len
)
82 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
83 pwm_t
*pwm
= assuan_get_pointer (ctx
);
86 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->ssh
)
87 return read_hook_ssh (pwm
->tcp
->ssh
, fd
, data
, len
);
90 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->tls
)
91 return read_hook_tls (pwm
, fd
, data
, len
);
95 return read ((int) fd
, data
, len
);
99 hook_write (assuan_context_t ctx
, assuan_fd_t fd
, const void *data
,
103 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
104 pwm_t
*pwm
= assuan_get_pointer (ctx
);
107 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->ssh
)
108 return write_hook_ssh (pwm
->tcp
->ssh
, fd
, data
, len
);
111 if (pwm
&& pwm
->tcp
&& pwm
->tcp
->tls
)
112 return write_hook_tls (pwm
, fd
, data
, len
);
116 /* libassuan cannot handle EAGAIN when doing writes. */
119 wrote
= write ((int) fd
, data
, len
);
120 if (wrote
== -1 && errno
== EAGAIN
)
123 while (wrote
== -1 && errno
== EAGAIN
);
129 hook_waitpid (assuan_context_t ctx
, pid_t pid
, int action
, int *status
,
132 return waitpid (pid
, status
, options
);
138 static int initialized
;
141 // May be called more than once.
142 gnutls_global_init ();
149 bindtextdomain ("libpwmd", LOCALEDIR
);
155 gpgrt_set_alloc_func (_xrealloc_gpgrt
);
164 gnutls_global_deinit ();
169 _connect_finalize (pwm_t
* pwm
)
174 int n
= assuan_get_active_fds (pwm
->ctx
, 0, active
, N_ARRAY (active
));
177 return GPG_ERR_EBADFD
;
181 pwm
->pinentry_pid
= -1;
184 rc
= pwmd_command (pwm
, &result
, NULL
, NULL
, NULL
, "GETINFO VERSION");
187 pwm
->version
= strtoul (result
, NULL
, 16);
191 if (!rc
&& pwm
->name
)
192 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION NAME=%s",
199 connect_uds (pwm_t
* pwm
, const char *path
)
201 char *socketpath
= NULL
;
207 return GPG_ERR_INV_ARG
;
209 pwbuf
= _getpwuid (&pw
);
211 return gpg_error_from_syserror ();
214 socketpath
= pwmd_strdup_printf ("%s/.pwmd/socket", pw
.pw_dir
);
216 socketpath
= _expand_homedir ((char *) path
, &pw
);
220 return GPG_ERR_ENOMEM
;
222 rc
= assuan_socket_connect (pwm
->ctx
, socketpath
, ASSUAN_INVALID_FD
, 0);
223 pwmd_free (socketpath
);
224 return rc
? rc
: _connect_finalize (pwm
);
228 init_handle (pwm_t
* pwm
)
231 static struct assuan_malloc_hooks mhooks
= {
232 pwmd_malloc
, pwmd_realloc
, pwmd_free
234 static struct assuan_system_hooks shooks
= {
235 ASSUAN_SYSTEM_HOOKS_VERSION
,
243 NULL
, //sendmsg both are used for FD passing
251 rc
= assuan_new_ext (&pwm
->ctx
, GPG_ERR_SOURCE_DEFAULT
, &mhooks
, NULL
,
256 assuan_set_pointer (pwm
->ctx
, pwm
);
257 assuan_ctx_set_system_hooks (pwm
->ctx
, &shooks
);
261 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
263 free_tcp (pwm_t
*pwm
)
265 struct tcp_s
*tcp
= pwm
->tcp
;
271 _free_ssh_conn (tcp
->ssh
);
277 pwmd_free (tcp
->host
);
280 freeaddrinfo (tcp
->addrs
);
284 pthread_cond_destroy (&tcp
->dns_cond
);
285 pthread_mutex_destroy (&tcp
->dns_mutex
);
291 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
293 resolve_host_thread (void *arg
)
296 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 int *n
= pwmd_malloc (sizeof (int));
315 pthread_cleanup_push (pwmd_free
, n
);
316 *n
= getaddrinfo (pwm
->tcp
->host
, portstr
, &hints
, &pwm
->tcp
->addrs
);
317 pthread_cleanup_pop (0);
318 pthread_cond_broadcast (&pwm
->tcp
->dns_cond
);
324 tcp_connect_common (pwm_t
* pwm
)
326 #define TS_TIMEOUT 50000000L
333 n
= pthread_create (&tid
, NULL
, resolve_host_thread
, pwm
);
335 return gpg_error_from_errno (n
);
337 pthread_mutex_lock (&pwm
->tcp
->dns_mutex
);
344 clock_gettime (CLOCK_REALTIME
, &ts
);
345 if (ts
.tv_nsec
+ TS_TIMEOUT
>= 1000000000LL) {
350 ts
.tv_nsec
+= TS_TIMEOUT
;
354 #ifdef HAVE_PTHREAD_CANCEL
355 pthread_cancel (tid
);
356 pthread_join (tid
, NULL
);
358 pthread_join (tid
, (void **)&result
);
361 return GPG_ERR_CANCELED
;
364 n
= pthread_cond_timedwait (&pwm
->tcp
->dns_cond
, &pwm
->tcp
->dns_mutex
,
368 if (pwm
->socket_timeout
&& ts
.tv_sec
- now
>= pwm
->socket_timeout
)
370 #ifdef HAVE_PTHREAD_CANCEL
371 pthread_cancel (tid
);
372 pthread_join (tid
, NULL
);
374 pthread_join (tid
, (void **)&result
);
377 return GPG_ERR_ETIMEDOUT
;
384 #ifdef HAVE_PTHREAD_CANCEL
385 pthread_cancel (tid
);
386 pthread_join (tid
, NULL
);
388 pthread_join (tid
, (void **)&result
);
391 return gpg_error_from_errno (n
);
394 pthread_join (tid
, (void **)&result
);
401 return GPG_ERR_UNKNOWN_HOST
; //FIXME
403 for (pwm
->tcp
->addr
= pwm
->tcp
->addrs
; pwm
->tcp
->addr
;
404 pwm
->tcp
->addr
= pwm
->tcp
->addrs
->ai_next
)
406 pwm
->fd
= socket (pwm
->tcp
->addr
->ai_family
, SOCK_STREAM
, 0);
409 rc
= gpg_error_from_syserror ();
410 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
)
415 if (fcntl (pwm
->fd
, F_SETFL
, O_NONBLOCK
) == -1)
417 rc
= gpg_error_from_syserror ();
421 if (connect (pwm
->fd
, pwm
->tcp
->addr
->ai_addr
,
422 pwm
->tcp
->addr
->ai_family
== AF_INET6
423 ? sizeof (struct sockaddr_in6
)
424 : sizeof (struct sockaddr
)) == -1)
429 unsigned elapsed
= 0;
431 rc
= gpg_error_from_syserror ();
432 if (gpg_err_code (rc
) != GPG_ERR_EINPROGRESS
)
436 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
)
445 FD_SET (pwm
->fd
, &wfds
);
446 n
= select (pwm
->fd
+1, NULL
, &wfds
, NULL
, &tv
);
448 if (!n
|| pwm
->cancel
)
451 rc
= gpg_error (GPG_ERR_CANCELED
);
452 else if (++elapsed
>= pwm
->socket_timeout
)
453 rc
= gpg_error (GPG_ERR_ETIMEDOUT
);
459 socklen_t len
= sizeof(int);
461 getsockopt (pwm
->fd
, SOL_SOCKET
, SO_ERROR
, &n
, &len
);
463 rc
= gpg_error_from_errno (n
);
466 rc
= gpg_error_from_syserror ();
472 if (pwm
->tcp
->addr
== pwm
->tcp
->addrs
->ai_next
473 || gpg_err_code (rc
) == GPG_ERR_ETIMEDOUT
485 if (fcntl (pwm
->fd
, F_SETFL
, 0) == -1)
486 rc
= gpg_error_from_syserror ();
493 command_start (pwm_t
*pwm
)
499 pwmd_connect (pwm_t
* pwm
, const char *url
, ...)
505 return FINISH (GPG_ERR_INV_ARG
);
508 rc
= init_handle (pwm
);
515 if (!(pwm
->opts
& OPT_SIGPIPE
))
516 signal (SIGPIPE
, SIG_IGN
);
521 rc
= GPG_ERR_UNSUPPORTED_PROTOCOL
;
523 if (p
&& (*p
== '/' || *p
== '~'))
524 rc
= connect_uds (pwm
, p
);
525 else if (!p
|| !strncmp (p
, "file://", 7))
529 #ifdef DEFAULT_PWMD_SOCKET
531 p
= DEFAULT_PWMD_SOCKET
;
533 rc
= connect_uds (pwm
, p
);
535 else if (!strncmp (p
, "ssh://", 6) || !strncmp (p
, "ssh6://", 7) ||
536 !strncmp (p
, "ssh4://", 7))
539 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
543 char *username
= NULL
;
545 if (!strncmp (p
, "ssh6://", 7))
547 pwm
->prot
= PWMD_IPV6
;
550 else if (!strncmp (p
, "ssh4://", 7))
552 pwm
->prot
= PWMD_IPV4
;
557 pwm
->prot
= PWMD_IP_ANY
;
561 rc
= _parse_ssh_url (p
, &host
, &port
, &username
);
565 char *identity
= NULL
;
566 char *knownhosts
= NULL
;
569 identity
= va_arg (ap
, char *);
571 if (!identity
&& !pwm
->use_agent
)
572 rc
= GPG_ERR_INV_ARG
;
574 knownhosts
= va_arg (ap
, char *);
579 rc
= _do_ssh_connect (pwm
, host
, port
, identity
, username
,
583 rc
= _connect_finalize (pwm
);
590 pwmd_free (username
);
591 pwm
->local_pinentry
= 1;
594 else if (!strncmp (p
, "tls://", 6) || !strncmp (p
, "tls6://", 7) ||
595 !strncmp (p
, "tls4://", 7))
598 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
603 if (!strncmp (p
, "tls6://", 7))
605 pwm
->prot
= PWMD_IPV6
;
608 else if (!strncmp (p
, "tls4://", 7))
610 pwm
->prot
= PWMD_IPV4
;
615 pwm
->prot
= PWMD_IP_ANY
;
619 rc
= _parse_tls_url (p
, &host
, &port
);
623 char *clientcert
= NULL
;
624 char *clientkey
= NULL
;
627 char *server_fp
= NULL
;
630 clientcert
= va_arg (ap
, char *);
633 rc
= GPG_ERR_INV_ARG
;
636 clientkey
= va_arg (ap
, char *);
638 rc
= GPG_ERR_INV_ARG
;
641 cacert
= va_arg (ap
, char *);
643 rc
= GPG_ERR_INV_ARG
;
646 prio
= va_arg (ap
, char *);
647 server_fp
= va_arg (ap
, char *);
655 rc
= _do_tls_connect (pwm
, host
, port
, clientcert
, clientkey
,
656 cacert
, prio
, server_fp
, pwm
->tls_verify
);
659 rc
= _connect_finalize (pwm
);
666 pwm
->local_pinentry
= 1;
677 disconnect (pwm_t
* pwm
)
683 assuan_release (pwm
->ctx
);
685 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
694 pwmd_close (pwm_t
* pwm
)
700 pwmd_free (pwm
->pinentry_error
);
701 pwmd_free (pwm
->pinentry_desc
);
702 pwmd_free (pwm
->pinentry_prompt
);
703 pwmd_free (pwm
->pinentry_tty
);
704 pwmd_free (pwm
->pinentry_display
);
705 pwmd_free (pwm
->pinentry_term
);
706 pwmd_free (pwm
->pinentry_lcctype
);
707 pwmd_free (pwm
->pinentry_lcmessages
);
708 pwmd_free (pwm
->filename
);
709 pwmd_free (pwm
->name
);
710 pwmd_free (pwm
->passphrase_info
);
711 pwmd_free (pwm
->passphrase_hint
);
715 _pinentry_disconnect (pwm
);
722 inquire_realloc_cb (void *data
, const void *buffer
, size_t len
)
724 membuf_t
*mem
= (membuf_t
*) data
;
730 if ((p
= pwmd_realloc (mem
->buf
, mem
->len
+ len
)) == NULL
)
731 return gpg_error (GPG_ERR_ENOMEM
);
734 memcpy ((char *) mem
->buf
+ mem
->len
, buffer
, len
);
740 get_password (pwm_t
* pwm
, char **result
, size_t * len
,
741 pwmd_pinentry_t w
, int echo
)
743 char buf
[LINE_MAX
] = { 0 }, *p
;
744 struct termios told
, tnew
;
753 if (!isatty (STDIN_FILENO
))
755 fprintf (stderr
, N_("Input is not from a terminal! Failing.\n"));
756 return GPG_ERR_ENOTTY
;
761 if (tcgetattr (STDIN_FILENO
, &told
) == -1)
762 return gpg_error_from_syserror ();
764 memcpy (&tnew
, &told
, sizeof (struct termios
));
765 tnew
.c_lflag
&= ~(ECHO
);
766 tnew
.c_lflag
|= ICANON
| ECHONL
;
768 if (tcsetattr (STDIN_FILENO
, TCSANOW
, &tnew
) == -1)
772 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
773 return gpg_error_from_errno (n
);
777 if (pwm
->passphrase_hint
)
778 fprintf(stderr
, N_("Key info: %s\n"), pwm
->passphrase_hint
);
782 case PWMD_PINENTRY_OPEN
:
783 fprintf (stderr
, N_("Password for %s: "), pwm
->filename
);
785 case PWMD_PINENTRY_OPEN_FAILED
:
786 fprintf (stderr
, N_("Invalid password. Password for %s: "),
789 case PWMD_PINENTRY_SAVE
:
790 fprintf (stderr
, N_("New password for %s: "), pwm
->filename
);
792 case PWMD_PINENTRY_SAVE_CONFIRM
:
793 fprintf (stderr
, N_("Confirm password: "));
799 if ((p
= fgets (buf
, sizeof (buf
), stdin
)) == NULL
)
802 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
807 tcsetattr (STDIN_FILENO
, TCSANOW
, &told
);
812 return GPG_ERR_CANCELED
;
815 /* Strip the newline character. */
816 p
[strlen (p
) - 1] = 0;
820 key
= pwmd_strdup_printf ("%s", p
);
821 memset (buf
, 0, sizeof (buf
));
823 return GPG_ERR_ENOMEM
;
834 *result
= pwmd_strdup ("");
844 pwmd_password (pwm_t
* pwm
, const char *keyword
, char **data
, size_t * size
)
847 int new_password
= 0;
848 char *password
= NULL
, *newpass
= NULL
;
859 if (!strcmp (keyword
, "NEW_PASSPHRASE"))
862 if (!new_password
&& pwm
->pinentry_try
)
866 if (pwm
->disable_pinentry
)
868 rc
= get_password (pwm
, &password
, size
,
869 new_password
? PWMD_PINENTRY_SAVE
:
870 error
? PWMD_PINENTRY_OPEN_FAILED
:
871 PWMD_PINENTRY_OPEN
, 0);
872 if (!rc
&& new_password
)
873 rc
= get_password (pwm
, &newpass
, size
, PWMD_PINENTRY_SAVE_CONFIRM
,
878 pwmd_pinentry_t which
;
882 ? PWMD_PINENTRY_SAVE_FAILED
: PWMD_PINENTRY_OPEN_FAILED
;
884 which
= new_password
? PWMD_PINENTRY_SAVE
: PWMD_PINENTRY_OPEN
;
886 rc
= pwmd_getpin (pwm
, pwm
->filename
, &password
, size
, which
);
887 if (!rc
&& new_password
)
888 rc
= pwmd_getpin (pwm
, pwm
->filename
, &newpass
, size
,
889 PWMD_PINENTRY_SAVE_CONFIRM
);
892 if (!rc
&& new_password
)
894 if ((!password
&& newpass
) || (!newpass
&& password
)
895 || (newpass
&& password
&& strcmp (newpass
, password
)))
897 if (pwm
->disable_pinentry
)
898 fprintf (stderr
, N_("Passphrases do not match.\n"));
900 pwmd_free (password
);
902 password
= newpass
= NULL
;
908 (void) pwmd_getpin (pwm
, pwm
->filename
, NULL
, NULL
, PWMD_PINENTRY_CLOSE
);
917 inquire_cb (void *data
, const char *keyword
)
919 pwm_t
*pwm
= (pwm_t
*) data
;
924 int new_password
= 0;
926 if (!strcmp (keyword
, "PASSPHRASE") || !strcmp (keyword
, "SIGN_PASSPHRASE"))
928 else if (!strcmp (keyword
, "NEW_PASSPHRASE") || !strcmp (keyword
, "GENKEY"))
931 /* Shouldn't get this far without a callback. */
932 if (!pwm
->override_inquire
&& !pwm
->inquire_func
933 && !is_password
&& !new_password
)
934 return gpg_error (GPG_ERR_ASS_NO_INQUIRE_CB
);
943 if (!pwm
->override_inquire
&& (is_password
|| new_password
))
946 rc
= pwmd_password (data
, keyword
, &result
, &len
);
951 rc
= pwm
->inquire_func (pwm
->inquire_data
, keyword
, rc
, &result
,
954 /* gpg will truncate a passphrase at the first nil byte which may be bad
955 * for generated key files. */
956 if ((!rc
|| gpg_err_code (rc
) == GPG_ERR_EOF
)
957 && (is_password
|| new_password
))
959 if (len
&& result
&& *result
)
961 for (size_t n
= 0; n
< len
; n
++)
963 if (result
[n
] == 0 && n
+1 != len
)
964 rc
= GPG_ERR_INV_PASSPHRASE
;
970 if (rc
&& gpg_err_code (rc
) != GPG_ERR_EOF
)
972 #ifndef LIBASSUAN_2_1_0
973 gpg_error_t trc
= rc
;
975 /* Cancel this inquire. */
976 rc
= assuan_send_data (pwm
->ctx
, NULL
, 1);
982 /* There is a bug (or feature?) in assuan_send_data() that
983 * when cancelling an inquire the next read from the server is
984 * not done until the next command making the next command
985 * fail with GPG_ERR_ASS_UNEXPECTED_CMD.
987 rc
= assuan_read_line (pwm
->ctx
, &line
, &len
);
989 /* Restore the original error. This differs from the error
990 * returned from the pwmd command (GPG_ERR_CANCELED). This
991 * error is returned to the calling function.
1000 if (gpg_err_code (rc
) == GPG_ERR_EOF
|| !rc
)
1002 if (len
<= 0 && !result
)
1007 else if ((len
<= 0 && result
) || (len
&& !result
))
1009 rc
= gpg_error (GPG_ERR_INV_ARG
);
1013 if (pwm
->inquire_maxlen
1014 && pwm
->inquire_sent
+ len
> pwm
->inquire_maxlen
)
1016 rc
= gpg_error (GPG_ERR_TOO_LARGE
);
1018 rc
= pwm
->inquire_func (pwm
->inquire_data
, keyword
, rc
,
1023 arc
= assuan_send_data (pwm
->ctx
, result
, len
);
1024 if (gpg_err_code (rc
) == GPG_ERR_EOF
)
1037 pwm
->inquire_sent
+= len
;
1039 if (pwm
->status_func
)
1041 char buf
[ASSUAN_LINELENGTH
];
1043 snprintf (buf
, sizeof (buf
), "XFER %zu %zu", pwm
->inquire_sent
,
1044 pwm
->inquire_total
);
1045 rc
= pwm
->status_func (pwm
->status_data
, buf
);
1055 pwm
->inquire_maxlen
= pwm
->inquire_sent
= 0;
1060 parse_assuan_line (pwm_t
* pwm
)
1066 rc
= assuan_read_line (pwm
->ctx
, &line
, &len
);
1069 if (line
[0] == 'O' && line
[1] == 'K' &&
1070 (line
[2] == 0 || line
[2] == ' '))
1073 else if (line
[0] == '#')
1076 else if (line
[0] == 'S' && (line
[1] == 0 || line
[1] == ' '))
1078 if (pwm
->status_func
)
1080 rc
= pwm
->status_func (pwm
->status_data
,
1081 line
[1] == 0 ? line
+ 1 : line
+ 2);
1084 else if (line
[0] == 'E' && line
[1] == 'R' && line
[2] == 'R' &&
1085 (line
[3] == 0 || line
[3] == ' '))
1088 rc
= strtol (line
, NULL
, 10);
1096 reset_handle (pwm_t
*pwm
)
1100 pwm
->pinentry_disabled
= 0;
1101 #ifdef WITH_PINENTRY
1103 _pinentry_disconnect (pwm
);
1105 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1116 pwmd_disconnect (pwm_t
* pwm
)
1119 return FINISH (GPG_ERR_INV_ARG
);
1121 command_start (pwm
);
1124 return FINISH (GPG_ERR_INV_STATE
);
1131 /* Note that this should only be called when not in a command. */
1133 pwmd_process (pwm_t
* pwm
)
1137 struct timeval tv
= { 0, 0 };
1140 if (!pwm
|| pwm
->fd
== -1)
1141 return FINISH (GPG_ERR_INV_ARG
);
1143 return FINISH (GPG_ERR_INV_STATE
);
1146 FD_SET (pwm
->fd
, &fds
);
1147 n
= select (pwm
->fd
+ 1, &fds
, NULL
, NULL
, &tv
);
1150 return FINISH (gpg_error_from_syserror ());
1154 if (FD_ISSET (pwm
->fd
, &fds
))
1155 rc
= parse_assuan_line (pwm
);
1158 while (!rc
&& assuan_pending_line (pwm
->ctx
))
1159 rc
= parse_assuan_line (pwm
);
1161 #if defined (WITH_SSH) || defined (WITH_GNUTLS)
1162 if (gpg_err_code (rc
) == GPG_ERR_EOF
&& pwm
->tcp
)
1173 status_cb (void *data
, const char *line
)
1177 if (!strncmp (line
, "INQUIRE_MAXLEN ", 15))
1178 pwm
->inquire_maxlen
= strtol (line
+ 15, NULL
, 10);
1179 else if (!strncmp (line
, "PASSPHRASE_HINT ", 16))
1181 pwmd_free (pwm
->passphrase_hint
);
1182 pwm
->passphrase_hint
= pwmd_strdup (line
+16);
1184 else if (!strncmp (line
, "PASSPHRASE_INFO ", 16))
1186 pwmd_free (pwm
->passphrase_info
);
1187 pwm
->passphrase_info
= pwmd_strdup (line
+16);
1190 if (pwm
->status_func
)
1191 return pwm
->status_func (pwm
->status_data
, line
);
1197 _assuan_command (pwm_t
* pwm
, assuan_context_t ctx
,
1198 char **result
, size_t * len
, const char *cmd
)
1204 return FINISH (GPG_ERR_INV_ARG
);
1206 if (strlen (cmd
) >= ASSUAN_LINELENGTH
+ 1)
1207 return FINISH (GPG_ERR_LINE_TOO_LONG
);
1211 rc
= assuan_transact (ctx
, cmd
, inquire_realloc_cb
, &data
,
1213 pwm
->pctx
== ctx
? pwm
->_inquire_func
: inquire_cb
,
1214 pwm
->pctx
== ctx
? pwm
->_inquire_data
: pwm
,
1224 pwmd_free (data
.buf
);
1232 inquire_realloc_cb (&data
, "", 1);
1235 *result
= (char *) data
.buf
;
1237 pwmd_free (data
.buf
);
1244 pwm
->inquire_maxlen
= 0;
1249 pwmd_command_ap (pwm_t
* pwm
, char **result
, size_t * rlen
,
1250 pwmd_inquire_cb_t func
, void *user
, const char *cmd
,
1257 command_start (pwm
);
1266 return FINISH (GPG_ERR_INV_ARG
);
1268 return FINISH (GPG_ERR_INV_STATE
);
1271 * C99 allows the dst pointer to be null which will calculate the length
1272 * of the would-be result and return it.
1275 len
= vsnprintf (NULL
, 0, cmd
, ap
) + 1;
1276 buf
= (char *) pwmd_malloc (len
);
1280 return FINISH (GPG_ERR_ENOMEM
);
1283 len
= vsnprintf (buf
, len
, cmd
, ap2
);
1286 if (buf
[strlen (buf
) - 1] == '\n')
1287 buf
[strlen (buf
) - 1] = 0;
1288 if (buf
[strlen (buf
) - 1] == '\r')
1289 buf
[strlen (buf
) - 1] = 0;
1291 pwm
->inquire_func
= func
;
1292 pwm
->inquire_data
= user
;
1293 pwm
->inquire_sent
= 0;
1294 gpg_error_t rc
= _assuan_command (pwm
, pwm
->ctx
, result
, rlen
, buf
);
1300 pwmd_command (pwm_t
* pwm
, char **result
, size_t * len
,
1301 pwmd_inquire_cb_t func
, void *user
, const char *cmd
, ...)
1312 return FINISH (GPG_ERR_INV_ARG
);
1314 return FINISH (GPG_ERR_INV_STATE
);
1317 gpg_error_t rc
= pwmd_command_ap (pwm
, result
, len
, func
, user
, cmd
, ap
);
1323 send_pinentry_timeout (pwm_t
*pwm
)
1327 if ((pwm
->pinentry_timeout
>= 0
1328 && pwm
->pinentry_timeout
!= pwm
->current_pinentry_timeout
)
1329 || (pwm
->pinentry_timeout
== -1
1330 && pwm
->pinentry_timeout
!= pwm
->current_pinentry_timeout
))
1332 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
,
1333 "OPTION pinentry-timeout=%i",
1334 pwm
->pinentry_timeout
);
1336 pwm
->current_pinentry_timeout
= pwm
->pinentry_timeout
;
1343 send_pinentry_options (pwm_t
* pwm
)
1347 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
,
1348 "OPTION disable-pinentry=0");
1349 if (!rc
&& pwm
->pinentry_tty
)
1350 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION TTYNAME=%s",
1353 if (!rc
&& pwm
->pinentry_term
)
1354 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION TTYTYPE=%s",
1355 pwm
->pinentry_term
);
1357 if (!rc
&& pwm
->pinentry_display
)
1358 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION DISPLAY=%s",
1359 pwm
->pinentry_display
);
1361 if (!rc
&& pwm
->pinentry_desc
)
1362 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION DESC=%s",
1363 pwm
->pinentry_desc
);
1365 if (!rc
&& pwm
->pinentry_lcctype
)
1366 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION LC_CTYPE=%s",
1367 pwm
->pinentry_lcctype
);
1369 if (!rc
&& pwm
->pinentry_lcmessages
)
1370 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION LC_MESSAGES=%s",
1371 pwm
->pinentry_lcmessages
);
1374 rc
= send_pinentry_timeout (pwm
);
1380 pwmd_socket_type (pwm_t
* pwm
, pwmd_socket_t
* result
)
1382 if (!pwm
|| !result
)
1383 return FINISH (GPG_ERR_INV_ARG
);
1385 *result
= PWMD_SOCKET_LOCAL
;
1388 return FINISH (GPG_ERR_INV_STATE
);
1390 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1392 if (pwm
->tcp
&& pwm
->tcp
->ssh
)
1393 *result
= PWMD_SOCKET_SSH
;
1396 if (pwm
->tcp
&& pwm
->tcp
->tls
)
1397 *result
= PWMD_SOCKET_TLS
;
1404 disable_pinentry (pwm_t
*pwm
, int *disable
)
1407 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1408 int no_pinentry
= pwm
->disable_pinentry
|| pwm
->tcp
|| pwm
->local_pinentry
;
1410 int no_pinentry
= pwm
->disable_pinentry
|| pwm
->local_pinentry
;
1414 *disable
= no_pinentry
;
1416 if (pwm
->pinentry_disabled
&& no_pinentry
)
1418 else if (!pwm
->pinentry_disabled
&& !no_pinentry
)
1421 rc
= pwmd_command (pwm
, NULL
, NULL
, NULL
, NULL
, "OPTION disable-pinentry=%i",
1424 pwm
->pinentry_disabled
= no_pinentry
;
1430 pwmd_open (pwm_t
* pwm
, const char *filename
, pwmd_inquire_cb_t cb
,
1434 int no_pinentry
= 0;
1436 if (!pwm
|| !filename
|| !*filename
)
1437 return FINISH (GPG_ERR_INV_ARG
);
1440 return FINISH (GPG_ERR_INV_STATE
);
1442 command_start (pwm
);
1443 rc
= disable_pinentry (pwm
, &no_pinentry
);
1444 if (!rc
&& !no_pinentry
)
1445 rc
= send_pinentry_options (pwm
);
1449 pwm
->pinentry_try
= 0;
1450 pwmd_free (pwm
->filename
);
1451 pwm
->filename
= pwmd_strdup (filename
);
1455 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
, "OPEN %s%s",
1456 (pwm
->opts
& OPT_LOCK_ON_OPEN
) ? "--lock " : "",
1459 while (gpg_err_code (rc
) == GPG_ERR_BAD_PASSPHRASE
1460 && pwm
->pinentry_disabled
1461 && ++pwm
->pinentry_try
< pwm
->pinentry_tries
);
1463 pwm
->pinentry_try
= 0;
1467 pwmd_free (pwm
->filename
);
1468 pwm
->filename
= NULL
;
1472 pwmd_free (pwm
->passphrase_hint
);
1473 pwmd_free (pwm
->passphrase_info
);
1474 pwm
->passphrase_info
= pwm
->passphrase_hint
= NULL
;
1479 do_pwmd_save_passwd (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
,
1480 void *data
, int save
)
1483 int no_pinentry
= 0;
1486 return FINISH (GPG_ERR_INV_ARG
);
1488 return FINISH (GPG_ERR_INV_STATE
);
1490 command_start (pwm
);
1491 rc
= disable_pinentry (pwm
, &no_pinentry
);
1492 if (!rc
&& !no_pinentry
)
1493 rc
= send_pinentry_options (pwm
);
1496 rc
= pwmd_command (pwm
, NULL
, NULL
, cb
, data
,
1497 save
? "SAVE %s" : "PASSWD %s", args
? args
: "");
1499 pwmd_free (pwm
->passphrase_hint
);
1500 pwmd_free (pwm
->passphrase_info
);
1501 pwm
->passphrase_info
= pwm
->passphrase_hint
= NULL
;
1506 pwmd_passwd (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
, void *data
)
1508 return do_pwmd_save_passwd (pwm
, args
, cb
, data
, 0);
1512 pwmd_save (pwm_t
* pwm
, const char *args
, pwmd_inquire_cb_t cb
, void *data
)
1514 return do_pwmd_save_passwd (pwm
, args
, cb
, data
, 1);
1518 pwmd_get_set_opt (pwm_t
*pwm
, pwmd_option_t opt
, int get
, va_list ap
)
1522 char *arg1
, **charpp
;
1526 return GPG_ERR_INV_ARG
;
1528 command_start (pwm
);
1531 case PWMD_OPTION_SERVER_VERSION
:
1533 return GPG_ERR_NOT_SUPPORTED
;
1536 rc
= GPG_ERR_INV_ARG
;
1538 rc
= GPG_ERR_INV_STATE
;
1541 unsigned *u
= va_arg (ap
, unsigned *);
1546 case PWMD_OPTION_SIGPIPE
:
1549 intp
= va_arg (ap
, int *);
1550 *intp
= pwm
->opts
& OPT_SIGPIPE
? 1 : 0;
1554 n
= va_arg (ap
, int);
1556 rc
= GPG_ERR_INV_VALUE
;
1559 pwm
->opts
|= OPT_SIGPIPE
;
1561 pwm
->opts
&= ~OPT_SIGPIPE
;
1564 case PWMD_OPTION_LOCK_ON_OPEN
:
1567 intp
= va_arg (ap
, int *);
1568 *intp
= pwm
->opts
& OPT_LOCK_ON_OPEN
? 1 : 0;
1572 n
= va_arg (ap
, int);
1575 rc
= GPG_ERR_INV_VALUE
;
1578 pwm
->opts
|= OPT_LOCK_ON_OPEN
;
1580 pwm
->opts
&= ~OPT_LOCK_ON_OPEN
;
1583 case PWMD_OPTION_INQUIRE_TOTAL
:
1586 sizetp
= va_arg (ap
, size_t *);
1587 *sizetp
= pwm
->inquire_total
;
1591 pwm
->inquire_total
= va_arg (ap
, size_t);
1593 case PWMD_OPTION_STATUS_CB
:
1596 pwmd_status_cb_t
*cb
= va_arg (ap
, pwmd_status_cb_t
*);
1598 *cb
= pwm
->status_func
;
1602 pwm
->status_func
= va_arg (ap
, pwmd_status_cb_t
);
1604 case PWMD_OPTION_STATUS_DATA
:
1607 void **data
= va_arg (ap
, void **);
1609 *data
= pwm
->status_data
;
1613 pwm
->status_data
= va_arg (ap
, void *);
1615 case PWMD_OPTION_NO_PINENTRY
:
1618 intp
= va_arg (ap
, int *);
1619 *intp
= pwm
->disable_pinentry
;
1623 n
= va_arg (ap
, int);
1626 rc
= GPG_ERR_INV_VALUE
;
1628 pwm
->disable_pinentry
= n
;
1630 case PWMD_OPTION_LOCAL_PINENTRY
:
1633 intp
= va_arg (ap
, int *);
1634 *intp
= pwm
->local_pinentry
;
1638 n
= va_arg (ap
, int);
1641 rc
= GPG_ERR_INV_VALUE
;
1643 pwm
->local_pinentry
= n
;
1646 case PWMD_OPTION_PINENTRY_TIMEOUT
:
1649 intp
= va_arg (ap
, int *);
1650 *intp
= pwm
->pinentry_timeout
;
1654 n
= va_arg (ap
, int);
1657 rc
= GPG_ERR_INV_VALUE
;
1659 pwm
->pinentry_timeout
= n
;
1661 case PWMD_OPTION_PINENTRY_TRIES
:
1664 intp
= va_arg (ap
, int *);
1665 *intp
= pwm
->pinentry_tries
;
1669 n
= va_arg (ap
, int);
1670 pwm
->pinentry_tries
= n
;
1672 case PWMD_OPTION_PINENTRY_PATH
:
1675 charpp
= va_arg (ap
, char **);
1676 *charpp
= pwm
->pinentry_path
;
1680 arg1
= va_arg (ap
, char *);
1681 pwmd_free (pwm
->pinentry_path
);
1682 pwm
->pinentry_path
= arg1
? _expand_homedir (arg1
, NULL
) : NULL
;
1684 case PWMD_OPTION_PINENTRY_TTY
:
1687 charpp
= va_arg (ap
, char **);
1688 *charpp
= pwm
->pinentry_tty
;
1692 arg1
= va_arg (ap
, char *);
1693 pwmd_free (pwm
->pinentry_tty
);
1694 pwm
->pinentry_tty
= arg1
? pwmd_strdup (arg1
) : NULL
;
1696 case PWMD_OPTION_PINENTRY_DISPLAY
:
1699 charpp
= va_arg (ap
, char **);
1700 *charpp
= pwm
->pinentry_display
;
1704 arg1
= va_arg (ap
, char *);
1705 pwmd_free (pwm
->pinentry_display
);
1706 pwm
->pinentry_display
= arg1
? pwmd_strdup (arg1
) : NULL
;
1708 case PWMD_OPTION_PINENTRY_TERM
:
1711 charpp
= va_arg (ap
, char **);
1712 *charpp
= pwm
->pinentry_term
;
1716 arg1
= va_arg (ap
, char *);
1717 pwmd_free (pwm
->pinentry_term
);
1718 pwm
->pinentry_term
= arg1
? pwmd_strdup (arg1
) : NULL
;
1720 case PWMD_OPTION_PINENTRY_ERROR
:
1723 charpp
= va_arg (ap
, char **);
1724 *charpp
= pwm
->pinentry_error
;
1728 arg1
= va_arg (ap
, char *);
1729 pwmd_free (pwm
->pinentry_error
);
1730 pwm
->pinentry_error
= arg1
? _percent_escape (arg1
) : NULL
;
1732 case PWMD_OPTION_PINENTRY_PROMPT
:
1735 charpp
= va_arg (ap
, char **);
1736 *charpp
= pwm
->pinentry_prompt
;
1740 arg1
= va_arg (ap
, char *);
1741 pwmd_free (pwm
->pinentry_prompt
);
1742 pwm
->pinentry_prompt
= arg1
? _percent_escape (arg1
) : NULL
;
1744 case PWMD_OPTION_PINENTRY_DESC
:
1747 charpp
= va_arg (ap
, char **);
1748 *charpp
= pwm
->pinentry_desc
;
1752 arg1
= va_arg (ap
, char *);
1753 pwmd_free (pwm
->pinentry_desc
);
1754 pwm
->pinentry_desc
= arg1
? _percent_escape (arg1
) : NULL
;
1756 case PWMD_OPTION_PINENTRY_LC_CTYPE
:
1759 charpp
= va_arg (ap
, char **);
1760 *charpp
= pwm
->pinentry_lcctype
;
1764 arg1
= va_arg (ap
, char *);
1765 pwmd_free (pwm
->pinentry_lcctype
);
1766 pwm
->pinentry_lcctype
= arg1
? pwmd_strdup (arg1
) : NULL
;
1768 case PWMD_OPTION_PINENTRY_LC_MESSAGES
:
1771 charpp
= va_arg (ap
, char **);
1772 *charpp
= pwm
->pinentry_lcmessages
;
1776 arg1
= va_arg (ap
, char *);
1777 pwmd_free (pwm
->pinentry_lcmessages
);
1778 pwm
->pinentry_lcmessages
= arg1
? pwmd_strdup (arg1
) : NULL
;
1780 case PWMD_OPTION_KNOWNHOST_CB
:
1783 pwmd_knownhost_cb_t
*cb
= va_arg (ap
, pwmd_knownhost_cb_t
*);
1789 pwm
->kh_cb
= va_arg (ap
, pwmd_knownhost_cb_t
);
1791 case PWMD_OPTION_KNOWNHOST_DATA
:
1794 void **data
= va_arg (ap
, void **);
1796 *data
= pwm
->kh_data
;
1800 pwm
->kh_data
= va_arg (ap
, void *);
1802 case PWMD_OPTION_SSH_AGENT
:
1805 intp
= va_arg (ap
, int *);
1806 *intp
= pwm
->use_agent
;
1810 pwm
->use_agent
= va_arg (ap
, int);
1812 if (pwm
->use_agent
< 0 || pwm
->use_agent
> 1)
1815 rc
= GPG_ERR_INV_VALUE
;
1818 case PWMD_OPTION_SSH_NEEDS_PASSPHRASE
:
1821 intp
= va_arg (ap
, int *);
1822 *intp
= pwm
->needs_passphrase
;
1826 pwm
->needs_passphrase
= va_arg (ap
, int);
1828 if (pwm
->needs_passphrase
< 0 || pwm
->needs_passphrase
> 1)
1830 pwm
->needs_passphrase
= 0;
1831 rc
= GPG_ERR_INV_VALUE
;
1834 case PWMD_OPTION_TLS_VERIFY
:
1837 intp
= va_arg (ap
, int *);
1838 *intp
= pwm
->tls_verify
;
1842 pwm
->tls_verify
= va_arg (ap
, int);
1844 if (pwm
->tls_verify
< 0 || pwm
->tls_verify
> 1)
1846 pwm
->tls_verify
= 0;
1847 rc
= GPG_ERR_INV_VALUE
;
1850 case PWMD_OPTION_SOCKET_TIMEOUT
:
1853 intp
= va_arg (ap
, int *);
1854 *intp
= pwm
->socket_timeout
;
1858 pwm
->socket_timeout
= va_arg (ap
, int);
1859 if (pwm
->socket_timeout
< 0)
1861 pwm
->socket_timeout
= 0;
1862 rc
= GPG_ERR_INV_VALUE
;
1866 if (pwm
->tcp
&& pwm
->tcp
->ssh
&& pwm
->tcp
->ssh
->session
)
1868 pwm
->tcp
->ssh
->timeout
= pwm
->socket_timeout
;
1869 libssh2_session_set_timeout (pwm
->tcp
->ssh
->session
,
1870 pwm
->socket_timeout
* 1000);
1874 if (pwm
->tcp
&& pwm
->tcp
->tls
&& pwm
->tcp
->tls
->session
)
1875 pwm
->tcp
->tls
->timeout
= pwm
->socket_timeout
;
1878 case PWMD_OPTION_OVERRIDE_INQUIRE
:
1881 intp
= va_arg (ap
, int *);
1882 *intp
= pwm
->override_inquire
;
1886 pwm
->override_inquire
= va_arg (ap
, int);
1888 if (pwm
->override_inquire
< 0 || pwm
->override_inquire
> 1)
1890 pwm
->override_inquire
= 0;
1891 rc
= GPG_ERR_INV_VALUE
;
1895 rc
= GPG_ERR_UNKNOWN_OPTION
;
1903 pwmd_setopt (pwm_t
* pwm
, pwmd_option_t opt
, ...)
1909 rc
= pwmd_get_set_opt (pwm
, opt
, 0, ap
);
1915 pwmd_getopt (pwm_t
*pwm
, pwmd_option_t opt
, ...)
1921 rc
= pwmd_get_set_opt (pwm
, opt
, 1, ap
);
1927 pwmd_new (const char *name
, pwm_t
** pwm
)
1929 pwm_t
*h
= pwmd_calloc (1, sizeof (pwm_t
));
1933 return FINISH (GPG_ERR_ENOMEM
);
1937 h
->name
= pwmd_strdup (name
);
1941 return FINISH (GPG_ERR_ENOMEM
);
1946 h
->pinentry_timeout
= -1;
1947 h
->current_pinentry_timeout
= -1;
1948 h
->pinentry_tries
= 3;
1949 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
1950 h
->prot
= PWMD_IP_ANY
;
1953 if (isatty (STDOUT_FILENO
))
1956 int err
= ttyname_r (STDOUT_FILENO
, buf
, sizeof (buf
));
1960 h
->pinentry_tty
= pwmd_strdup (buf
);
1961 if (!h
->pinentry_tty
)
1963 rc
= GPG_ERR_ENOMEM
;
1969 if (getenv ("TERM") && h
->pinentry_tty
)
1971 h
->pinentry_term
= pwmd_strdup (getenv ("TERM"));
1972 if (!h
->pinentry_term
)
1974 rc
= GPG_ERR_ENOMEM
;
1979 if (getenv ("DISPLAY"))
1981 h
->pinentry_display
= pwmd_strdup (getenv ("DISPLAY"));
1982 if (!h
->pinentry_display
)
1984 rc
= GPG_ERR_ENOMEM
;
1998 pwmd_free (void *ptr
)
2004 pwmd_malloc (size_t size
)
2006 return _xmalloc (size
);
2010 pwmd_calloc (size_t nmemb
, size_t size
)
2012 return _xcalloc (nmemb
, size
);
2016 pwmd_realloc (void *ptr
, size_t size
)
2018 return _xrealloc (ptr
, size
);
2022 pwmd_strdup (const char *str
)
2029 t
= _xmalloc ((len
+ 1) * sizeof (char));
2033 for (c
= 0; c
< len
; c
++)
2041 pwmd_strdup_printf (const char *fmt
, ...)
2052 len
= vsnprintf (NULL
, 0, fmt
, ap
);
2054 buf
= pwmd_malloc (++len
);
2056 vsnprintf (buf
, len
, fmt
, ap2
);
2063 pwmd_getpin (pwm_t
* pwm
, const char *filename
, char **result
,
2064 size_t * len
, pwmd_pinentry_t which
)
2066 #ifndef WITH_PINENTRY
2067 return FINISH (GPG_ERR_NOT_IMPLEMENTED
);
2069 command_start (pwm
);
2070 gpg_error_t rc
= _pwmd_getpin (pwm
, filename
, result
, len
, which
);
2079 return LIBPWMD_VERSION_STR
;
2087 #ifdef WITH_PINENTRY
2088 n
|= PWMD_FEATURE_PINENTRY
;
2091 n
|= PWMD_FEATURE_SSH
;
2094 n
|= PWMD_FEATURE_CRACK
;
2097 n
|= PWMD_FEATURE_GNUTLS
;
2103 pwmd_fd (pwm_t
* pwm
, int *fd
)
2106 return FINISH (GPG_ERR_INV_ARG
);
2109 return FINISH (GPG_ERR_INV_STATE
);
2116 pwmd_set_pointer (pwm_t
*pwm
, void *data
)
2118 pwm
->user_data
= data
;
2122 pwmd_get_pointer (pwm_t
*pwm
)
2124 return pwm
->user_data
;
2128 pwmd_tls_error (pwm_t
*pwm
)
2133 return pwm
? pwm
->tls_error
: 0;
2138 pwmd_cancel (pwm_t
*pwm
)
2141 return FINISH (GPG_ERR_INV_ARG
);
2143 #if defined(WITH_SSH) || defined(WITH_GNUTLS)
2144 if (pwm
->fd
== -1 && !pwm
->tcp
)
2148 return FINISH (GPG_ERR_INV_STATE
);
2150 /* Can only cancel the connection for the time being. */
2152 return FINISH (GPG_ERR_INV_STATE
);