diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index e5977ad6a..a96406fa3 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -205,6 +205,7 @@ static int start_pinentry (ctrl_t ctrl) { int rc = 0; + const char *full_pgmname; const char *pgmname; assuan_context_t ctx; const char *argv[5]; @@ -257,11 +258,11 @@ start_pinentry (ctrl_t ctrl) #endif } - if (!opt.pinentry_program || !*opt.pinentry_program) - opt.pinentry_program = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY); - pgmname = opt.pinentry_program; - if ( !(pgmname = strrchr (opt.pinentry_program, '/'))) - pgmname = opt.pinentry_program; + full_pgmname = opt.pinentry_program; + if (!full_pgmname || !*full_pgmname) + full_pgmname = gnupg_module_name (GNUPG_MODULE_NAME_PINENTRY); + if ( !(pgmname = strrchr (full_pgmname, '/'))) + pgmname = full_pgmname; else pgmname++; @@ -269,7 +270,7 @@ start_pinentry (ctrl_t ctrl) the resource bundle. For other systems we stick to the usual convention of supplying only the name of the program. */ #ifdef __APPLE__ - argv[0] = opt.pinentry_program; + argv[0] = full_pgmname; #else /*!__APPLE__*/ argv[0] = pgmname; #endif /*__APPLE__*/ @@ -310,13 +311,13 @@ start_pinentry (ctrl_t ctrl) that atfork is used to change the environment for pinentry. We start the server in detached mode to suppress the console window under Windows. */ - rc = assuan_pipe_connect (ctx, opt.pinentry_program, argv, + rc = assuan_pipe_connect (ctx, full_pgmname, argv, no_close_list, atfork_cb, ctrl, ASSUAN_PIPE_CONNECT_DETACHED); if (rc) { log_error ("can't connect to the PIN entry module '%s': %s\n", - opt.pinentry_program, gpg_strerror (rc)); + full_pgmname, gpg_strerror (rc)); assuan_release (ctx); return unlock_pinentry (gpg_error (GPG_ERR_NO_PIN_ENTRY)); } diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c index a874e76c2..6e1c76e20 100644 --- a/agent/gpg-agent.c +++ b/agent/gpg-agent.c @@ -1827,9 +1827,14 @@ agent_sighup_action (void) { log_info ("SIGHUP received - " "re-reading configuration and flushing cache\n"); + agent_flush_cache (); reread_configuration (); agent_reload_trustlist (); + /* We flush the module name cache so that after installing a + "pinentry" binary that one can be used in case the + "pinentry-basic" fallback was in use. */ + gnupg_module_name_flush_some (); } diff --git a/common/homedir.c b/common/homedir.c index 27141eb75..e3efcee7b 100644 --- a/common/homedir.c +++ b/common/homedir.c @@ -32,6 +32,7 @@ #include #include #include +#include #ifdef HAVE_W32_SYSTEM #include /* Due to the stupid mingw64 requirement to @@ -607,6 +608,41 @@ dirmngr_user_socket_name (void) } +/* Return the default pinentry name. If RESET is true the internal + cache is first flushed. */ +static const char * +get_default_pinentry_name (int reset) +{ + static char *name; + + if (reset) + { + xfree (name); + name = NULL; + } + + if (!name) + { + name = xstrconcat (gnupg_bindir (), + DIRSEP_S "pinentry" EXEEXT_S, NULL); + if (access (name, F_OK) && errno == ENOENT) + { + char *name2; + name2 = xstrconcat (gnupg_bindir (), + DIRSEP_S "pinentry-basic" EXEEXT_S, NULL); + if (access (name2, F_OK)) + xfree (name2); /* Does not exist. */ + else /* Switch to pinentry-basic. */ + { + xfree (name); + name = name2; + } + } + } + return name; +} + + /* Return the file name of a helper tool. WHICH is one of the GNUPG_MODULE_NAME_foo constants. */ const char * @@ -630,9 +666,9 @@ gnupg_module_name (int which) case GNUPG_MODULE_NAME_PINENTRY: #ifdef GNUPG_DEFAULT_PINENTRY - return GNUPG_DEFAULT_PINENTRY; + return GNUPG_DEFAULT_PINENTRY; /* (Set by a configure option) */ #else - X(bindir, "pinentry"); + return get_default_pinentry_name (0); #endif case GNUPG_MODULE_NAME_SCDAEMON: @@ -683,3 +719,12 @@ gnupg_module_name (int which) } #undef X } + + +/* Flush some of the cached module names. This is for example used by + gpg-agent to allow configuring a different pinentry. */ +void +gnupg_module_name_flush_some (void) +{ + (void)get_default_pinentry_name (1); +} diff --git a/common/util.h b/common/util.h index 24107f533..9103e094b 100644 --- a/common/util.h +++ b/common/util.h @@ -254,6 +254,7 @@ const char *dirmngr_user_socket_name (void); #define GNUPG_MODULE_NAME_GPGCONF 10 #define GNUPG_MODULE_NAME_DIRMNGR_LDAP 11 const char *gnupg_module_name (int which); +void gnupg_module_name_flush_some (void); diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi index 93264988d..84a7d60d9 100644 --- a/doc/gpg-agent.texi +++ b/doc/gpg-agent.texi @@ -445,8 +445,10 @@ This option does nothing yet. @item --pinentry-program @var{filename} @opindex pinentry-program -Use program @var{filename} as the PIN entry. The default is installation -dependent. +Use program @var{filename} as the PIN entry. The default is +installation dependent. With the default configuration the name of +the default pinentry is @file{pinentry}; if that file does not exist +but a @file{pinentry-basic} exist the latter is used. @item --pinentry-touch-file @var{filename} @opindex pinentry-touch-file