summaryrefslogtreecommitdiffstats
path: root/sm
diff options
context:
space:
mode:
authorWerner Koch <wk@gnupg.org>2008-02-14 20:50:10 +0100
committerWerner Koch <wk@gnupg.org>2008-02-14 20:50:10 +0100
commit30a97e770cce0d6529058052cd78990ff08b84ad (patch)
tree626d2942172a8387a1cc00a1a9bce1e5bba1ad52 /sm
parentAlways search missing certifcates using a running Dirmngr's cache. (diff)
downloadgnupg2-30a97e770cce0d6529058052cd78990ff08b84ad.tar.xz
gnupg2-30a97e770cce0d6529058052cd78990ff08b84ad.zip
Poems for AllowSetForegroundWindow (W32)
Diffstat (limited to 'sm')
-rw-r--r--sm/ChangeLog13
-rw-r--r--sm/call-agent.c104
-rw-r--r--sm/gpgsm.h2
-rw-r--r--sm/server.c21
4 files changed, 114 insertions, 26 deletions
diff --git a/sm/ChangeLog b/sm/ChangeLog
index 2ba2ee3b2..8f348a5f2 100644
--- a/sm/ChangeLog
+++ b/sm/ChangeLog
@@ -1,3 +1,16 @@
+2008-02-14 Werner Koch <wk@g10code.com>
+
+ * server.c (option_handler): Add option allow-pinentry-notify.
+ (gpgsm_proxy_pinentry_notify): New.
+ * call-agent.c (default_inq_cb): New.
+ (gpgsm_agent_pksign, gpgsm_scd_pksign, gpgsm_agent_readkey)
+ (gpgsm_agent_istrusted, gpgsm_agent_marktrusted)
+ (gpgsm_agent_passwd, gpgsm_agent_get_confirmation): Call it.
+ (struct cipher_parm_s, struct genkey_parm_s): Add field CTRL.
+ (inq_ciphertext_cb): Test keyword and fallback to default_inq_cb.
+ (inq_genkey_parms): Ditto.
+ (start_agent): Tell agent to send us the pinentry notifications.
+
2008-02-13 Werner Koch <wk@g10code.com>
* call-dirmngr.c (gpgsm_dirmngr_lookup): Add arg CACHE_ONLY.
diff --git a/sm/call-agent.c b/sm/call-agent.c
index e0461d95f..625ca9d6e 100644
--- a/sm/call-agent.c
+++ b/sm/call-agent.c
@@ -1,6 +1,6 @@
-/* call-agent.c - divert operations to the agent
- * Copyright (C) 2001, 2002, 2003, 2005,
- * 2007 Free Software Foundation, Inc.
+/* call-agent.c - Divert GPGSM operations to the agent
+ * Copyright (C) 2001, 2002, 2003, 2005, 2007,
+ * 2008 Free Software Foundation, Inc.
*
* This file is part of GnuPG.
*
@@ -44,6 +44,7 @@ static assuan_context_t agent_ctx = NULL;
struct cipher_parm_s
{
+ ctrl_t ctrl;
assuan_context_t ctx;
const unsigned char *ciphertext;
size_t ciphertextlen;
@@ -51,6 +52,7 @@ struct cipher_parm_s
struct genkey_parm_s
{
+ ctrl_t ctrl;
assuan_context_t ctx;
const unsigned char *sexp;
size_t sexplen;
@@ -78,15 +80,27 @@ start_agent (ctrl_t ctrl)
serialize the access to the agent (which is
suitable given that the agent is not MT. */
else
- rc = start_new_gpg_agent (&agent_ctx,
- GPG_ERR_SOURCE_DEFAULT,
- opt.homedir,
- opt.agent_program,
- opt.display, opt.ttyname, opt.ttytype,
- opt.lc_ctype, opt.lc_messages,
- opt.xauthority, opt.pinentry_user_data,
- opt.verbose, DBG_ASSUAN,
- gpgsm_status2, ctrl);
+ {
+ rc = start_new_gpg_agent (&agent_ctx,
+ GPG_ERR_SOURCE_DEFAULT,
+ opt.homedir,
+ opt.agent_program,
+ opt.display, opt.ttyname, opt.ttytype,
+ opt.lc_ctype, opt.lc_messages,
+ opt.xauthority, opt.pinentry_user_data,
+ opt.verbose, DBG_ASSUAN,
+ gpgsm_status2, ctrl);
+
+ if (!rc)
+ {
+ /* Tell the agent that we support Pinentry notifications. No
+ error checking so that it will work also with older
+ agents. */
+ assuan_transact (agent_ctx, "OPTION allow-pinentry-notify",
+ NULL, NULL, NULL, NULL, NULL, NULL);
+ }
+ }
+
if (!ctrl->agent_seen)
{
ctrl->agent_seen = 1;
@@ -109,6 +123,29 @@ membuf_data_cb (void *opaque, const void *buffer, size_t length)
}
+/* This is the default inquiry callback. It mainly handles the
+ Pinentry notifications. */
+static int
+default_inq_cb (void *opaque, const char *line)
+{
+ gpg_error_t err;
+ ctrl_t ctrl = opaque;
+
+ if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
+ {
+ err = gpgsm_proxy_pinentry_notify (ctrl, line);
+ if (err)
+ log_error (_("failed to proxy %s inquiry to client\n"),
+ "PINENTRY_LAUNCHED");
+ /* We do not pass errors to avoid breaking other code. */
+ }
+ else
+ log_error ("ignoring gpg-agent inquiry `%s'\n", line);
+
+ return 0;
+}
+
+
/* Call the agent to do a sign operation using the key identified by
@@ -161,7 +198,8 @@ gpgsm_agent_pksign (ctrl_t ctrl, const char *keygrip, const char *desc,
init_membuf (&data, 1024);
rc = assuan_transact (agent_ctx, "PKSIGN",
- membuf_data_cb, &data, NULL, NULL, NULL, NULL);
+ membuf_data_cb, &data, default_inq_cb, ctrl,
+ NULL, NULL);
if (rc)
{
xfree (get_membuf (&data, &len));
@@ -225,7 +263,8 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
snprintf (line, DIM(line)-1, "SCD PKSIGN %s %s", hashopt, keyid);
line[DIM(line)-1] = 0;
rc = assuan_transact (agent_ctx, line,
- membuf_data_cb, &data, NULL, NULL, NULL, NULL);
+ membuf_data_cb, &data, default_inq_cb, ctrl,
+ NULL, NULL);
if (rc)
{
xfree (get_membuf (&data, &len));
@@ -262,14 +301,20 @@ gpgsm_scd_pksign (ctrl_t ctrl, const char *keyid, const char *desc,
/* Handle a CIPHERTEXT inquiry. Note, we only send the data,
assuan_transact talkes care of flushing and writing the end */
static int
-inq_ciphertext_cb (void *opaque, const char *keyword)
+inq_ciphertext_cb (void *opaque, const char *line)
{
struct cipher_parm_s *parm = opaque;
int rc;
- assuan_begin_confidential (parm->ctx);
- rc = assuan_send_data (parm->ctx, parm->ciphertext, parm->ciphertextlen);
- assuan_end_confidential (parm->ctx);
+ if (!strncmp (line, "CIPHERTEXT", 10) && (line[10]==' '||!line[10]))
+ {
+ assuan_begin_confidential (parm->ctx);
+ rc = assuan_send_data (parm->ctx, parm->ciphertext, parm->ciphertextlen);
+ assuan_end_confidential (parm->ctx);
+ }
+ else
+ rc = default_inq_cb (parm->ctrl, line);
+
return rc;
}
@@ -323,6 +368,7 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
}
init_membuf (&data, 1024);
+ cipher_parm.ctrl = ctrl;
cipher_parm.ctx = agent_ctx;
cipher_parm.ciphertext = ciphertext;
cipher_parm.ciphertextlen = ciphertextlen;
@@ -377,12 +423,18 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
/* Handle a KEYPARMS inquiry. Note, we only send the data,
assuan_transact takes care of flushing and writing the end */
static int
-inq_genkey_parms (void *opaque, const char *keyword)
+inq_genkey_parms (void *opaque, const char *line)
{
struct genkey_parm_s *parm = opaque;
int rc;
- rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen);
+ if (!strncmp (line, "KEYPARAM", 8) && (line[8]==' '||!line[8]))
+ {
+ rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen);
+ }
+ else
+ rc = default_inq_cb (parm->ctrl, line);
+
return rc;
}
@@ -409,6 +461,7 @@ gpgsm_agent_genkey (ctrl_t ctrl,
return rc;
init_membuf (&data, 1024);
+ gk_parm.ctrl = ctrl;
gk_parm.ctx = agent_ctx;
gk_parm.sexp = keyparms;
gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL);
@@ -465,7 +518,7 @@ gpgsm_agent_readkey (ctrl_t ctrl, int fromcard, const char *hexkeygrip,
init_membuf (&data, 1024);
rc = assuan_transact (agent_ctx, line,
membuf_data_cb, &data,
- NULL, NULL, NULL, NULL);
+ default_inq_cb, ctrl, NULL, NULL);
if (rc)
{
xfree (get_membuf (&data, &len));
@@ -568,7 +621,8 @@ gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert)
ksba_free (dn);
xfree (fpr);
- rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+ rc = assuan_transact (agent_ctx, line, NULL, NULL,
+ default_inq_cb, ctrl, NULL, NULL);
return rc;
}
@@ -722,7 +776,8 @@ gpgsm_agent_passwd (ctrl_t ctrl, const char *hexkeygrip, const char *desc)
snprintf (line, DIM(line)-1, "PASSWD %s", hexkeygrip);
line[DIM(line)-1] = 0;
- rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+ rc = assuan_transact (agent_ctx, line, NULL, NULL,
+ default_inq_cb, ctrl, NULL, NULL);
return rc;
}
@@ -743,6 +798,7 @@ gpgsm_agent_get_confirmation (ctrl_t ctrl, const char *desc)
snprintf (line, DIM(line)-1, "GET_CONFIRMATION %s", desc);
line[DIM(line)-1] = 0;
- rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL);
+ rc = assuan_transact (agent_ctx, line, NULL, NULL,
+ default_inq_cb, ctrl, NULL, NULL);
return rc;
}
diff --git a/sm/gpgsm.h b/sm/gpgsm.h
index 5e7f3f33d..26a191f87 100644
--- a/sm/gpgsm.h
+++ b/sm/gpgsm.h
@@ -218,6 +218,8 @@ gpg_error_t gpgsm_status (ctrl_t ctrl, int no, const char *text);
gpg_error_t gpgsm_status2 (ctrl_t ctrl, int no, ...);
gpg_error_t gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text,
gpg_err_code_t ec);
+gpg_error_t gpgsm_proxy_pinentry_notify (ctrl_t ctrl,
+ const unsigned char *line);
/*-- fingerprint --*/
unsigned char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo,
diff --git a/sm/server.c b/sm/server.c
index fbff003f8..e38d1764a 100644
--- a/sm/server.c
+++ b/sm/server.c
@@ -49,6 +49,8 @@ struct server_local_s {
certlist_t recplist;
certlist_t signerlist;
certlist_t default_recplist; /* As set by main() - don't release. */
+ int allow_pinentry_notify; /* Set if pinentry notifications should
+ be passed back to the client. */
};
@@ -292,6 +294,8 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
int i = *value? atoi (value) : 0;
ctrl->server_local->enable_audit_log = i;
}
+ else if (!strcmp (key, "allow-pinentry-notify"))
+ ctrl->server_local->allow_pinentry_notify = 1;
else
return gpg_error (GPG_ERR_UNKNOWN_OPTION);
@@ -299,8 +303,6 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
}
-
-
static void
reset_notify (assuan_context_t ctx)
{
@@ -1284,3 +1286,18 @@ gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text,
return gpgsm_status2 (ctrl, no, buf, NULL);
}
+
+/* Helper to notify the client about Pinentry events. Because that
+ might disturb some older clients, this is only done when enabled
+ via an option. Returns an gpg error code. */
+gpg_error_t
+gpgsm_proxy_pinentry_notify (ctrl_t ctrl, const unsigned char *line)
+{
+ if (!ctrl || !ctrl->server_local
+ || !ctrl->server_local->allow_pinentry_notify)
+ return 0;
+ return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
+}
+
+
+