1
0
mirror of git://git.gnupg.org/gnupg.git synced 2025-04-17 15:44:34 +02:00

New agent option pinentry-mode.

This provides the framework and implements the ask, cancel and error.
loopback will be implemented later.
This commit is contained in:
Werner Koch 2011-03-03 18:35:08 +01:00
parent 35205e1300
commit b786f0e12b
6 changed files with 197 additions and 45 deletions

View File

@ -1,3 +1,16 @@
2011-03-03 Werner Koch <wk@g10code.com>
* gpg-agent.c: Add option --allow-loopback-pinentry.
* command.c (option_handler): Add option pinentry-mode.
* agent.h (pinentry_mode_t): New enum.
(struct server_local_s): Add PINENTRY_MODE.
(struct opt): Add ALLOW_LOOPBACK_PINENTRY.
* call-pinentry.c (agent_askpin): Implement ask, cancel and error
pinentry modes.
(agent_get_passphrase, agent_get_confirmation): Ditto.
(agent_show_message): Return cancel if pinentry mode is not "ask".
(agent_popup_message_start): Ditto.
2011-03-02 Werner Koch <wk@g10code.com> 2011-03-02 Werner Koch <wk@g10code.com>
* call-scd.c (hash_algo_option): New. * call-scd.c (hash_algo_option): New.

View File

