mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
agent: Avoid multiple calls to scd for KEYINFO.
* agent/command.c (struct server_local_s): Add last_card_keyinfo. (eventcounter): Add maybe_key_change. (cmd_genkey, cmd_scd, cmd_import_key, cmd_delete_key): Bump new counter. (cmd_keyinfo): Cache the keyinfo from the card. (start_command_handler): Release the cache. -- This cache speeds up processing of commands like "gpg -K" because scdaemon does not need to be asked for each key as long as nothing changed with the card. We should have a better notification service from scdaemon to make sure that we get only the relevant events. What we do right now is a bit course but sufficient. Signed-off-by: Werner Koch <wk@gnupg.org>
This commit is contained in:
parent
aaef0fc3a7
commit
2e86cca7f4
@ -112,6 +112,16 @@ struct server_local_s
|
|||||||
|
|
||||||
/* Last PASSWD_NONCE sent as status (malloced). */
|
/* Last PASSWD_NONCE sent as status (malloced). */
|
||||||
char *last_passwd_nonce;
|
char *last_passwd_nonce;
|
||||||
|
|
||||||
|
/* Per connection cache of the keyinfo from the cards. The
|
||||||
|
* eventcounters for cards at the time the info was fetched is
|
||||||
|
* stored here as a freshness indicator. */
|
||||||
|
struct {
|
||||||
|
struct card_key_info_s *ki;
|
||||||
|
unsigned int eventno;
|
||||||
|
unsigned int maybe_key_change;
|
||||||
|
} last_card_keyinfo;
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -148,6 +158,11 @@ struct
|
|||||||
detected. */
|
detected. */
|
||||||
unsigned int card;
|
unsigned int card;
|
||||||
|
|
||||||
|
/* Internal counter to track possible changes to a key.
|
||||||
|
* FIXME: This should be replaced by generic notifications from scd.
|
||||||
|
*/
|
||||||
|
unsigned int maybe_key_change;
|
||||||
|
|
||||||
} eventcounter;
|
} eventcounter;
|
||||||
|
|
||||||
|
|
||||||
@ -927,6 +942,8 @@ cmd_genkey (assuan_context_t ctx, char *line)
|
|||||||
if (*line)
|
if (*line)
|
||||||
cache_nonce = xtrystrdup (line);
|
cache_nonce = xtrystrdup (line);
|
||||||
|
|
||||||
|
eventcounter.maybe_key_change++;
|
||||||
|
|
||||||
/* First inquire the parameters */
|
/* First inquire the parameters */
|
||||||
rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", MAXLEN_KEYPARAM);
|
rc = print_assuan_status (ctx, "INQUIRE_MAXLEN", "%u", MAXLEN_KEYPARAM);
|
||||||
if (!rc)
|
if (!rc)
|
||||||
@ -1307,7 +1324,24 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
|
|||||||
if (opt_with_ssh || list_mode == 2)
|
if (opt_with_ssh || list_mode == 2)
|
||||||
cf = ssh_open_control_file ();
|
cf = ssh_open_control_file ();
|
||||||
|
|
||||||
agent_card_keyinfo (ctrl, NULL, 0, &keyinfo_on_cards);
|
/* Take the keyinfo for cards from our local cache. Actually this
|
||||||
|
* cache could be a global one but then we would need to employ
|
||||||
|
* reference counting. */
|
||||||
|
if (ctrl->server_local->last_card_keyinfo.ki
|
||||||
|
&& ctrl->server_local->last_card_keyinfo.eventno == eventcounter.card
|
||||||
|
&& (ctrl->server_local->last_card_keyinfo.maybe_key_change
|
||||||
|
== eventcounter.maybe_key_change))
|
||||||
|
{
|
||||||
|
keyinfo_on_cards = ctrl->server_local->last_card_keyinfo.ki;
|
||||||
|
}
|
||||||
|
else if (!agent_card_keyinfo (ctrl, NULL, 0, &keyinfo_on_cards))
|
||||||
|
{
|
||||||
|
agent_card_free_keyinfo (ctrl->server_local->last_card_keyinfo.ki);
|
||||||
|
ctrl->server_local->last_card_keyinfo.ki = keyinfo_on_cards;
|
||||||
|
ctrl->server_local->last_card_keyinfo.eventno = eventcounter.card;
|
||||||
|
ctrl->server_local->last_card_keyinfo.maybe_key_change
|
||||||
|
= eventcounter.maybe_key_change;
|
||||||
|
}
|
||||||
|
|
||||||
if (list_mode == 2)
|
if (list_mode == 2)
|
||||||
{
|
{
|
||||||
@ -1413,7 +1447,6 @@ cmd_keyinfo (assuan_context_t ctx, char *line)
|
|||||||
}
|
}
|
||||||
|
|
||||||
leave:
|
leave:
|
||||||
agent_card_free_keyinfo (keyinfo_on_cards);
|
|
||||||
ssh_close_control_file (cf);
|
ssh_close_control_file (cf);
|
||||||
if (dir)
|
if (dir)
|
||||||
closedir (dir);
|
closedir (dir);
|
||||||
@ -2034,6 +2067,9 @@ cmd_scd (assuan_context_t ctx, char *line)
|
|||||||
if (ctrl->restricted)
|
if (ctrl->restricted)
|
||||||
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
return leave_cmd (ctx, gpg_error (GPG_ERR_FORBIDDEN));
|
||||||
|
|
||||||
|
/* All SCD prefixed commands may change a key. */
|
||||||
|
eventcounter.maybe_key_change++;
|
||||||
|
|
||||||
rc = divert_generic_cmd (ctrl, line, ctx);
|
rc = divert_generic_cmd (ctrl, line, ctx);
|
||||||
#else
|
#else
|
||||||
(void)ctx; (void)line;
|
(void)ctx; (void)line;
|
||||||
@ -2152,6 +2188,8 @@ cmd_import_key (assuan_context_t ctx, char *line)
|
|||||||
if (*line)
|
if (*line)
|
||||||
cache_nonce = xtrystrdup (line);
|
cache_nonce = xtrystrdup (line);
|
||||||
|
|
||||||
|
eventcounter.maybe_key_change++;
|
||||||
|
|
||||||
assuan_begin_confidential (ctx);
|
assuan_begin_confidential (ctx);
|
||||||
err = assuan_inquire (ctx, "KEYDATA",
|
err = assuan_inquire (ctx, "KEYDATA",
|
||||||
&wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
|
&wrappedkey, &wrappedkeylen, MAXLEN_KEYDATA);
|
||||||
@ -2495,6 +2533,8 @@ cmd_delete_key (assuan_context_t ctx, char *line)
|
|||||||
stub_only = has_option (line, "--stub-only");
|
stub_only = has_option (line, "--stub-only");
|
||||||
line = skip_options (line);
|
line = skip_options (line);
|
||||||
|
|
||||||
|
eventcounter.maybe_key_change++;
|
||||||
|
|
||||||
/* If the use of a loopback pinentry has been disabled, we assume
|
/* If the use of a loopback pinentry has been disabled, we assume
|
||||||
* that a silent deletion of keys shall also not be allowed. */
|
* that a silent deletion of keys shall also not be allowed. */
|
||||||
if (!opt.allow_loopback_pinentry)
|
if (!opt.allow_loopback_pinentry)
|
||||||
@ -3640,6 +3680,9 @@ start_command_handler (ctrl_t ctrl, gnupg_fd_t listen_fd, gnupg_fd_t fd)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Clear the keyinfo cache. */
|
||||||
|
agent_card_free_keyinfo (ctrl->server_local->last_card_keyinfo.ki);
|
||||||
|
|
||||||
/* Reset the nonce caches. */
|
/* Reset the nonce caches. */
|
||||||
clear_nonce_cache (ctrl);
|
clear_nonce_cache (ctrl);
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user