aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNeal H. Walfield <[email protected]>2015-05-06 13:20:32 +0000
committerNeal H. Walfield <[email protected]>2015-05-07 13:03:27 +0000
commit56b5c9f94f2e55d096be585ed061ccf1c9ec0de6 (patch)
tree1fa93938e1cfd7504520282f7b8cc1ff0f53adad
parentagent: Or in the value; don't overwrite the variable. (diff)
downloadgnupg-56b5c9f94f2e55d096be585ed061ccf1c9ec0de6.tar.gz
gnupg-56b5c9f94f2e55d096be585ed061ccf1c9ec0de6.zip
agent: Improve support for externally cached passwords.
* agent/call-pinentry.c (PINENTRY_STATUS_PASSWORD_FROM_CACHE): New constant. (pinentry_status_cb): Add it to *FLAGS if PASSWORD_FROM_CACHE was provided. (agent_askpin): Pass "OPTION allow-external-password-cache" to the pinentry. Always pass SETKEYINFO to the pinentry. If there is no stable identifier, then use "--clear". If the password is incorrect and PINENTRY_STATUS_PASSWORD_FROM_CACHE is set in *PINENTRY_STATUS, then decrement PININFO->FAILED_TRIES. -- Signed-off-by: Neal H. Walfield <[email protected]>
Diffstat (limited to '')
-rw-r--r--agent/call-pinentry.c47
1 files changed, 35 insertions, 12 deletions
diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c
index 925386637..8c6fd085a 100644
--- a/agent/call-pinentry.c
+++ b/agent/call-pinentry.c
@@ -713,7 +713,8 @@ setup_qualitybar (void)
enum
{
PINENTRY_STATUS_CLOSE_BUTTON = 1 << 0,
- PINENTRY_STATUS_PIN_REPEATED = 1 << 8
+ PINENTRY_STATUS_PIN_REPEATED = 1 << 8,
+ PINENTRY_STATUS_PASSWORD_FROM_CACHE = 1 << 9
};
/* Check the button_info line for a close action. Also check for the
@@ -733,6 +734,10 @@ pinentry_status_cb (void *opaque, const char *line)
{
*flag |= PINENTRY_STATUS_PIN_REPEATED;
}
+ else if (has_leading_keyword (line, "PASSWORD_FROM_CACHE"))
+ {
+ *flag |= PINENTRY_STATUS_PASSWORD_FROM_CACHE;
+ }
return 0;
}
@@ -809,23 +814,36 @@ agent_askpin (ctrl_t ctrl,
if (rc)
return rc;
- /* If we have a KYEINFO string and are normal, user, or ssh cache
+ /* Indicate to the pinentry that it may read from an external cache.
+
+ It is essential that the pinentry respect this. If the cached
+ password is not up to date and retry == 1, then, using a version
+ of GPG Agent that doesn't support this, won't issue another pin
+ request and the user won't get a chance to correct the
+ password. */
+ rc = assuan_transact (entry_ctx, "OPTION allow-external-password-cache",
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
+ return unlock_pinentry (rc);
+
+ /* If we have a KEYINFO string and are normal, user, or ssh cache
mode, we tell that the Pinentry so it may use it for own caching
purposes. Most pinentries won't have this implemented and thus
we do not error out in this case. */
if (keyinfo && (cache_mode == CACHE_MODE_NORMAL
|| cache_mode == CACHE_MODE_USER
|| cache_mode == CACHE_MODE_SSH))
- {
- snprintf (line, DIM(line)-1, "SETKEYINFO %c/%s",
- cache_mode == CACHE_MODE_USER? 'u' :
- cache_mode == CACHE_MODE_SSH? 's' : 'n',
- keyinfo);
- rc = assuan_transact (entry_ctx, line,
- NULL, NULL, NULL, NULL, NULL, NULL);
- if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
- return unlock_pinentry (rc);
- }
+ snprintf (line, DIM(line)-1, "SETKEYINFO %c/%s",
+ cache_mode == CACHE_MODE_USER? 'u' :
+ cache_mode == CACHE_MODE_SSH? 's' : 'n',
+ keyinfo);
+ else
+ snprintf (line, DIM(line)-1, "SETKEYINFO --clear");
+
+ rc = assuan_transact (entry_ctx, line,
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ if (rc && gpg_err_code (rc) != GPG_ERR_ASS_UNKNOWN_CMD)
+ return unlock_pinentry (rc);
snprintf (line, DIM(line)-1, "SETDESC %s", desc_text);
line[DIM(line)-1] = 0;
@@ -965,6 +983,11 @@ agent_askpin (ctrl_t ctrl,
pininfo->repeat_okay = 1;
return unlock_pinentry (0); /* okay, got a PIN or passphrase */
}
+
+ if ((pinentry_status & PINENTRY_STATUS_PASSWORD_FROM_CACHE))
+ /* The password was read from the cache. Don't count this
+ against the retry count. */
+ pininfo->failed_tries --;
}
return unlock_pinentry (gpg_error (pininfo->min_digits? GPG_ERR_BAD_PIN