summaryrefslogtreecommitdiffstats
path: root/g10
diff options
context:
space:
mode:
authorNIIBE Yutaka <gniibe@fsij.org>2019-06-04 02:17:21 +0200
committerNIIBE Yutaka <gniibe@fsij.org>2019-06-04 02:17:21 +0200
commit20acc7c0226550530085a674ef1bb41ebfa39408 (patch)
treeb459b077352be56c64262645039a04f213139ce7 /g10
parentdoc: Add a section for gpg-check-pattern. (diff)
downloadgnupg2-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.c66
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;
}