Poems for AllowSetForegroundWindow (W32)

This commit is contained in:
Werner Koch 2008-02-14 19:50:10 +00:00
parent 0819c1e8ca
commit 30a97e770c
39 changed files with 8817 additions and 8079 deletions

View File

@ -1,3 +1,10 @@
2008-02-14 Werner Koch <wk@g10code.com>
* command.c (agent_inq_pinentry_launched): New.
(option_handler): Add option allow-pinentry-notify.
* call-pinentry.c (getinfo_pid_cb): New.
(start_pinentry): Ask for the PID and notify the client.
2008-01-15 Marcus Brinkmann <marcus@g10code.de> 2008-01-15 Marcus Brinkmann <marcus@g10code.de>
* call-pinentry.c (start_pinentry): Start pinentry in detached * call-pinentry.c (start_pinentry): Start pinentry in detached

View File

@ -1,5 +1,5 @@
/* call-pinentry.c - fork of the pinentry to query stuff from the user /* call-pinentry.c - fork of the pinentry to query stuff from the user
* Copyright (C) 2001, 2002, 2004, 2007 Free Software Foundation, Inc. * Copyright (C) 2001, 2002, 2004, 2007, 2008 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -177,6 +177,23 @@ atfork_cb (void *opaque, int where)
} }
} }
static int
getinfo_pid_cb (void *opaque, const void *buffer, size_t length)
{
unsigned long *pid = opaque;
char pidbuf[50];
/* There is only the pid in the server's response. */
if (length >= sizeof pidbuf)
length = sizeof pidbuf -1;
if (length)
{
strncpy (pidbuf, buffer, length);
pidbuf[length] = 0;
*pid = strtoul (pidbuf, NULL, 10);
}
return 0;
}
/* Fork off the pin entry if this has not already been done. Note, /* Fork off the pin entry if this has not already been done. Note,
that this function must always be used to aquire the lock for the that this function must always be used to aquire the lock for the
@ -193,6 +210,7 @@ start_pinentry (ctrl_t ctrl)
int i; int i;
pth_event_t evt; pth_event_t evt;
const char *tmpstr; const char *tmpstr;
unsigned long pinentry_pid;
evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0)); evt = pth_event (PTH_EVENT_TIME, pth_timeout (LOCK_TIMEOUT, 0));
if (!pth_mutex_acquire (&entry_lock, 0, evt)) if (!pth_mutex_acquire (&entry_lock, 0, evt))
@ -357,9 +375,33 @@ start_pinentry (ctrl_t ctrl)
} }
} }
/* Now ask the Pinentry for its PID. If the Pinentry is new enough
it will send the pid back and we will use an inquire to notify
our client. The client may answer the inquiry either with END or
with CAN to cancel the pinentry. */
rc = assuan_transact (entry_ctx, "GETINFO pid",
getinfo_pid_cb, &pinentry_pid,
NULL, NULL, NULL, NULL);
if (rc)
{
log_info ("You may want to update to a newer pinentry\n");
rc = 0;
}
else if (!rc && (pid_t)pinentry_pid == (pid_t)(-1))
log_error ("pinentry did not return a PID\n");
else
{
rc = agent_inq_pinentry_launched (ctrl, pinentry_pid);
if (gpg_err_code (rc) == GPG_ERR_CANCELED)
return unlock_pinentry (gpg_error (GPG_ERR_CANCELED));
rc = 0;
}
return 0; return 0;
} }
/* Returns True is the pinentry is currently active. If WAITSECONDS is /* Returns True is the pinentry is currently active. If WAITSECONDS is
greater than zero the function will wait for this many seconds greater than zero the function will wait for this many seconds
before returning. */ before returning. */

View File

