[svn] GnuPG - r5009 - trunk/agent
svn author wk
cvs at cvs.gnupg.org
Fri May 15 13:16:29 CEST 2009
Author: wk
Date: 2009-05-15 13:16:28 +0200 (Fri, 15 May 2009)
New Revision: 5009
Modified:
trunk/agent/ChangeLog
trunk/agent/agent.h
trunk/agent/cache.c
trunk/agent/call-pinentry.c
trunk/agent/command-ssh.c
trunk/agent/command.c
trunk/agent/findkey.c
trunk/agent/pkdecrypt.c
trunk/agent/pksign.c
Log:
Fix bug #1053
Add option --qualitybar to command GET_PASSPHRASE.
Modified: trunk/agent/ChangeLog
===================================================================
--- trunk/agent/ChangeLog 2009-05-13 17:12:00 UTC (rev 5008)
+++ trunk/agent/ChangeLog 2009-05-15 11:16:28 UTC (rev 5009)
@@ -1,3 +1,22 @@
+2009-05-15 Werner Koch <wk at g10code.com>
+
+ Fix bug #1053.
+
+ * agent.h (lookup_ttl_t): New.
+ * findkey.c (unprotect): Add arg LOOKUP_TTL.
+ (agent_key_from_file): Ditto.
+ * pksign.c (agent_pksign_do): Ditto.
+ * command-ssh.c (ttl_from_sshcontrol): New.
+ (data_sign): Pass new function to agent_pksign_do.
+ (search_control_file): Add new arg R_TTL.
+
+2009-05-14 Werner Koch <wk at g10code.com>
+
+ * command.c (cmd_get_passphrase): Add option --qualitybar.
+ * call-pinentry.c (agent_askpin): Factor some code out to ...
+ (setup_qualitybar): .. new.
+ (agent_get_passphrase): Add arg WITH_QUALITYBAR and implement it.
+
2009-04-14 Marcus Brinkmann <marcus at g10code.de>
* call-pinentry.c (agent_get_confirmation): Try SETNOTOK command
Modified: trunk/agent/agent.h
===================================================================
--- trunk/agent/agent.h 2009-05-13 17:12:00 UTC (rev 5008)
+++ trunk/agent/agent.h 2009-05-15 11:16:28 UTC (rev 5009)
@@ -201,6 +201,10 @@
cache_mode_t;
+/* The type of a function to lookup a TTL by a keygrip. */
+typedef int (*lookup_ttl_t)(const char *hexgrip);
+
+
/*-- gpg-agent.c --*/
void agent_exit (int rc) JNLIB_GCC_A_NR; /* Also implemented in other tools */
const char *get_agent_socket_name (void);
@@ -229,6 +233,7 @@
const unsigned char *grip,
unsigned char **shadow_info,
cache_mode_t cache_mode,
+ lookup_ttl_t lookup_ttl,
gcry_sexp_t *result);
gpg_error_t agent_public_key_from_file (ctrl_t ctrl,
const unsigned char *grip,
@@ -249,7 +254,7 @@
struct pin_entry_info_s *pininfo);
int agent_get_passphrase (ctrl_t ctrl, char **retpass,
const char *desc, const char *prompt,
- const char *errtext);
+ const char *errtext, int with_qualitybar);
int agent_get_confirmation (ctrl_t ctrl, const char *desc, const char *ok,
const char *cancel);
int agent_show_message (ctrl_t ctrl, const char *desc, const char *ok_btn);
@@ -270,7 +275,7 @@
/*-- pksign.c --*/
int agent_pksign_do (ctrl_t ctrl, const char *desc_text,
gcry_sexp_t *signature_sexp,
- cache_mode_t cache_mode);
+ cache_mode_t cache_mode, lookup_ttl_t lookup_ttl);
int agent_pksign (ctrl_t ctrl, const char *desc_text,
membuf_t *outbuf, cache_mode_t cache_mode);
Modified: trunk/agent/cache.c
===================================================================
--- trunk/agent/cache.c 2009-05-13 17:12:00 UTC (rev 5008)
+++ trunk/agent/cache.c 2009-05-15 11:16:28 UTC (rev 5009)
@@ -194,8 +194,8 @@
with a maximum lifetime of TTL seconds. If there is already data
under this key, it will be replaced. Using a DATA of NULL deletes
the entry. A TTL of 0 is replaced by the default TTL and a TTL of
- -1 set infinite timeout. CACHE_MODE is stored with the cache entry
- and used t select different timeouts. */
+ -1 set infinite timeout. CACHE_MODE is stored with the cache entry
+ and used to select different timeouts. */
int
agent_put_cache (const char *key, cache_mode_t cache_mode,
const char *data, int ttl)
Modified: trunk/agent/call-pinentry.c
===================================================================
--- trunk/agent/call-pinentry.c 2009-05-13 17:12:00 UTC (rev 5008)
+++ trunk/agent/call-pinentry.c 2009-05-15 11:16:28 UTC (rev 5009)
@@ -570,8 +570,61 @@
}
+/* Helper for agent_askpin and agent_get_passphrase. */
+static int
+setup_qualitybar (void)
+{
+ int rc;
+ char line[ASSUAN_LINELENGTH];
+ char *tmpstr, *tmpstr2;
+ const char *tooltip;
+
+ /* TRANSLATORS: This string is displayed by Pinentry as the label
+ for the quality bar. */
+ tmpstr = try_percent_escape (_("Quality:"), "\t\r\n\f\v");
+ snprintf (line, DIM(line)-1, "SETQUALITYBAR %s", tmpstr? tmpstr:"");
+ line[DIM(line)-1] = 0;
+ xfree (tmpstr);
+ rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc == 103 /*(Old assuan error code)*/
+ || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
+ ; /* Ignore Unknown Command from old Pinentry versions. */
+ else if (rc)
+ return rc;
+
+ tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0);
+ if (tmpstr2)
+ tooltip = tmpstr2;
+ else
+ {
+ /* TRANSLATORS: This string is a tooltip, shown by pinentry when
+ hovering over the quality bar. Please use an appropriate
+ string to describe what this is about. The length of the
+ tooltip is limited to about 900 characters. If you do not
+ translate this entry, a default english text (see source)
+ will be used. */
+ tooltip = _("pinentry.qualitybar.tooltip");
+ if (!strcmp ("pinentry.qualitybar.tooltip", tooltip))
+ tooltip = ("The quality of the text entered above.\n"
+ "Please ask your administrator for "
+ "details about the criteria.");
+ }
+ tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
+ xfree (tmpstr2);
+ snprintf (line, DIM(line)-1, "SETQUALITYBAR_TT %s", tmpstr? tmpstr:"");
+ line[DIM(line)-1] = 0;
+ xfree (tmpstr);
+ rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc == 103 /*(Old assuan error code)*/
+ || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
+ ; /* Ignore Unknown Command from old pinentry versions. */
+ else if (rc)
+ return rc;
+ return 0;
+}
+
/* Call the Entry and ask for the PIN. We do check for a valid PIN
number here and repeat it as long as we have invalid formed
@@ -627,52 +680,9 @@
to the pinentry. */
if (pininfo->with_qualitybar && opt.min_passphrase_len )
{
- char *tmpstr, *tmpstr2;
- const char *tooltip;
-
- /* TRANSLATORS: This string is displayed by pinentry as the
- label for the quality bar. */
- tmpstr = try_percent_escape (_("Quality:"), "\t\r\n\f\v");
- snprintf (line, DIM(line)-1, "SETQUALITYBAR %s", tmpstr? tmpstr:"");
- line[DIM(line)-1] = 0;
- xfree (tmpstr);
- rc = assuan_transact (entry_ctx, line,
- NULL, NULL, NULL, NULL, NULL, NULL);
- if (rc == 103 /*(Old assuan error code)*/
- || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
- ; /* Ignore Unknown Command from old pinentry versions. */
- else if (rc)
+ rc = setup_qualitybar ();
+ if (rc)
return unlock_pinentry (rc);
-
- tmpstr2 = gnupg_get_help_string ("pinentry.qualitybar.tooltip", 0);
- if (tmpstr2)
- tooltip = tmpstr2;
- else
- {
- /* TRANSLATORS: This string is a tooltip, shown by pinentry
- when hovering over the quality bar. Please use an
- appropriate string to describe what this is about. The
- length of the tooltip is limited to about 900 characters.
- If you do not translate this entry, a default english
- text (see source) will be used. */
- tooltip = _("pinentry.qualitybar.tooltip");
- if (!strcmp ("pinentry.qualitybar.tooltip", tooltip))
- tooltip = ("The quality of the text entered above.\n"
- "Please ask your administrator for "
- "details about the criteria.");
- }
- tmpstr = try_percent_escape (tooltip, "\t\r\n\f\v");
- xfree (tmpstr2);
- snprintf (line, DIM(line)-1, "SETQUALITYBAR_TT %s", tmpstr? tmpstr:"");
- line[DIM(line)-1] = 0;
- xfree (tmpstr);
- rc = assuan_transact (entry_ctx, line,
- NULL, NULL, NULL, NULL, NULL, NULL);
- if (rc == 103 /*(Old assuan error code)*/
- || gpg_err_code (rc) == GPG_ERR_ASS_UNKNOWN_CMD)
- ; /* Ignore Unknown Command from old pinentry versions. */
- else if (rc)
- return unlock_pinentry (rc);
}
if (initial_errtext)
@@ -764,7 +774,7 @@
int
agent_get_passphrase (ctrl_t ctrl,
char **retpass, const char *desc, const char *prompt,
- const char *errtext)
+ const char *errtext, int with_qualitybar)
{
int rc;
@@ -798,6 +808,13 @@
if (rc)
return unlock_pinentry (rc);
+ if (with_qualitybar && opt.min_passphrase_len)
+ {
+ rc = setup_qualitybar ();
+ if (rc)
+ return unlock_pinentry (rc);
+ }
+
if (errtext)
{
snprintf (line, DIM(line)-1, "SETERROR %s", errtext);
@@ -815,7 +832,7 @@
assuan_begin_confidential (entry_ctx);
rc = assuan_transact (entry_ctx, "GETPIN", getpin_cb, &parm,
- NULL, NULL, NULL, NULL);
+ inq_quality, entry_ctx, NULL, NULL);
/* Most pinentries out in the wild return the old Assuan error code
for canceled which gets translated to an assuan Cancel error and
not to the code for a user cancel. Fix this here. */
Modified: trunk/agent/command-ssh.c
===================================================================
--- trunk/agent/command-ssh.c 2009-05-13 17:12:00 UTC (rev 5008)
+++ trunk/agent/command-ssh.c 2009-05-15 11:16:28 UTC (rev 5009)
@@ -1,5 +1,5 @@
/* command-ssh.c - gpg-agent's ssh-agent emulation layer
- * Copyright (C) 2004, 2005, 2006 Free Software Foundation, Inc.
+ * Copyright (C) 2004, 2005, 2006, 2009 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -710,17 +710,20 @@
/* Search the file at stream FP from the beginning until a matching
HEXGRIP is found; return success in this case and store true at
- DISABLED if the found key has been disabled. */
+ DISABLED if the found key has been disabled. If R_TTL is not NULL
+ a specified TTL for that key is stored there. */
static gpg_error_t
-search_control_file (FILE *fp, const char *hexgrip, int *disabled)
+search_control_file (FILE *fp, const char *hexgrip,
+ int *r_disabled, int *r_ttl)
{
int c, i;
- char *p, line[256];
-
+ char *p, *pend, line[256];
+ long ttl;
+
assert (strlen (hexgrip) == 40 );
rewind (fp);
- *disabled = 0;
+ *r_disabled = 0;
next_line:
do
{
@@ -746,10 +749,10 @@
}
while (!*p || *p == '\n' || *p == '#');
- *disabled = 0;
+ *r_disabled = 0;
if (*p == '!')
{
- *disabled = 1;
+ *r_disabled = 1;
for (p++; spacep (p); p++)
;
}
@@ -763,8 +766,18 @@
return gpg_error (GPG_ERR_BAD_DATA);
}
- /* Fixme: Get TTL and flags. */
+ ttl = strtol (p, &pend, 10);
+ p = pend;
+ if (!(spacep (p) || *p == '\n') || ttl < -1)
+ {
+ log_error ("invalid TTL value in ssh control file; assuming 0\n");
+ ttl = 0;
+ }
+ if (r_ttl)
+ *r_ttl = ttl;
+ /* Here is the place to parse flags if we need them. */
+
return 0; /* Okay: found it. */
}
@@ -788,7 +801,7 @@
if (err)
return err;
- err = search_control_file (fp, hexgrip, &disabled);
+ err = search_control_file (fp, hexgrip, &disabled, NULL);
if (err && gpg_err_code(err) == GPG_ERR_EOF)
{
struct tm *tp;
@@ -808,7 +821,30 @@
}
+/* Scan the sshcontrol file and return the TTL. */
+static int
+ttl_from_sshcontrol (const char *hexgrip)
+{
+ FILE *fp;
+ int disabled, ttl;
+ if (!hexgrip || strlen (hexgrip) != 40)
+ return 0; /* Wrong input: Use global default. */
+
+ if (open_control_file (&fp, 0))
+ return 0; /* Error: Use the global default TTL. */
+
+ if (search_control_file (fp, hexgrip, &disabled, &ttl)
+ || disabled)
+ ttl = 0; /* Use the global default if not found or disabled. */
+
+ fclose (fp);
+
+ return ttl;
+}
+
+
+
/*
@@ -1875,7 +1911,7 @@
hexgrip[40] = 0;
if ( strlen (hexgrip) != 40 )
continue;
- if (search_control_file (ctrl_fp, hexgrip, &disabled)
+ if (search_control_file (ctrl_fp, hexgrip, &disabled, NULL)
|| disabled)
continue;
@@ -1972,6 +2008,7 @@
return ret_err;
}
+
/* This function hashes the data contained in DATA of size DATA_N
according to the message digest algorithm specified by MD_ALGORITHM
and writes the message digest to HASH, which needs to large enough
@@ -2017,7 +2054,7 @@
err = agent_pksign_do (ctrl,
_("Please enter the passphrase "
"for the ssh key%0A %c"), &signature_sexp,
- CACHE_MODE_SSH);
+ CACHE_MODE_SSH, ttl_from_sshcontrol);
ctrl->use_auth_call = 0;
if (err)
goto out;
Modified: trunk/agent/command.c
===================================================================
--- trunk/agent/command.c 2009-05-13 17:12:00 UTC (rev 5008)
+++ trunk/agent/command.c 2009-05-15 11:16:28 UTC (rev 5009)
@@ -986,7 +986,8 @@
}
-/* GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]] <cache_id>
+/* GET_PASSPHRASE [--data] [--check] [--no-ask] [--repeat[=N]]
+ [--qualitybar] <cache_id>
[<error_message> <prompt> <description>]
This function is usually used to ask for a passphrase to be used
@@ -1007,6 +1008,10 @@
If the 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 GPG_ERR_NO_DATA is returned.
+
+ If the option "--qualitybar" is used a visual indication of the
+ entered passphrase quality is shown. (Unless no minimum passphrase
+ length has been configured.)
*/
static int
@@ -1020,7 +1025,8 @@
const char *desc2 = _("Please re-enter this passphrase");
char *p;
void *cache_marker;
- int opt_data, opt_check, opt_no_ask, opt_repeat = 0;
+ int opt_data, opt_check, opt_no_ask, opt_qualbar;
+ int opt_repeat = 0;
char *repeat_errtext = NULL;
opt_data = has_option (line, "--data");
@@ -1034,6 +1040,7 @@
else
opt_repeat = 1;
}
+ opt_qualbar = has_option (line, "--qualitybar");
line = skip_options (line);
cacheid = line;
@@ -1102,7 +1109,8 @@
next_try:
rc = agent_get_passphrase (ctrl, &response, desc, prompt,
- repeat_errtext? repeat_errtext:errtext);
+ repeat_errtext? repeat_errtext:errtext,
+ opt_qualbar);
xfree (repeat_errtext);
repeat_errtext = NULL;
if (!rc)
@@ -1119,7 +1127,7 @@
char *response2;
rc = agent_get_passphrase (ctrl, &response2, desc2, prompt,
- errtext);
+ errtext, 0);
if (rc)
break;
if (strcmp (response2, response))
@@ -1265,7 +1273,8 @@
ctrl->in_passwd++;
rc = agent_key_from_file (ctrl, ctrl->server_local->keydesc,
- grip, &shadow_info, CACHE_MODE_IGNORE, &s_skey);
+ grip, &shadow_info, CACHE_MODE_IGNORE, NULL,
+ &s_skey);
if (rc)
;
else if (!s_skey)
Modified: trunk/agent/findkey.c
===================================================================
--- trunk/agent/findkey.c 2009-05-13 17:12:00 UTC (rev 5008)
+++ trunk/agent/findkey.c 2009-05-15 11:16:28 UTC (rev 5009)
@@ -297,11 +297,12 @@
/* Unprotect the canconical encoded S-expression key in KEYBUF. GRIP
should be the hex encoded keygrip of that key to be used with the
caching mechanism. DESC_TEXT may be set to override the default
- description used for the pinentry. */
+ description used for the pinentry. If LOOKUP_TTL is given this
+ function is used to lookup the default ttl. */
static int
unprotect (ctrl_t ctrl, const char *desc_text,
unsigned char **keybuf, const unsigned char *grip,
- cache_mode_t cache_mode)
+ cache_mode_t cache_mode, lookup_ttl_t lookup_ttl)
{
struct pin_entry_info_s *pi;
struct try_unprotect_arg_s arg;
@@ -406,7 +407,8 @@
return rc;
}
}
- agent_put_cache (hexgrip, cache_mode, pi->pin, 0);
+ agent_put_cache (hexgrip, cache_mode, pi->pin,
+ lookup_ttl? lookup_ttl (hexgrip) : 0);
xfree (*keybuf);
*keybuf = arg.unprotected_key;
}
@@ -488,11 +490,16 @@
to a token; in this case an allocated S-expression with the
shadow_info part from the file is stored at SHADOW_INFO.
CACHE_MODE defines now the cache shall be used. DESC_TEXT may be
- set to present a custom description for the pinentry. */
+ set to present a custom description for the pinentry. LOOKUP_TTL
+ is an optional function to convey a TTL to the cache manager; we do
+ not simply pass the TTL value because the value is only needed if an
+ unprotect action was needed and looking up the TTL may have some
+ overhead (e.g. scanning the sshcontrol file). */
gpg_error_t
agent_key_from_file (ctrl_t ctrl, const char *desc_text,
const unsigned char *grip, unsigned char **shadow_info,
- cache_mode_t cache_mode, gcry_sexp_t *result)
+ cache_mode_t cache_mode, lookup_ttl_t lookup_ttl,
+ gcry_sexp_t *result)
{
int rc;
unsigned char *buf;
@@ -502,7 +509,7 @@
*result = NULL;
if (shadow_info)
- *shadow_info = NULL;
+ *shadow_info = NULL;
rc = read_key_file (grip, &s_skey);
if (rc)
@@ -563,7 +570,8 @@
if (!rc)
{
- rc = unprotect (ctrl, desc_text_final, &buf, grip, cache_mode);
+ rc = unprotect (ctrl, desc_text_final, &buf, grip,
+ cache_mode, lookup_ttl);
if (rc)
log_error ("failed to unprotect the secret key: %s\n",
gpg_strerror (rc));
Modified: trunk/agent/pkdecrypt.c
===================================================================
--- trunk/agent/pkdecrypt.c 2009-05-13 17:12:00 UTC (rev 5008)
+++ trunk/agent/pkdecrypt.c 2009-05-15 11:16:28 UTC (rev 5009)
@@ -66,7 +66,7 @@
}
rc = agent_key_from_file (ctrl, desc_text,
ctrl->keygrip, &shadow_info,
- CACHE_MODE_NORMAL, &s_skey);
+ CACHE_MODE_NORMAL, NULL, &s_skey);
if (rc)
{
if (gpg_err_code (rc) == GPG_ERR_ENOENT)
Modified: trunk/agent/pksign.c
===================================================================
--- trunk/agent/pksign.c 2009-05-13 17:12:00 UTC (rev 5008)
+++ trunk/agent/pksign.c 2009-05-15 11:16:28 UTC (rev 5009)
@@ -125,10 +125,12 @@
/* SIGN whatever information we have accumulated in CTRL and return
- the signature S-Expression. */
+ the signature S-expression. LOOKUP is an optional function to
+ provide a way for lower layers to ask for the caching TTL. */
int
agent_pksign_do (ctrl_t ctrl, const char *desc_text,
- gcry_sexp_t *signature_sexp, cache_mode_t cache_mode)
+ gcry_sexp_t *signature_sexp,
+ cache_mode_t cache_mode, lookup_ttl_t lookup_ttl)
{
gcry_sexp_t s_skey = NULL, s_sig = NULL;
unsigned char *shadow_info = NULL;
@@ -138,7 +140,8 @@
return gpg_error (GPG_ERR_NO_SECKEY);
rc = agent_key_from_file (ctrl, desc_text, ctrl->keygrip,
- &shadow_info, cache_mode, &s_skey);
+ &shadow_info, cache_mode, lookup_ttl,
+ &s_skey);
if (rc)
{
log_error ("failed to read the secret key\n");
@@ -238,7 +241,7 @@
size_t len = 0;
int rc = 0;
- rc = agent_pksign_do (ctrl, desc_text, &s_sig, cache_mode);
+ rc = agent_pksign_do (ctrl, desc_text, &s_sig, cache_mode, NULL);
if (rc)
goto leave;
More information about the Gnupg-commits
mailing list