@ -45,6 +45,18 @@
/* Maximum length of a digest. */ /* Maximum length of a digest. */
#define MAX_DIGEST_LEN 64 #define MAX_DIGEST_LEN 64
/* Values for the pinentry mode. */
typedef enum
{
PINENTRY_MODE_ASK = 0, /* Ask via pinentry (default). */
PINENTRY_MODE_CANCEL, /* Always return a cancel error. */
PINENTRY_MODE_ERROR, /* Return error code for no pinentry. */
PINENTRY_MODE_LOOPBACK,/* Use an inquiry to get the value. */
}
pinentry_mode_t;
/* A large struct name "opt" to keep global flags */ /* A large struct name "opt" to keep global flags */
struct struct
{ {
@ -67,7 +79,6 @@ struct
char *startup_lc_ctype; char *startup_lc_ctype;
char *startup_lc_messages; char *startup_lc_messages;
const char *pinentry_program; /* Filename of the program to start as const char *pinentry_program; /* Filename of the program to start as
pinentry. */ pinentry. */
const char *scdaemon_program; /* Filename of the program to handle const char *scdaemon_program; /* Filename of the program to handle
@ -105,6 +116,7 @@ struct
int ignore_cache_for_signing; int ignore_cache_for_signing;
int allow_mark_trusted; int allow_mark_trusted;
int allow_preset_passphrase; int allow_preset_passphrase;
int allow_loopback_pinentry;
int keep_tty; /* Don't switch the TTY (for pinentry) on request */ int keep_tty; /* Don't switch the TTY (for pinentry) on request */
int keep_display; /* Don't switch the DISPLAY (for pinentry) on request */ int keep_display; /* Don't switch the DISPLAY (for pinentry) on request */
int ssh_support; /* Enable ssh-agent emulation. */ int ssh_support; /* Enable ssh-agent emulation. */
@ -149,6 +161,9 @@ struct server_control_s
char *lc_ctype; char *lc_ctype;
char *lc_messages; char *lc_messages;
/* The current pinentry mode. */
pinentry_mode_t pinentry_mode;
struct { struct {
int algo; int algo;
unsigned char value[MAX_DIGEST_LEN]; unsigned char value[MAX_DIGEST_LEN];

View File

@ -742,6 +742,14 @@ agent_askpin (ctrl_t ctrl,
if (opt.batch) if (opt.batch)
return 0; /* fixme: we should return BAD PIN */ return 0; /* fixme: we should return BAD PIN */
if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
{
if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
return gpg_error (GPG_ERR_CANCELED);
/*FIXME: Implement loopback mode. */
return gpg_error (GPG_ERR_NO_PIN_ENTRY);
}
if (!pininfo || pininfo->max_length < 1) if (!pininfo || pininfo->max_length < 1)
return gpg_error (GPG_ERR_INV_VALUE); return gpg_error (GPG_ERR_INV_VALUE);
if (!desc_text && pininfo->min_digits) if (!desc_text && pininfo->min_digits)
@ -895,6 +903,14 @@ agent_get_passphrase (ctrl_t ctrl,
if (opt.batch) if (opt.batch)
return gpg_error (GPG_ERR_BAD_PASSPHRASE); return gpg_error (GPG_ERR_BAD_PASSPHRASE);
if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
{
if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
return gpg_error (GPG_ERR_CANCELED);
return gpg_error (GPG_ERR_NO_PIN_ENTRY);
}
rc = start_pinentry (ctrl); rc = start_pinentry (ctrl);
if (rc) if (rc)
return rc; return rc;
@ -981,6 +997,14 @@ agent_get_confirmation (ctrl_t ctrl,
int rc; int rc;
char line[ASSUAN_LINELENGTH]; char line[ASSUAN_LINELENGTH];
if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
{
if (ctrl->pinentry_mode == PINENTRY_MODE_CANCEL)
return gpg_error (GPG_ERR_CANCELED);
return gpg_error (GPG_ERR_NO_PIN_ENTRY);
}
rc = start_pinentry (ctrl); rc = start_pinentry (ctrl);
if (rc) if (rc)
return rc; return rc;
@ -1046,7 +1070,7 @@ agent_get_confirmation (ctrl_t ctrl,
/* Pop up the PINentry, display the text DESC and a button with the /* Pop up the PINentry, display the text DESC and a button with the
text OK_BTN (which may be NULL to use the default of "OK") and waut text OK_BTN (which may be NULL to use the default of "OK") and wait
for the user to hit this button. The return value is not for the user to hit this button. The return value is not
relevant. */ relevant. */
int int
@ -1055,6 +1079,9 @@ agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
int rc; int rc;
char line[ASSUAN_LINELENGTH]; char line[ASSUAN_LINELENGTH];
if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
return gpg_error (GPG_ERR_CANCELED);
rc = start_pinentry (ctrl); rc = start_pinentry (ctrl);
if (rc) if (rc)
return rc; return rc;
@ -1123,6 +1150,9 @@ agent_popup_message_start (ctrl_t ctrl, const char *desc, const char *ok_btn)
char line[ASSUAN_LINELENGTH]; char line[ASSUAN_LINELENGTH];
pth_attr_t tattr; pth_attr_t tattr;
if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
return gpg_error (GPG_ERR_CANCELED);
rc = start_pinentry (ctrl); rc = start_pinentry (ctrl);
if (rc) if (rc)
return rc; return rc;

View File

@ -2402,6 +2402,24 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0; ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
else if (!strcmp (key, "allow-pinentry-notify")) else if (!strcmp (key, "allow-pinentry-notify"))
ctrl->server_local->allow_pinentry_notify = 1; ctrl->server_local->allow_pinentry_notify = 1;
else if (!strcmp (key, "pinentry-mode"))
{
if (!strcmp (value, "ask") || !strcmp (value, "default"))
ctrl->pinentry_mode = PINENTRY_MODE_ASK;
else if (!strcmp (value, "cancel"))
ctrl->pinentry_mode = PINENTRY_MODE_CANCEL;
else if (!strcmp (value, "error"))
ctrl->pinentry_mode = PINENTRY_MODE_ERROR;
else if (!strcmp (value, "loopback"))
{
if (opt.allow_loopback_pinentry)
ctrl->pinentry_mode = PINENTRY_MODE_LOOPBACK;
else
err = gpg_error (GPG_ERR_NOT_SUPPORTED);
}
else
err = gpg_error (GPG_ERR_INV_VALUE);
}
else else
err = gpg_error (GPG_ERR_UNKNOWN_OPTION); err = gpg_error (GPG_ERR_UNKNOWN_OPTION);

View File

@ -105,6 +105,7 @@ enum cmd_and_opt_values
oIgnoreCacheForSigning, oIgnoreCacheForSigning,
oAllowMarkTrusted, oAllowMarkTrusted,
oAllowPresetPassphrase, oAllowPresetPassphrase,
oAllowLoopbackPinentry,
oKeepTTY, oKeepTTY,
oKeepDISPLAY, oKeepDISPLAY,
oSSHSupport, oSSHSupport,
@ -179,6 +180,8 @@ static ARGPARSE_OPTS opts[] = {
N_("allow clients to mark keys as \"trusted\"")}, N_("allow clients to mark keys as \"trusted\"")},
{ oAllowPresetPassphrase, "allow-preset-passphrase", 0, { oAllowPresetPassphrase, "allow-preset-passphrase", 0,
N_("allow presetting passphrase")}, N_("allow presetting passphrase")},
{ oAllowLoopbackPinentry, "allow-loopback-pinentry", 0,
N_("allow presetting passphrase")},
{ oSSHSupport, "enable-ssh-support", 0, N_("enable ssh-agent emulation") }, { oSSHSupport, "enable-ssh-support", 0, N_("enable ssh-agent emulation") },
{ oWriteEnvFile, "write-env-file", 2|8, { oWriteEnvFile, "write-env-file", 2|8,
N_("|FILE|write environment settings also to FILE")}, N_("|FILE|write environment settings also to FILE")},
@ -549,6 +552,8 @@ parse_rereadable_options (ARGPARSE_ARGS *pargs, int reread)
case oAllowPresetPassphrase: opt.allow_preset_passphrase = 1; break; case oAllowPresetPassphrase: opt.allow_preset_passphrase = 1; break;
case oAllowLoopbackPinentry: opt.allow_loopback_pinentry = 1; break;
default: default:
return 0; /* not handled */ return 0; /* not handled */
} }

View File

@ -348,6 +348,12 @@ Allow clients to mark keys as trusted, i.e. put them into the
@file{trustlist.txt} file. This is by default not allowed to make it @file{trustlist.txt} file. This is by default not allowed to make it
harder for users to inadvertently accept Root-CA keys. harder for users to inadvertently accept Root-CA keys.
@anchor{option --allow-loopback-pinentry}
@item --allow-loopback-pinentry
@opindex allow-loopback-pinentry
Allow clients to use the loopback pinentry features; see the option
@option{pinentry-mode} for details.
@item --ignore-cache-for-signing @item --ignore-cache-for-signing
@opindex ignore-cache-for-signing @opindex ignore-cache-for-signing
This option will let @command{gpg-agent} bypass the passphrase cache for all This option will let @command{gpg-agent} bypass the passphrase cache for all
@ -800,6 +806,7 @@ secret keys.
* Agent UPDATESTARTUPTTY:: Change the Standard Display * Agent UPDATESTARTUPTTY:: Change the Standard Display
* Agent GETEVENTCOUNTER:: Get the Event Counters * Agent GETEVENTCOUNTER:: Get the Event Counters
* Agent GETINFO:: Return information about the process * Agent GETINFO:: Return information about the process
* Agent OPTION:: Set options for the session
@end menu @end menu
@node Agent PKDECRYPT @node Agent PKDECRYPT
@ -1279,6 +1286,70 @@ Return the name of the socket used for SSH connections. If SSH support
has not been enabled the error @code{GPG_ERR_NO_DATA} will be returned. has not been enabled the error @code{GPG_ERR_NO_DATA} will be returned.
@end table @end table
@node Agent OPTION
@subsection Set options for the session
Here is a list of session options which are not yet described with
other commands. The general syntax for an Assuan option is:
@smallexample
OPTION @var{key}=@var{value}
@end smallexample
@noindent
Supported @var{key}s are:
@table @code
@item agent-awareness
This may be used to tell gpg-agent of which gpg-agent version the
client is aware of. gpg-agent uses this information to enable
features which might break older clients.
@item putenv
Change the session's environment to be used for the
Pinentry. Valid values are:
@table @code
@item @var{name}
Delete envvar @var{name}
@item @var{name}=
Set envvar @var{name} to the empty string
@item @var{name}=@var{value}
Set envvar @var{name} to the string @var{value}.
@end table
@item use-cache-for-signing
See Assuan command @code{PKSIGN}.
@item allow-pinentry-notify
This does not need any value. It is used to enable the
PINENTRY_LAUNCHED inquiry.
@item pinentry-mode
This option is used to change the operation mode of the pinentry. The
following values are defined:
@table @code
@item ask
This is the default mode which pops up a pinentry as needed.
@item cancel
Instead of popping up a pinentry, return the error code
@code{GPG_ERR_CANCELED}.
@item error
Instead of popping up a pinentry, return the error code
@code{GPG_ERR_NO_PIN_ENTRY}.
@item loopback
Use a loopback pinentry. This fakes a pinentry by using inquiries
back to the caller to ask for a passphrase. This option may only be
set if the agent has been configured for that.
Use the @xref{option --allow-loopback-pinentry}.
@end table
@end table
@mansect see also @mansect see also
@ifset isman @ifset isman