@ -1,6 +1,6 @@
/* command.c - gpg-agent command handler /* command.c - gpg-agent command handler
* Copyright (C) 2001, 2002, 2003, 2004, 2005, * Copyright (C) 2001, 2002, 2003, 2004, 2005,
* 2006 Free Software Foundation, Inc. * 2006, 2008 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -60,6 +60,8 @@ struct server_local_s
int stopme; /* If set to true the agent will be terminated after int stopme; /* If set to true the agent will be terminated after
the end of this session. */ the end of this session. */
#endif #endif
int allow_pinentry_notify; /* Set if pinentry notifications should
be done. */
}; };
@ -318,6 +320,22 @@ agent_write_status (ctrl_t ctrl, const char *keyword, ...)
} }
/* Helper to notify the client about a lauchned Pinentry. Because
that might disturb some older clients, this is only done when
enabled via an option. Returns an gpg error code. */
gpg_error_t
agent_inq_pinentry_launched (ctrl_t ctrl, unsigned long pid)
{
char line[100];
if (!ctrl || !ctrl->server_local
|| !ctrl->server_local->allow_pinentry_notify)
return 0;
snprintf (line, DIM(line)-1, "PINENTRY_LAUNCHED %lu", pid);
return assuan_inquire (ctrl->server_local->assuan_ctx, line, NULL, NULL, 0);
}
/* GETEVENTCOUNTER /* GETEVENTCOUNTER
@ -697,7 +715,7 @@ cmd_pkdecrypt (assuan_context_t ctx, char *line)
part. Here is an example transaction: part. Here is an example transaction:
C: GENKEY C: GENKEY
S: INQUIRE KEYPARM S: INQUIRE KEYPARAM
C: D (genkey (rsa (nbits 1024))) C: D (genkey (rsa (nbits 1024)))
C: END C: END
S: D (public-key S: D (public-key
@ -1465,6 +1483,8 @@ option_handler (assuan_context_t ctx, const char *key, const char *value)
} }
else if (!strcmp (key, "use-cache-for-signing")) else if (!strcmp (key, "use-cache-for-signing"))
ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0; ctrl->server_local->use_cache_for_signing = *value? atoi (value) : 0;
else if (!strcmp (key, "allow-pinentry-notify"))
ctrl->server_local->allow_pinentry_notify = 1;
else else
return gpg_error (GPG_ERR_UNKNOWN_OPTION); return gpg_error (GPG_ERR_UNKNOWN_OPTION);

View File

@ -1,3 +1,8 @@
2008-02-14 Werner Koch <wk@g10code.com>
* sysutils.c (gnupg_allow_set_foregound_window): New.
(WINVER) [W32]: Define.
2008-01-31 Werner Koch <wk@g10code.com> 2008-01-31 Werner Koch <wk@g10code.com>
* audit.c (audit_print_result): Make sure that the output is * audit.c (audit_print_result): Make sure that the output is

View File

@ -1,6 +1,6 @@
/* sysutils.c - system helpers /* sysutils.c - system helpers
* Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004, * Copyright (C) 1998, 1999, 2000, 2001, 2003, 2004,
* 2007 Free Software Foundation, Inc. * 2007, 2008 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -43,6 +43,7 @@
# include <sys/resource.h> # include <sys/resource.h>
#endif #endif
#ifdef HAVE_W32_SYSTEM #ifdef HAVE_W32_SYSTEM
# define WINVER 0x0500 /* Required for AllowSetForegroundWindow. */
# include <windows.h> # include <windows.h>
#endif #endif
#ifdef HAVE_PTH #ifdef HAVE_PTH
@ -471,3 +472,17 @@ gnupg_reopen_std (const char *pgmname)
#endif /* HAVE_STAT && !HAVE_W32_SYSTEM */ #endif /* HAVE_STAT && !HAVE_W32_SYSTEM */
} }
/* Hack required for Windows. */
void
gnupg_allow_set_foregound_window (pid_t pid)
{
if (!pid || pid == (pid_t)(-1))
log_info ("%s called with invalid pid %lu\n",
"gnupg_allow_set_foregound_window", (unsigned long)pid);
#ifdef HAVE_W32_SYSTEM
else if (!AllowSetForegroundWindow (pid))
log_info ("AllowSetForegroundWindow(%lu) failed: %s\n",
(unsigned long)pid, w32_strerror (-1));
#endif
}

View File

@ -47,6 +47,7 @@ int translate_sys2libc_fd (gnupg_fd_t fd, int for_write);
int translate_sys2libc_fd_int (int fd, int for_write); int translate_sys2libc_fd_int (int fd, int for_write);
FILE *gnupg_tmpfile (void); FILE *gnupg_tmpfile (void);
void gnupg_reopen_std (const char *pgmname); void gnupg_reopen_std (const char *pgmname);
void gnupg_allow_set_foregound_window (pid_t pid);
#ifdef HAVE_W32_SYSTEM #ifdef HAVE_W32_SYSTEM

View File

