summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2011-03-03 18:35:08 +0100
committerWerner Koch <wk@gnupg.org>2011-03-03 18:35:08 +0100
commitb786f0e12b93d8d61eea18c934f5731fe86402d3 (patch)
tree2286e2a32cdc573b9cf2ac482fea66150238d0c4
parentPrint the secret keyinfo stuff with --card-status again. (diff)
downloadgnupg2-b786f0e12b93d8d61eea18c934f5731fe86402d3.tar.xz
gnupg2-b786f0e12b93d8d61eea18c934f5731fe86402d3.zip
New agent option pinentry-mode.
This provides the framework and implements the ask, cancel and error. loopback will be implemented later.
-rw-r--r--agent/ChangeLog13
-rw-r--r--agent/agent.h17
-rw-r--r--agent/call-pinentry.c32
-rw-r--r--agent/command.c18
-rw-r--r--agent/gpg-agent.c5
-rw-r--r--doc/gpg-agent.texi157
6 files changed, 197 insertions, 45 deletions
diff --git a/agent/ChangeLog b/agent/ChangeLog
index 7ec8789fd..de5f3da5b 100644
--- a/agent/ChangeLog
+++ b/agent/ChangeLog
@@ -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>
* call-scd.c (hash_algo_option): New.
diff --git a/agent/agent.h b/agent/agent.h
index 3319c3684..3e01897d1 100644
--- a/agent/agent.h
+++ b/agent/agent.h
@@ -45,6 +45,18 @@
/* Maximum length of a digest. */
#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 */
struct
{
@@ -67,7 +79,6 @@ struct
char *startup_lc_ctype;
char *startup_lc_messages;
-
const char *pinentry_program; /* Filename of the program to start as
pinentry. */
const char *scdaemon_program; /* Filename of the program to handle
@@ -105,6 +116,7 @@ struct
int ignore_cache_for_signing;
int allow_mark_trusted;
int allow_preset_passphrase;
+ int allow_loopback_pinentry;
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 ssh_support; /* Enable ssh-agent emulation. */
@@ -149,6 +161,9 @@ struct server_control_s
char *lc_ctype;
char *lc_messages;
+ /* The current pinentry mode. */
+ pinentry_mode_t pinentry_mode;
+
struct {
int algo;
unsigned char value[MAX_DIGEST_LEN];
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index c570e3819..4c30f6dea 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -742,6 +742,14 @@ agent_askpin (ctrl_t ctrl,
if (opt.batch)
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)
return gpg_error (GPG_ERR_INV_VALUE);
if (!desc_text && pininfo->min_digits)
@@ -895,6 +903,14 @@ agent_get_passphrase (ctrl_t ctrl,
if (opt.batch)
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);
if (rc)
return rc;
@@ -981,6 +997,14 @@ agent_get_confirmation (ctrl_t ctrl,
int rc;
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);
if (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
- 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
relevant. */
int
@@ -1055,6 +1079,9 @@ agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn)
int rc;
char line[ASSUAN_LINELENGTH];
+ if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
+ return gpg_error (GPG_ERR_CANCELED);
+
rc = start_pinentry (ctrl);
if (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];
pth_attr_t tattr;
+ if (ctrl->pinentry_mode != PINENTRY_MODE_ASK)
+ return gpg_error (GPG_ERR_CANCELED);
+
rc = start_pinentry (ctrl);
if (rc)
return rc;
diff --git a/agent/command.c b/agent/command.c
index 79b9b9731..b4b9b9e4c 100644
--- a/agent/command.c
+++ b/agent/command.c
@@ -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;
else if (!strcmp (key, "allow-pinentry-notify"))
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
err = gpg_error (GPG_ERR_UNKNOWN_OPTION);
diff --git a/agent/gpg-agent.c b/agent/gpg-agent.c
index e5af91ed9..c64b32feb 100644
--- a/agent/gpg-agent.c
+++ b/agent/gpg-agent.c
@@ -105,6 +105,7 @@ enum cmd_and_opt_values
oIgnoreCacheForSigning,
oAllowMarkTrusted,
oAllowPresetPassphrase,
+ oAllowLoopbackPinentry,
oKeepTTY,
oKeepDISPLAY,
oSSHSupport,
@@ -179,6 +180,8 @@ static ARGPARSE_OPTS opts[] = {
N_("allow clients to mark keys as \"trusted\"")},
{ oAllowPresetPassphrase, "allow-preset-passphrase", 0,
N_("allow presetting passphrase")},
+ { oAllowLoopbackPinentry, "allow-loopback-pinentry", 0,
+ N_("allow presetting passphrase")},
{ oSSHSupport, "enable-ssh-support", 0, N_("enable ssh-agent emulation") },
{ oWriteEnvFile, "write-env-file", 2|8,
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 oAllowLoopbackPinentry: opt.allow_loopback_pinentry = 1; break;
+
default:
return 0; /* not handled */
}
diff --git a/doc/gpg-agent.texi b/doc/gpg-agent.texi
index cb5f7d732..280670bd3 100644
--- a/doc/gpg-agent.texi
+++ b/doc/gpg-agent.texi
@@ -2,7 +2,7 @@
@c This is part of the GnuPG manual.
@c For copying conditions, see the file gnupg.texi.
-@c Note that we use this texinfo file for all versions of GnuPG:
+@c Note that we use this texinfo file for all versions of GnuPG:
@c 2.0 and 2.1. The macro "gpgtwoone" controls parts which are only
@c valid for GnuPG 2.1 and later.
@@ -26,23 +26,23 @@
.IR dir ]
.RB [ \-\-options
.IR file ]
-.RI [ options ]
+.RI [ options ]
.br
.B gpg-agent
.RB [ \-\-homedir
.IR dir ]
.RB [ \-\-options
.IR file ]
-.RI [ options ]
-.B \-\-server
+.RI [ options ]
+.B \-\-server
.br
.B gpg-agent
.RB [ \-\-homedir
.IR dir ]
.RB [ \-\-options
.IR file ]
-.RI [ options ]
-.B \-\-daemon
+.RI [ options ]
+.B \-\-daemon
.RI [ command_line ]
@end ifset
@@ -106,7 +106,7 @@ fi
It reads the data out of the file and exports the variables. If you
don't use Secure Shell, you don't need the last two export statements.
@end ifclear
-
+
@noindent
You should always add the following lines to your @code{.bashrc} or
whatever initialization file is used for all shell invocations:
@@ -235,7 +235,7 @@ a numeric value or a keyword:
@item none
No debugging at all. A value of less than 1 may be used instead of
the keyword.
-@item basic
+@item basic
Some basic debug messages. A value between 1 and 2 may be used
instead of the keyword.
@item advanced
@@ -263,8 +263,8 @@ usual C-Syntax. The currently defined bits are:
@table @code
@item 0 (1)
X.509 or OpenPGP protocol related data
-@item 1 (2)
-values of big number integers
+@item 1 (2)
+values of big number integers
@item 2 (4)
low level crypto operations
@item 5 (32)
@@ -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
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
@opindex ignore-cache-for-signing
This option will let @command{gpg-agent} bypass the passphrase cache for all
@@ -398,7 +404,7 @@ to 1.
Check the passphrase against the pattern given in @var{file}. When
entering a new passphrase matching one of these pattern a warning will
be displayed. @var{file} should be an absolute filename. The default is
-not to use any pattern file.
+not to use any pattern file.
Security note: It is known that checking a passphrase against a list of
pattern or even against a complete dictionary is not very effective to
@@ -408,7 +414,7 @@ behavior and optionally to run a passphrase cracker regularly on all
users passphrases to catch the very simple ones.
@item --max-passphrase-days @var{n}
-@opindex max-passphrase-days
+@opindex max-passphrase-days
Ask the user to change the passphrase if @var{n} days have passed since
the last change. With @option{--enforce-passphrase-constraints} set the
user may not bypass this check.
@@ -477,10 +483,10 @@ option has been enabled.
@itemx --lc-ctype @var{string}
@itemx --lc-messages @var{string}
@itemx --xauthority @var{string}
-@opindex display
-@opindex ttyname
-@opindex ttytype
-@opindex lc-ctype
+@opindex display
+@opindex ttyname
+@opindex ttytype
+@opindex lc-ctype
@opindex lc-messages
@opindex xauthority
These options are used with the server mode to pass localization
@@ -563,7 +569,7 @@ agent. By default they may all be found in the current home directory
two dashes may not be entered and the option may not be abbreviated.
This file is also read after a @code{SIGHUP} however only a few
options will actually have an effect. This default name may be
- changed on the command line (@pxref{option --options}).
+ changed on the command line (@pxref{option --options}).
You should backup this file.
@item trustlist.txt
@@ -576,21 +582,21 @@ agent. By default they may all be found in the current home directory
allows to cut and paste the fingerprint from a key listing output. If
the line is prefixed with a @code{!} the key is explicitly marked as
not trusted.
-
+
Here is an example where two keys are marked as ultimately trusted
and one as not trusted:
-
+
@example
# CN=Wurzel ZS 3,O=Intevation GmbH,C=DE
A6935DD34EF3087973C706FC311AA2CCF733765B S
-
+
# CN=PCA-1-Verwaltung-02/O=PKI-1-Verwaltung/C=DE
- DC:BD:69:25:48:BD:BB:7E:31:6E:BB:80:D3:00:80:35:D4:F8:A6:CD S
+ DC:BD:69:25:48:BD:BB:7E:31:6E:BB:80:D3:00:80:35:D4:F8:A6:CD S
# CN=Root-CA/O=Schlapphuete/L=Pullach/C=DE
!14:56:98:D3:FE:9C:CA:5A:31:6E:BC:81:D3:11:4E:00:90:A3:44:C2 S
@end example
-
+
Before entering a key into this file, you need to ensure its
authenticity. How to do this depends on your organisation; your
administrator might have already entered those keys which are deemed
@@ -625,7 +631,7 @@ fails, try again using the chain validation model.
@end table
-
+
@item sshcontrol
@cindex sshcontrol
This file is used when support for the secure shell agent protocol has
@@ -641,11 +647,11 @@ optional field for arbitrary flags. A non-zero TTL overrides the global
default as set by @option{--default-cache-ttl-ssh}.
The keygrip may be prefixed with a @code{!} to disable an entry entry.
-
+
The following example lists exactly one key. Note that keys available
through a OpenPGP smartcard in the active smartcard reader are
implicitly added to this list; i.e. there is no need to list them.
-
+
@example
# Key added on 2005-02-25 15:08:29
5A6592BF45DC73BD876874A28FD4639282E29B52 0
@@ -675,7 +681,7 @@ a small helper script is provided to create these files (@pxref{addgnupghome}).
@node Agent Signals
@section Use of some signals.
A running @command{gpg-agent} may be controlled by signals, i.e. using
-the @command{kill} command to send a signal to the process.
+the @command{kill} command to send a signal to the process.
Here is a list of supported signals:
@@ -714,7 +720,7 @@ This signal is used for internal purposes.
@end table
-@c
+@c
@c Examples
@c
@mansect examples
@@ -757,7 +763,7 @@ and add something like (for Bourne shells)
@noindent
to your shell initialization file (e.g. @file{~/.bashrc}).
-@c
+@c
@c Assuan Protocol
@c
@manpause
@@ -800,6 +806,7 @@ secret keys.
* Agent UPDATESTARTUPTTY:: Change the Standard Display
* Agent GETEVENTCOUNTER:: Get the Event Counters
* Agent GETINFO:: Return information about the process
+* Agent OPTION:: Set options for the session
@end menu
@node Agent PKDECRYPT
@@ -831,13 +838,13 @@ text.
C: D xxxx)
C: END
@end example
-
+
Please note that the server may send status info lines while reading the
data lines from the client. The data send is a SPKI like S-Exp with
this structure:
@example
- (enc-val
+ (enc-val
(<algo>
(<param_name1> <mpi>)
...
@@ -850,20 +857,20 @@ the parameters depend on the algorithm. The agent does return an error
if there is an inconsistency.
If the decryption was successful the decrypted data is returned by
-means of "D" lines.
+means of "D" lines.
Here is an example session:
@example
C: PKDECRYPT
S: INQUIRE CIPHERTEXT
- C: D (enc-val elg (a 349324324)
+ C: D (enc-val elg (a 349324324)
C: D (b 3F444677CA)))
C: END
S: # session key follows
S: D (value 1234567890ABCDEF0)
S: OK descryption successful
-@end example
+@end example
@node Agent PKSIGN
@@ -911,8 +918,8 @@ different algorithms. The agent does then some checks, asks for the
passphrase and as a result the server returns the signature as an SPKI
like S-expression in "D" lines:
-@example
- (sig-val
+@example
+ (sig-val
(<algo>
(<param_name1> <mpi>)
...
@@ -960,7 +967,7 @@ option allows to choose the storage location. To get the secret key out
of the PSE, a special export tool has to be used.
@example
- GENKEY
+ GENKEY
@end example
Invokes the key generation process and the server will then inquire
@@ -1095,13 +1102,13 @@ Known sequences with the pattern @@foo@@ are replaced according to this
table:
@table @code
-@item @@FPR16@@
+@item @@FPR16@@
Format the fingerprint according to gpg rules for a v3 keys.
-@item @@FPR20@@
+@item @@FPR20@@
Format the fingerprint according to gpg rules for a v4 keys.
@item @@FPR@@
Choose an appropriate format to format the fingerprint.
-@item @@@@
+@item @@@@
Replaced by a single @code{@@}
@end table
@@ -1123,7 +1130,7 @@ arguments the agent returns a cached passphrase or an error. By
convention either the hexified fingerprint of the key shall be used for
@var{cache_id} or an arbitrary string prefixed with the name of the
calling application and a colon: Like @code{gpg:somestring}.
-
+
@var{error_message} is either a single @code{X} for no error message or
a string to be shown as an error message like (e.g. "invalid
passphrase"). Blanks must be percent escaped or replaced by @code{+}'.
@@ -1147,7 +1154,7 @@ has been found in the cache.
If the option @option{--no-ask} is used and the passphrase is not in the
cache the user will not be asked to enter a passphrase but the error
-code @code{GPG_ERR_NO_DATA} is returned.
+code @code{GPG_ERR_NO_DATA} is returned.
If the option @option{--qualitybar} is used and a minimum passphrase
length has been configured, a visual indication of the entered
@@ -1279,11 +1286,75 @@ 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.
@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
@ifset isman
-@command{gpg2}(1),
-@command{gpgsm}(1),
+@command{gpg2}(1),
+@command{gpgsm}(1),
@command{gpg-connect-agent}(1),
@command{scdaemon}(1)
@end ifset