diff options
author | NIIBE Yutaka <gniibe@fsij.org> | 2019-06-04 02:17:21 +0200 |
---|---|---|
committer | NIIBE Yutaka <gniibe@fsij.org> | 2019-06-04 02:17:21 +0200 |
commit | 20acc7c0226550530085a674ef1bb41ebfa39408 (patch) | |
tree | b459b077352be56c64262645039a04f213139ce7 /g10 | |
parent | doc: Add a section for gpg-check-pattern. (diff) | |
download | gnupg2-20acc7c0226550530085a674ef1bb41ebfa39408.tar.xz gnupg2-20acc7c0226550530085a674ef1bb41ebfa39408.zip |
g10,agent: Support CONFIRM for --delete-key.
* agent/call-pinentry.c (agent_get_confirmation): Add call of
pinentry_loopback_confirm.
(agent_popup_message_start): Likewise.
(agent_popup_message_stop): Return if it's loopback mode.
* agent/command.c (pinentry_loopback_confirm): New.
* g10/call-agent.c (default_inq_cb): Support "CONFIRM" inquery
when PINENTRY_MODE_LOOPBACK mode.
(confirm_status_cb): New.
(agent_delete_key): Supply confirm_status_cb to set the description
string for confirmation.
--
In the Assuan communication, we introduce new interaction:
[gpg] [gpg-agent]
--- CMD: PKDECRYPT -->
<-- STATUS: SETDESC "..."
<-- STATUS: SETOK "..."
<-- STATUS: SETNOTOK "..."
<-- INQUERY: CONFIRM 0/1 (0 for display, 1 for user query)
--- INQUERY-result: -->
<-- RESULT: ...
GnuPG-bug-id: 3465
Signed-off-by: NIIBE Yutaka <gniibe@fsij.org>
Diffstat (limited to 'g10')
-rw-r--r-- | g10/call-agent.c | 66 |
1 files changed, 64 insertions, 2 deletions
diff --git a/g10/call-agent.c b/g10/call-agent.c index f6c7d3951..19deb73d7 100644 --- a/g10/call-agent.c +++ b/g10/call-agent.c @@ -41,6 +41,7 @@ #include "../common/status.h" #include "../common/shareddefs.h" #include "../common/host2net.h" +#include "../common/ttyio.h" #define CONTROL_D ('D' - 'A' + 1) @@ -48,6 +49,13 @@ static assuan_context_t agent_ctx = NULL; static int did_early_card_test; +struct confirm_parm_s +{ + char *desc; + char *ok; + char *notok; +}; + struct default_inq_parm_s { ctrl_t ctrl; @@ -57,6 +65,7 @@ struct default_inq_parm_s u32 *mainkeyid; int pubkey_algo; } keyinfo; + struct confirm_parm_s *confirm; }; struct cipher_parm_s @@ -136,6 +145,7 @@ default_inq_cb (void *opaque, const char *line) { gpg_error_t err = 0; struct default_inq_parm_s *parm = opaque; + const char *s; if (has_leading_keyword (line, "PINENTRY_LAUNCHED")) { @@ -151,7 +161,7 @@ default_inq_cb (void *opaque, const char *line) { if (have_static_passphrase ()) { - const char *s = get_static_passphrase (); + s = get_static_passphrase (); err = assuan_send_data (parm->ctx, s, strlen (s)); } else @@ -176,6 +186,27 @@ default_inq_cb (void *opaque, const char *line) xfree (pw); } } + else if ((s = has_leading_keyword (line, "CONFIRM")) + && opt.pinentry_mode == PINENTRY_MODE_LOOPBACK + && parm->confirm) + { + int ask = atoi (s); + int yes; + + if (ask) + { + yes = cpr_get_answer_is_yes (NULL, parm->confirm->desc); + if (yes) + err = assuan_send_data (parm->ctx, NULL, 0); + else + err = gpg_error (GPG_ERR_NOT_CONFIRMED); + } + else + { + tty_printf ("%s", parm->confirm->desc); + err = assuan_send_data (parm->ctx, NULL, 0); + } + } else log_debug ("ignoring gpg-agent inquiry '%s'\n", line); @@ -2512,6 +2543,31 @@ agent_export_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc, } +/* Status callback for handling confirmation. */ +static gpg_error_t +confirm_status_cb (void *opaque, const char *line) +{ + struct confirm_parm_s *parm = opaque; + const char *s; + + if ((s = has_leading_keyword (line, "SETDESC"))) + { + xfree (parm->desc); + parm->desc = unescape_status_string (s); + } + else if ((s = has_leading_keyword (line, "SETOK"))) + { + xfree (parm->ok); + parm->ok = unescape_status_string (s); + } + else if ((s = has_leading_keyword (line, "SETNOTOK"))) + { + xfree (parm->notok); + parm->notok = unescape_status_string (s); + } + + return 0; +} /* Ask the agent to delete the key identified by HEXKEYGRIP. If DESC is not NULL, display DESC instead of the default description @@ -2524,9 +2580,12 @@ agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc, gpg_error_t err; char line[ASSUAN_LINELENGTH]; struct default_inq_parm_s dfltparm; + struct confirm_parm_s confirm_parm; + memset (&confirm_parm, 0, sizeof confirm_parm); memset (&dfltparm, 0, sizeof dfltparm); dfltparm.ctrl = ctrl; + dfltparm.confirm = &confirm_parm; err = start_agent (ctrl, 0); if (err) @@ -2548,7 +2607,10 @@ agent_delete_key (ctrl_t ctrl, const char *hexkeygrip, const char *desc, force? " --force":"", hexkeygrip); err = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, &dfltparm, - NULL, NULL); + confirm_status_cb, &confirm_parm); + xfree (confirm_parm.desc); + xfree (confirm_parm.ok); + xfree (confirm_parm.notok); return err; } |