1
0
镜像来自 git://git.gnupg.org/gnupg.git synced 2025-07-01 22:37:57 +02:00

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 <neal@g10code.com>
This commit is contained in:
Neal H. Walfield 2015-05-06 15:20:32 +02:00
父節點 74944330ba
當前提交 56b5c9f94f

查看文件

@ -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