diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 46db9e85e..813df9a05 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -354,6 +354,19 @@ start_pinentry (ctrl_t ctrl) if (DBG_IPC) log_debug ("connection to PIN entry established\n"); + value = session_env_getenv (ctrl->session_env, "PINENTRY_USER_DATA"); + if (value != NULL) + { + char *optstr; + if (asprintf (&optstr, "OPTION pinentry-user-data=%s", value) < 0 ) + return unlock_pinentry (out_of_core ()); + rc = assuan_transact (entry_ctx, optstr, NULL, NULL, NULL, NULL, NULL, + NULL); + xfree (optstr); + if (rc && gpg_err_code (rc) != GPG_ERR_UNKNOWN_OPTION) + return unlock_pinentry (rc); + } + rc = assuan_transact (entry_ctx, opt.no_grab? "OPTION no-grab":"OPTION grab", NULL, NULL, NULL, NULL, NULL, NULL); diff --git a/tests/openpgp/fake-pinentry.c b/tests/openpgp/fake-pinentry.c index ce897650d..90e086c67 100644 --- a/tests/openpgp/fake-pinentry.c +++ b/tests/openpgp/fake-pinentry.c @@ -18,10 +18,12 @@ * along with this program; if not, see . */ +#include #include #include #include #include +#include FILE *log_stream; @@ -109,12 +111,39 @@ get_passphrase (const char *fname) fclose (source); fclose (sink); - rename (fname_new, fname); + if (unlink (fname)) + { + fprintf (stderr, "Failed to remove %s: %s", + fname, strerror (errno)); + exit (1); + } + + if (rename (fname_new, fname)) + { + fprintf (stderr, "Failed to rename %s to %s: %s", + fname, fname_new, strerror (errno)); + exit (1); + } return passphrase; } -#define spacep(p) (*(p) == ' ' || *(p) == '\t') +#define spacep(p) (*(p) == ' ' || *(p) == '\t' \ + || *(p) == '\r' || *(p) == '\n') + +/* rstrip line. */ +void +rstrip (char *buffer) +{ + char *p; + for (p = buffer + strlen (buffer) - 1; p >= buffer; p--) + { + if (! spacep (p)) + break; + *p = 0; + } +} + /* Skip over options in LINE. @@ -165,6 +194,8 @@ int main (int argc, char **argv) { char *args; + char *option_user_data = NULL; + int got_environment_user_data; char *logfile; char *passphrasefile; char *passphrase; @@ -176,9 +207,11 @@ main (int argc, char **argv) setvbuf (stdout, NULL, _IOLBF, BUFSIZ); args = getenv ("PINENTRY_USER_DATA"); + got_environment_user_data = args != NULL; if (! args) args = ""; + restart: logfile = option_value (args, "--logfile"); if (logfile) { @@ -215,9 +248,7 @@ main (int argc, char **argv) return 1; } - p = passphrase + strlen (passphrase) - 1; - if (*p == '\n') - *p = 0; + rstrip (passphrase); } else { @@ -226,12 +257,13 @@ main (int argc, char **argv) passphrase = "no PINENTRY_USER_DATA -- using default passphrase"; } - reply ("# fake-pinentry started. Passphrase='%s'.\n", passphrase); + reply ("# fake-pinentry(%d) started. Passphrase='%s'.\n", + getpid (), passphrase); reply ("OK - what's up?\n"); while (! feof (stdin)) { - char buffer[1024]; + char buffer[1024], *p; if (fgets (buffer, sizeof buffer, stdin) == NULL) break; @@ -239,6 +271,8 @@ main (int argc, char **argv) if (log_stream) fprintf (log_stream, "< %s", buffer); + rstrip (buffer); + if (strncmp (buffer, "GETPIN", 6) == 0) reply ("D %s\n", passphrase); else if (strncmp (buffer, "BYE", 3) == 0) @@ -246,6 +280,22 @@ main (int argc, char **argv) reply ("OK\n"); break; } +#define OPT_USER_DATA "OPTION pinentry-user-data=" + else if (strncmp (buffer, OPT_USER_DATA, strlen (OPT_USER_DATA)) == 0) + { + if (got_environment_user_data) + { + reply ("OK - I already got the data from the environment.\n"); + continue; + } + + if (log_stream) + fclose (log_stream); + log_stream = NULL; + free (option_user_data); + option_user_data = args = strdup (buffer + strlen (OPT_USER_DATA)); + goto restart; + } reply ("OK\n"); } @@ -254,5 +304,6 @@ main (int argc, char **argv) if (log_stream) fclose (log_stream); + free (option_user_data); return 0; }