@ -1,3 +1,13 @@
2008-02-14 Werner Koch <wk@g10code.com>
* call-agent.c (default_inq_cb): New.
(agent_learn, agent_scd_getattr, agent_scd_pksign)
(agent_scd_pkdecrypt, agent_scd_change_pin, agent_scd_checkpin)
(agent_get_passphrase, agent_clear_passphrase): Use new callback.
(inq_writekey_parms): Fall back to the new callback for other
inquiries.
(start_agent): Tell agent that we accept pinentry notifications.
2008-02-11 Werner Koch <wk@g10code.com> 2008-02-11 Werner Koch <wk@g10code.com>
* server.c (cmd_getinfo): New. * server.c (cmd_getinfo): New.

View File

@ -1,5 +1,6 @@
/* call-agent.c - divert operations to the agent /* call-agent.c - Divert GPG operations to the agent.
* Copyright (C) 2001, 2002, 2003, 2006, 2007 Free Software Foundation, Inc. * Copyright (C) 2001, 2002, 2003, 2006, 2007,
* 2008 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -36,6 +37,7 @@
#include "options.h" #include "options.h"
#include "i18n.h" #include "i18n.h"
#include "asshelp.h" #include "asshelp.h"
#include "sysutils.h"
#include "call-agent.h" #include "call-agent.h"
#ifndef DBG_ASSUAN #ifndef DBG_ASSUAN
@ -72,19 +74,31 @@ struct genkey_parm_s
static int static int
start_agent (void) start_agent (void)
{ {
int rc;
if (agent_ctx) if (agent_ctx)
return 0; /* Fixme: We need a context for each thread or serialize return 0; /* Fixme: We need a context for each thread or serialize
the access to the agent. */ the access to the agent. */
return start_new_gpg_agent (&agent_ctx, rc = start_new_gpg_agent (&agent_ctx,
GPG_ERR_SOURCE_DEFAULT, GPG_ERR_SOURCE_DEFAULT,
opt.homedir, opt.homedir,
opt.agent_program, opt.agent_program,
opt.display, opt.ttyname, opt.ttytype, opt.display, opt.ttyname, opt.ttytype,
opt.lc_ctype, opt.lc_messages, opt.lc_ctype, opt.lc_messages,
opt.xauthority, opt.pinentry_user_data, opt.xauthority, opt.pinentry_user_data,
opt.verbose, DBG_ASSUAN, opt.verbose, DBG_ASSUAN,
NULL, NULL); NULL, NULL);
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);
}
return rc;
} }
@ -187,6 +201,29 @@ store_serialno (const char *line)
/* This is the default inquiry callback. It mainly handles the
Pinentry notifications. */
static int
default_inq_cb (void *opaque, const char *line)
{
(void)opaque;
if (!strncmp (line, "PINENTRY_LAUNCHED", 17) && (line[17]==' '||!line[17]))
{
/* There is no working server mode yet thus we use
AllowSetForegroundWindow window right here. We might want to
do this anyway in case gpg is called on the console. */
gnupg_allow_set_foregound_window ((pid_t)strtoul (line+17, NULL, 10));
/* We do not pass errors to avoid breaking other code. */
}
else
log_debug ("ignoring gpg-agent inquiry `%s'\n", line);
return 0;
}
/* Release the card info structure INFO. */ /* Release the card info structure INFO. */
void void
agent_release_card_info (struct agent_card_info_s *info) agent_release_card_info (struct agent_card_info_s *info)
@ -326,7 +363,7 @@ agent_learn (struct agent_card_info_s *info)
memset (info, 0, sizeof *info); memset (info, 0, sizeof *info);
rc = assuan_transact (agent_ctx, "LEARN --send", rc = assuan_transact (agent_ctx, "LEARN --send",
NULL, NULL, NULL, NULL, NULL, NULL, default_inq_cb, NULL,
learn_status_cb, info); learn_status_cb, info);
return rc; return rc;
@ -353,7 +390,7 @@ agent_scd_getattr (const char *name, struct agent_card_info_s *info)
if (rc) if (rc)
return rc; return rc;
rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, rc = assuan_transact (agent_ctx, line, NULL, NULL, default_inq_cb, NULL,
learn_status_cb, info); learn_status_cb, info);
return rc; return rc;
@ -401,7 +438,8 @@ agent_scd_setattr (const char *name,
if (rc) if (rc)
return rc; return rc;
rc = assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); rc = assuan_transact (agent_ctx, line, NULL, NULL,
default_inq_cb, NULL, NULL, NULL);
return rc; return rc;
} }
@ -409,12 +447,20 @@ agent_scd_setattr (const char *name,
/* Handle a KEYDATA inquiry. Note, we only send the data, /* Handle a KEYDATA inquiry. Note, we only send the data,
assuan_transact takes care of flushing and writing the end */ assuan_transact takes care of flushing and writing the end */
static assuan_error_t static int
inq_writekey_parms (void *opaque, const char *keyword) inq_writekey_parms (void *opaque, const char *line)
{ {
int rc;
struct writekey_parm_s *parm = opaque; struct writekey_parm_s *parm = opaque;
return assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen); if (!strncmp (line, "KEYDATA", 7) && (line[7]==' '||!line[7]))
{
rc = assuan_send_data (parm->ctx, parm->keydata, parm->keydatalen);
}
else
rc = default_inq_cb (opaque, line);
return rc;
} }
@ -529,7 +575,7 @@ agent_scd_genkey (struct agent_card_genkey_s *info, int keyno, int force,
memset (info, 0, sizeof *info); memset (info, 0, sizeof *info);
rc = assuan_transact (agent_ctx, line, rc = assuan_transact (agent_ctx, line,
NULL, NULL, NULL, NULL, NULL, NULL, default_inq_cb, NULL,
scd_genkey_cb, info); scd_genkey_cb, info);
return rc; return rc;
@ -589,7 +635,7 @@ agent_scd_pksign (const char *serialno, int hashalgo,
serialno); serialno);
line[DIM(line)-1] = 0; line[DIM(line)-1] = 0;
rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data, rc = assuan_transact (agent_ctx, line, membuf_data_cb, &data,
NULL, NULL, NULL, NULL); default_inq_cb, NULL, NULL, NULL);
if (rc) if (rc)
{ {
xfree (get_membuf (&data, &len)); xfree (get_membuf (&data, &len));
@ -639,7 +685,7 @@ agent_scd_pkdecrypt (const char *serialno,
line[DIM(line)-1] = 0; line[DIM(line)-1] = 0;
rc = assuan_transact (agent_ctx, line, rc = assuan_transact (agent_ctx, line,
membuf_data_cb, &data, membuf_data_cb, &data,
NULL, NULL, NULL, NULL); default_inq_cb, NULL, NULL, NULL);
if (rc) if (rc)
{ {
xfree (get_membuf (&data, &len)); xfree (get_membuf (&data, &len));
@ -679,7 +725,7 @@ agent_scd_change_pin (int chvno, const char *serialno)
snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno); snprintf (line, DIM(line)-1, "SCD PASSWD %s %d", reset, chvno);
line[DIM(line)-1] = 0; line[DIM(line)-1] = 0;
rc = assuan_transact (agent_ctx, line, NULL, NULL, rc = assuan_transact (agent_ctx, line, NULL, NULL,
NULL, NULL, NULL, NULL); default_inq_cb, NULL, NULL, NULL);
return rc; return rc;
} }
@ -701,7 +747,7 @@ agent_scd_checkpin (const char *serialno)
line[DIM(line)-1] = 0; line[DIM(line)-1] = 0;
return assuan_transact (agent_ctx, line, return assuan_transact (agent_ctx, line,
NULL, NULL, NULL, NULL,
NULL, NULL, NULL, NULL); default_inq_cb, NULL, NULL, NULL);
} }
@ -775,7 +821,8 @@ agent_get_passphrase (const char *cache_id,
init_membuf_secure (&data, 64); init_membuf_secure (&data, 64);
rc = assuan_transact (agent_ctx, line, rc = assuan_transact (agent_ctx, line,
membuf_data_cb, &data, NULL, NULL, NULL, NULL); membuf_data_cb, &data,
default_inq_cb, NULL, NULL, NULL);
if (rc) if (rc)
xfree (get_membuf (&data, NULL)); xfree (get_membuf (&data, NULL));
@ -806,5 +853,6 @@ agent_clear_passphrase (const char *cache_id)
snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id); snprintf (line, DIM(line)-1, "CLEAR_PASSPHRASE %s", cache_id);
line[DIM(line)-1] = 0; line[DIM(line)-1] = 0;
return assuan_transact (agent_ctx, line, NULL, NULL, NULL, NULL, NULL, NULL); return assuan_transact (agent_ctx, line, NULL, NULL,
default_inq_cb, NULL, NULL, NULL);
} }

