mirror of
git://git.gnupg.org/gnupg.git
synced 2024-12-22 10:19:57 +01:00
Poems for AllowSetForegroundWindow (W32)
This commit is contained in:
parent
0819c1e8ca
commit
30a97e770c
@ -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
|
||||||
|
@ -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. */
|
||||||
|
@ -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);
|
||||||
|
|
||||||
|
@ -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
|
||||||
|
@ -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
|
||||||
|
}
|
||||||
|
@ -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
|
||||||
|
@ -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.
|
||||||
|
@ -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,11 +74,13 @@ 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,
|
||||||
@ -85,6 +89,16 @@ start_agent (void)
|
|||||||
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);
|
||||||
}
|
}
|
||||||
|
622
po/pt_BR.po
622
po/pt_BR.po
File diff suppressed because it is too large
Load Diff
605
po/zh_CN.po
605
po/zh_CN.po
File diff suppressed because it is too large
Load Diff
605
po/zh_TW.po
605
po/zh_TW.po
File diff suppressed because it is too large
Load Diff
13
sm/ChangeLog
13
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>
|
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.
|
||||||
|
@ -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,6 +80,7 @@ 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,
|
rc = start_new_gpg_agent (&agent_ctx,
|
||||||
GPG_ERR_SOURCE_DEFAULT,
|
GPG_ERR_SOURCE_DEFAULT,
|
||||||
opt.homedir,
|
opt.homedir,
|
||||||
@ -87,6 +90,17 @@ start_agent (ctrl_t ctrl)
|
|||||||
opt.xauthority, opt.pinentry_user_data,
|
opt.xauthority, opt.pinentry_user_data,
|
||||||
opt.verbose, DBG_ASSUAN,
|
opt.verbose, DBG_ASSUAN,
|
||||||
gpgsm_status2, ctrl);
|
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;
|
||||||
|
|
||||||
|
if (!strncmp (line, "CIPHERTEXT", 10) && (line[10]==' '||!line[10]))
|
||||||
|
{
|
||||||
assuan_begin_confidential (parm->ctx);
|
assuan_begin_confidential (parm->ctx);
|
||||||
rc = assuan_send_data (parm->ctx, parm->ciphertext, parm->ciphertextlen);
|
rc = assuan_send_data (parm->ctx, parm->ciphertext, parm->ciphertextlen);
|
||||||
assuan_end_confidential (parm->ctx);
|
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;
|
||||||
|
|
||||||
|
if (!strncmp (line, "KEYPARAM", 8) && (line[8]==' '||!line[8]))
|
||||||
|
{
|
||||||
rc = assuan_send_data (parm->ctx, parm->sexp, parm->sexplen);
|
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;
|
||||||
}
|
}
|
||||||
|
@ -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,
|
||||||
|
21
sm/server.c
21
sm/server.c
@ -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);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user