diff options
author | Werner Koch <wk@gnupg.org> | 2008-02-14 20:50:10 +0100 |
---|---|---|
committer | Werner Koch <wk@gnupg.org> | 2008-02-14 20:50:10 +0100 |
commit | 30a97e770cce0d6529058052cd78990ff08b84ad (patch) | |
tree | 626d2942172a8387a1cc00a1a9bce1e5bba1ad52 /sm | |
parent | Always search missing certifcates using a running Dirmngr's cache. (diff) | |
download | gnupg2-30a97e770cce0d6529058052cd78990ff08b84ad.tar.xz gnupg2-30a97e770cce0d6529058052cd78990ff08b84ad.zip |
Poems for AllowSetForegroundWindow (W32)
Diffstat (limited to 'sm')
-rw-r--r-- | sm/ChangeLog | 13 | ||||
-rw-r--r-- | sm/call-agent.c | 104 | ||||
-rw-r--r-- | sm/gpgsm.h | 2 | ||||
-rw-r--r-- | sm/server.c | 21 |
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); +} + + + |