621
po/be.po

File diff suppressed because it is too large Load Diff

622
po/ca.po

File diff suppressed because it is too large Load Diff

605
po/cs.po

File diff suppressed because it is too large Load Diff

619
po/da.po

File diff suppressed because it is too large Load Diff

606
po/de.po

File diff suppressed because it is too large Load Diff

619
po/el.po

File diff suppressed because it is too large Load Diff

622
po/eo.po

File diff suppressed because it is too large Load Diff

608
po/es.po

File diff suppressed because it is too large Load Diff

619
po/et.po

File diff suppressed because it is too large Load Diff

619
po/fi.po

File diff suppressed because it is too large Load Diff

605
po/fr.po

File diff suppressed because it is too large Load Diff

622
po/gl.po

File diff suppressed because it is too large Load Diff

619
po/hu.po

File diff suppressed because it is too large Load Diff

619
po/id.po

File diff suppressed because it is too large Load Diff

619
po/it.po

File diff suppressed because it is too large Load Diff

605
po/ja.po

File diff suppressed because it is too large Load Diff

605
po/nb.po

File diff suppressed because it is too large Load Diff

606
po/pl.po

File diff suppressed because it is too large Load Diff

619
po/pt.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

605
po/ro.po

File diff suppressed because it is too large Load Diff

