From 2180845959839705200e3172dbafc94b70b9007f Mon Sep 17 00:00:00 2001 From: Werner Koch Date: Tue, 14 Apr 2015 18:41:05 +0200 Subject: [PATCH] agent: Send the new SETKEYINFO command to the Pinentry. * agent/call-pinentry.c (agent_askpin): Add args keyinfo and cache_mode. Change all callers to pass (NULL,0) for them. Send SETKEYINFO command. * agent/findkey.c (unprotect): Pass the keygrip and the cache_mode for the new args. Signed-off-by: Werner Koch --- agent/agent.h | 3 ++- agent/call-pinentry.c | 24 ++++++++++++++++++++++-- agent/command-ssh.c | 4 ++-- agent/cvt-openpgp.c | 2 +- agent/divert-scd.c | 6 +++--- agent/findkey.c | 2 +- agent/genkey.c | 4 ++-- 7 files changed, 33 insertions(+), 12 deletions(-) diff --git a/agent/agent.h b/agent/agent.h index 30d0ffb5a..2a2658de7 100644 --- a/agent/agent.h +++ b/agent/agent.h @@ -354,7 +354,8 @@ int pinentry_active_p (ctrl_t ctrl, int waitseconds); int agent_askpin (ctrl_t ctrl, const char *desc_text, const char *prompt_text, const char *inital_errtext, - struct pin_entry_info_s *pininfo); + struct pin_entry_info_s *pininfo, + const char *keyinfo, cache_mode_t cache_mode); int agent_get_passphrase (ctrl_t ctrl, char **retpass, const char *desc, const char *prompt, const char *errtext, int with_qualitybar); diff --git a/agent/call-pinentry.c b/agent/call-pinentry.c index 6db429c47..d3a0547aa 100644 --- a/agent/call-pinentry.c +++ b/agent/call-pinentry.c @@ -737,12 +737,14 @@ close_button_status_cb (void *opaque, const char *line) /* 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 - numbers. */ + numbers. KEYINFO and CACHEMODE are used to tell pinentry something + about the key. */ int agent_askpin (ctrl_t ctrl, const char *desc_text, const char *prompt_text, const char *initial_errtext, - struct pin_entry_info_s *pininfo) + struct pin_entry_info_s *pininfo, + const char *keyinfo, cache_mode_t cache_mode) { int rc; char line[ASSUAN_LINELENGTH]; @@ -802,6 +804,24 @@ agent_askpin (ctrl_t ctrl, if (rc) return rc; + /* If we have a KYEINFO 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, "SETDESC %s", desc_text); line[DIM(line)-1] = 0; rc = assuan_transact (entry_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); diff --git a/agent/command-ssh.c b/agent/command-ssh.c index fffdb00d9..a51782772 100644 --- a/agent/command-ssh.c +++ b/agent/command-ssh.c @@ -3110,7 +3110,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec, pi2->check_cb_arg = pi->pin; next_try: - err = agent_askpin (ctrl, description, NULL, initial_errtext, pi); + err = agent_askpin (ctrl, description, NULL, initial_errtext, pi, NULL, 0); initial_errtext = NULL; if (err) goto out; @@ -3119,7 +3119,7 @@ ssh_identity_register (ctrl_t ctrl, ssh_key_type_spec_t *spec, it already did the repetition check, ask to confirm it. */ if (*pi->pin && !pi->repeat_okay) { - err = agent_askpin (ctrl, description2, NULL, NULL, pi2); + err = agent_askpin (ctrl, description2, NULL, NULL, pi2, NULL, 0); if (err == -1) { /* The re-entered one did not match and the user did not hit cancel. */ diff --git a/agent/cvt-openpgp.c b/agent/cvt-openpgp.c index b00f032e7..562179b26 100644 --- a/agent/cvt-openpgp.c +++ b/agent/cvt-openpgp.c @@ -961,7 +961,7 @@ convert_from_openpgp_main (ctrl_t ctrl, gcry_sexp_t s_pgp, err = try_do_unprotect_cb (pi); } if (gpg_err_code (err) == GPG_ERR_BAD_PASSPHRASE && !from_native) - err = agent_askpin (ctrl, prompt, NULL, NULL, pi); + err = agent_askpin (ctrl, prompt, NULL, NULL, pi, NULL, 0); skeyidx = pi_arg.skeyidx; if (!err && r_passphrase && is_protected) { diff --git a/agent/divert-scd.c b/agent/divert-scd.c index 1408d65af..0c287b4dd 100644 --- a/agent/divert-scd.c +++ b/agent/divert-scd.c @@ -270,7 +270,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) if (any_flags) { - rc = agent_askpin (ctrl, info, prompt, again_text, pi); + rc = agent_askpin (ctrl, info, prompt, again_text, pi, NULL, 0); again_text = NULL; if (!rc && newpin) { @@ -292,7 +292,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) is_puk? _("Repeat this PUK"): _("Repeat this PIN")), - prompt, NULL, pi2); + prompt, NULL, pi2, NULL, 0); if (!rc && strcmp (pi->pin, pi2->pin)) { again_text = (resetcode? @@ -316,7 +316,7 @@ getpin_cb (void *opaque, const char *info, char *buf, size_t maxbuf) info? info:"", info? ")":"") < 0) desc = NULL; - rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi); + rc = agent_askpin (ctrl, desc?desc:info, prompt, NULL, pi, NULL, 0); xfree (desc); } diff --git a/agent/findkey.c b/agent/findkey.c index 6f01789cd..80771c5bb 100644 --- a/agent/findkey.c +++ b/agent/findkey.c @@ -463,7 +463,7 @@ unprotect (ctrl_t ctrl, const char *cache_nonce, const char *desc_text, arg.change_required = 0; pi->check_cb_arg = &arg; - rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi); + rc = agent_askpin (ctrl, desc_text, NULL, NULL, pi, hexgrip, cache_mode); if (!rc) { assert (arg.unprotected_key); diff --git a/agent/genkey.c b/agent/genkey.c index ecf676eff..30fc44d60 100644 --- a/agent/genkey.c +++ b/agent/genkey.c @@ -370,7 +370,7 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt, pi2->check_cb_arg = pi->pin; next_try: - err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi); + err = agent_askpin (ctrl, text1, NULL, initial_errtext, pi, NULL, 0); initial_errtext = NULL; if (!err) { @@ -384,7 +384,7 @@ agent_ask_new_passphrase (ctrl_t ctrl, const char *prompt, it already did the repetition check, ask to confirm it. */ if (*pi->pin && !pi->repeat_okay) { - err = agent_askpin (ctrl, text2, NULL, NULL, pi2); + err = agent_askpin (ctrl, text2, NULL, NULL, pi2, NULL, 0); if (err == -1) { /* The re-entered one did not match and the user did not hit cancel. */