From 5b3386b5162ae0eee7d49421f3f7e70a502a604c Mon Sep 17 00:00:00 2001 From: Ben Kibbey Date: Wed, 25 Dec 2013 11:52:07 -0500 Subject: [PATCH] pwmc: add ".set pinentry-timeout". This lets the local pinentry timeout setting be used in interactive mode rather than requiring it being specified on the command line. It also removes the global pwm handle used for blocking other pinentry's so it should be thread-safe now. --- doc/pwmc.1.in | 4 +++ src/libpwmd.c | 4 +-- src/pinentry.c | 86 ++++------------------------------------------------------ src/pwmc.c | 17 ++++++++++++ 4 files changed, 29 insertions(+), 82 deletions(-) diff --git a/doc/pwmc.1.in b/doc/pwmc.1.in index d8f31453..a2691fb0 100644 --- a/doc/pwmc.1.in +++ b/doc/pwmc.1.in @@ -489,6 +489,10 @@ for the next command requiring a new passphrase. This is equivalent to the .I "\-\-new-key-file" command line option. This value will be unset after the next protocol command to prevent misuse. +.TP +.I pinentry-timeout +Set the amount of seconds before the pinentry program will close and return an +error while waiting for user input. .RE .TP diff --git a/src/libpwmd.c b/src/libpwmd.c index 38178b50..a514a412 100644 --- a/src/libpwmd.c +++ b/src/libpwmd.c @@ -1188,7 +1188,7 @@ send_pinentry_options (pwm_t * pwm) rc = pwmd_command (pwm, NULL, NULL, NULL, NULL, "OPTION LC_MESSAGES=%s", pwm->pinentry_lcmessages); - if (!rc && pwm->pinentry_timeout > 0) + if (!rc && pwm->pinentry_timeout >= 0) rc = pwmd_command (pwm, NULL, NULL, NULL, NULL, "OPTION pinentry-timeout=%i", pwm->pinentry_timeout); @@ -1692,7 +1692,7 @@ pwmd_new (const char *name, pwm_t ** pwm) } reset_handle (h); - h->pinentry_timeout = -30; + h->pinentry_timeout = -1; h->pinentry_tries = 3; #if defined(WITH_SSH) || defined(WITH_GNUTLS) h->prot = PWMD_IP_ANY; diff --git a/src/pinentry.c b/src/pinentry.c index 7475db1d..ce66379a 100644 --- a/src/pinentry.c +++ b/src/pinentry.c @@ -22,7 +22,6 @@ #endif #include -#include #include #include #include @@ -38,10 +37,6 @@ #include #endif -static pwm_t *gpwm; -static int gelapsed, gtimeout; -static gpg_error_t grc; - static gpg_error_t set_pinentry_strings (pwm_t * pwm, pwmd_pinentry_t which); static gpg_error_t @@ -310,32 +305,15 @@ set_pinentry_strings (pwm_t * pwm, pwmd_pinentry_t which) } #endif - return rc; -} - -static gpg_error_t -terminate_pinentry (pwm_t * pwm) -{ - pid_t pid; - - if (!pwm || pwm->pinentry_pid == -1) - return GPG_ERR_INV_ARG; - - pid = pwm->pinentry_pid; - pwm->pinentry_pid = -1; - - if (kill (pid, 0) == 0) + if (pwm->pinentry_timeout >= 0) { - if (kill (pid, SIGINT) == -1) - { - if (kill (pid, SIGKILL) == -1) - return gpg_error_from_errno (errno); - } + char buf[32]; + + snprintf(buf, sizeof(buf), "SETTIMEOUT %i", pwm->pinentry_timeout); + rc = pinentry_command(pwm, NULL, NULL, buf); } - else - return gpg_error_from_errno (errno); - return 0; + return rc; } void @@ -348,32 +326,9 @@ _pinentry_disconnect (pwm_t * pwm) pwm->pinentry_pid = -1; } -/* - * Only called from a child process. - */ -static void -catchsig (int sig) -{ - switch (sig) - { - case SIGALRM: - if (++gelapsed >= gtimeout) - { - terminate_pinentry (gpwm); - grc = gpg_err_make (GPG_ERR_SOURCE_PINENTRY, GPG_ERR_CANCELED); - } - else - alarm (1); - break; - default: - break; - } -} - gpg_error_t _getpin (pwm_t * pwm, char **result, size_t * len, pwmd_pinentry_t which) { - grc = 0; gpg_error_t rc = set_pinentry_strings (pwm, which); if (rc) @@ -382,21 +337,8 @@ _getpin (pwm_t * pwm, char **result, size_t * len, pwmd_pinentry_t which) return rc; } - if (gtimeout) - { - signal (SIGALRM, catchsig); - alarm (1); - } - rc = pinentry_command (pwm, result, len, which == PWMD_PINENTRY_CONFIRM ? "CONFIRM" : "GETPIN"); - - /* - * Since there was input cancel any timeout setting. - */ - alarm (0); - signal (SIGALRM, SIG_DFL); - if (rc) { _pinentry_disconnect (pwm); @@ -441,24 +383,8 @@ _pwmd_getpin (pwm_t * pwm, const char *filename, char **result, if (!result && which != PWMD_PINENTRY_CONFIRM) return GPG_ERR_INV_ARG; - /* Another handle is using this pinentry method. Allowing this instance - * would reset the timeout and global handle which wouldn't be good. */ - if (gpwm) - return GPG_ERR_PIN_BLOCKED; - - if (pwm->pinentry_timeout != 0) - { - gpwm = pwm; - gtimeout = abs (pwm->pinentry_timeout); - gelapsed = 0; - } - pwm->filename = (char *) filename; rc = _getpin (pwm, result, len, which); pwm->filename = p; - - /* Don't timeout when an invalid passphrase was entered. */ - gtimeout = 0; - gpwm = NULL; return rc; } diff --git a/src/pwmc.c b/src/pwmc.c index a068b139..feec8422 100644 --- a/src/pwmc.c +++ b/src/pwmc.c @@ -78,6 +78,7 @@ static int interactive; #include "mem.h" +#define DEFAULT_PIN_TIMEOUT 30 #define DEFAULT_PIN_TRIES 3 #define FINISH(rc) (gpg_err_source(rc) == GPG_ERR_SOURCE_UNKNOWN) \ ? gpg_error(rc) : rc @@ -1129,6 +1130,19 @@ set_command (const char *line) } } } + else if (!strcmp(name, "pinentry-timeout")) + { + char *e = NULL; + int n = strtol(valuep, &e, 10); + + if (e && *e) + return gpg_error (GPG_ERR_INV_VALUE); + + if (!valuep || !*valuep) + n = DEFAULT_PIN_TIMEOUT; + + rc = pwmd_setopt(pwm, PWMD_OPTION_PINENTRY_TIMEOUT, n); + } else if (!strcmp (name, "help")) { fprintf (stderr, @@ -1141,6 +1155,9 @@ set_command (const char *line) "new-keyfile []\n" " set or unset the keyfile to be used when a new passphrase is required (*)\n" "\n" + "pinentry-timeout \n" + " the amount of seconds before pinentry gives up waiting for input\n" + "\n" "* = the next protocol command will unset this value\n" )); } -- 2.11.4.GIT