diff options
Diffstat (limited to '')
-rw-r--r-- | sm/call-agent.c | 104 |
1 files changed, 80 insertions, 24 deletions
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; } |