605
po/ru.po

File diff suppressed because it is too large Load Diff

619
po/sk.po

File diff suppressed because it is too large Load Diff

606
po/sv.po

File diff suppressed because it is too large Load Diff

606
po/tr.po

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -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> 2008-02-13 Werner Koch <wk@g10code.com>
* call-dirmngr.c (gpgsm_dirmngr_lookup): Add arg CACHE_ONLY. * call-dirmngr.c (gpgsm_dirmngr_lookup): Add arg CACHE_ONLY.

View File

@ -1,6 +1,6 @@
/* call-agent.c - divert operations to the agent /* call-agent.c - Divert GPGSM operations to the agent
* Copyright (C) 2001, 2002, 2003, 2005, * Copyright (C) 2001, 2002, 2003, 2005, 2007,
* 2007 Free Software Foundation, Inc. * 2008 Free Software Foundation, Inc.
* *
* This file is part of GnuPG. * This file is part of GnuPG.
* *
@ -44,6 +44,7 @@ static assuan_context_t agent_ctx = NULL;
struct cipher_parm_s struct cipher_parm_s
{ {
ctrl_t ctrl;
assuan_context_t ctx; assuan_context_t ctx;
const unsigned char *ciphertext; const unsigned char *ciphertext;
size_t ciphertextlen; size_t ciphertextlen;
@ -51,6 +52,7 @@ struct cipher_parm_s
struct genkey_parm_s struct genkey_parm_s
{ {
ctrl_t ctrl;
assuan_context_t ctx; assuan_context_t ctx;
const unsigned char *sexp; const unsigned char *sexp;
size_t sexplen; size_t sexplen;
@ -78,15 +80,27 @@ start_agent (ctrl_t ctrl)
serialize the access to the agent (which is serialize the access to the agent (which is
suitable given that the agent is not MT. */ suitable given that the agent is not MT. */
else else
rc = start_new_gpg_agent (&agent_ctx, {
GPG_ERR_SOURCE_DEFAULT, rc = start_new_gpg_agent (&agent_ctx,
opt.homedir, GPG_ERR_SOURCE_DEFAULT,
opt.agent_program, opt.homedir,
opt.display, opt.ttyname, opt.ttytype, opt.agent_program,
opt.lc_ctype, opt.lc_messages, opt.display, opt.ttyname, opt.ttytype,
opt.xauthority, opt.pinentry_user_data, opt.lc_ctype, opt.lc_messages,
opt.verbose, DBG_ASSUAN, opt.xauthority, opt.pinentry_user_data,
gpgsm_status2, ctrl); 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) if (!ctrl->agent_seen)
{ {
ctrl->agent_seen = 1; 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 /* 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); init_membuf (&data, 1024);
rc = assuan_transact (agent_ctx, "PKSIGN", 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) if (rc)
{ {
xfree (get_membuf (&data, &len)); 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); snprintf (line, DIM(line)-1, "SCD PKSIGN %s %s", hashopt, keyid);
line[DIM(line)-1] = 0; line[DIM(line)-1] = 0;
rc = assuan_transact (agent_ctx, line, 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) if (rc)
{ {
xfree (get_membuf (&data, &len)); 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, /* Handle a CIPHERTEXT inquiry. Note, we only send the data,
assuan_transact talkes care of flushing and writing the end */ assuan_transact talkes care of flushing and writing the end */
static int static int
inq_ciphertext_cb (void *opaque, const char *keyword) inq_ciphertext_cb (void *opaque, const char *line)
{ {
struct cipher_parm_s *parm = opaque; struct cipher_parm_s *parm = opaque;
int rc; int rc;
assuan_begin_confidential (parm->ctx); if (!strncmp (line, "CIPHERTEXT", 10) && (line[10]==' '||!line[10]))
rc = assuan_send_data (parm->ctx, parm->ciphertext, parm->ciphertextlen); {
assuan_end_confidential (parm->ctx); 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; return rc;
} }
@ -323,6 +368,7 @@ gpgsm_agent_pkdecrypt (ctrl_t ctrl, const char *keygrip, const char *desc,
} }
init_membuf (&data, 1024); init_membuf (&data, 1024);
cipher_parm.ctrl = ctrl;
cipher_parm.ctx = agent_ctx; cipher_parm.ctx = agent_ctx;
cipher_parm.ciphertext = ciphertext; cipher_parm.ciphertext = ciphertext;
cipher_parm.ciphertextlen = ciphertextlen; 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, /* Handle a KEYPARMS inquiry. Note, we only send the data,
assuan_transact takes care of flushing and writing the end */ assuan_transact takes care of flushing and writing the end */
static int static int
inq_genkey_parms (void *opaque, const char *keyword) inq_genkey_parms (void *opaque, const char *line)
{ {
struct genkey_parm_s *parm = opaque; struct genkey_parm_s *parm = opaque;
int rc; 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; return rc;
} }
@ -409,6 +461,7 @@ gpgsm_agent_genkey (ctrl_t ctrl,
return rc; return rc;
init_membuf (&data, 1024); init_membuf (&data, 1024);
gk_parm.ctrl = ctrl;
gk_parm.ctx = agent_ctx; gk_parm.ctx = agent_ctx;
gk_parm.sexp = keyparms; gk_parm.sexp = keyparms;
gk_parm.sexplen = gcry_sexp_canon_len (keyparms, 0, NULL, NULL); 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); init_membuf (&data, 1024);
rc = assuan_transact (agent_ctx, line, rc = assuan_transact (agent_ctx, line,
membuf_data_cb, &data, membuf_data_cb, &data,
NULL, NULL, NULL, NULL); default_inq_cb, ctrl, NULL, NULL);
if (rc) if (rc)
{ {
xfree (get_membuf (&data, &len)); xfree (get_membuf (&data, &len));
@ -568,7 +621,8 @@ gpgsm_agent_marktrusted (ctrl_t ctrl, ksba_cert_t cert)
ksba_free (dn); ksba_free (dn);
xfree (fpr); 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; 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); snprintf (line, DIM(line)-1, "PASSWD %s", hexkeygrip);
line[DIM(line)-1] = 0; 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; 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); snprintf (line, DIM(line)-1, "GET_CONFIRMATION %s", desc);
line[DIM(line)-1] = 0; 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; return rc;
} }

View File

@ -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_status2 (ctrl_t ctrl, int no, ...);
gpg_error_t gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text, gpg_error_t gpgsm_status_with_err_code (ctrl_t ctrl, int no, const char *text,
gpg_err_code_t ec); gpg_err_code_t ec);
gpg_error_t gpgsm_proxy_pinentry_notify (ctrl_t ctrl,
const unsigned char *line);
/*-- fingerprint --*/ /*-- fingerprint --*/
unsigned char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo, unsigned char *gpgsm_get_fingerprint (ksba_cert_t cert, int algo,

View File

@ -49,6 +49,8 @@ struct server_local_s {
certlist_t recplist; certlist_t recplist;
certlist_t signerlist; certlist_t signerlist;
certlist_t default_recplist; /* As set by main() - don't release. */ 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; int i = *value? atoi (value) : 0;
ctrl->server_local->enable_audit_log = i; ctrl->server_local->enable_audit_log = i;
} }
else if (!strcmp (key, "allow-pinentry-notify"))
ctrl->server_local->allow_pinentry_notify = 1;
else else
return gpg_error (GPG_ERR_UNKNOWN_OPTION); 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 static void
reset_notify (assuan_context_t ctx) 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); 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);
}