1
0
mirror of git://git.gnupg.org/gnupg.git synced 2024-12-22 10:19:57 +01:00

Collected changes

This commit is contained in:
Werner Koch 2010-05-03 11:10:49 +00:00
parent 1dfd0e0eda
commit 830af45ca2
10 changed files with 129 additions and 21 deletions

View File

@ -1,3 +1,12 @@
2010-05-03 Werner Koch <wk@g10code.com>
* gpg-agent.c (check_own_socket_thread): Do not release SOCKNAME
too early.
2010-03-17 Werner Koch <wk@g10code.com>
* call-scd.c (unlock_scd): Send a BYE under certain conditions.
2010-02-19 Werner Koch <wk@g10code.com> 2010-02-19 Werner Koch <wk@g10code.com>
* call-pinentry.c (start_pinentry): Remove a translation prefix. * call-pinentry.c (start_pinentry): Remove a translation prefix.

View File

@ -176,6 +176,17 @@ agent_scd_dump_state (void)
static int static int
unlock_scd (ctrl_t ctrl, int rc) unlock_scd (ctrl_t ctrl, int rc)
{ {
if (gpg_err_code (rc) == GPG_ERR_NOT_OPERATIONAL
&& gpg_err_source (rc) == GPG_ERR_SOURCE_SCD)
{
/* If the SCdaemon returned this error, it detected a major
problem, like no reader connected. To finish this we need to
stop the connection. This simulates an explicit killing of
the SCdaemon. */
assuan_transact (primary_scd_ctx, "BYE",
NULL, NULL, NULL, NULL, NULL, NULL);
}
if (ctrl->scd_local->locked != 1) if (ctrl->scd_local->locked != 1)
{ {
log_error ("unlock_scd: invalid lock count (%d)\n", log_error ("unlock_scd: invalid lock count (%d)\n",

View File

@ -2101,7 +2101,6 @@ check_own_socket_thread (void *arg)
check_own_socket_running++; check_own_socket_running++;
rc = assuan_new (&ctx); rc = assuan_new (&ctx);
xfree (sockname);
if (rc) if (rc)
{ {
log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc)); log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
@ -2137,6 +2136,7 @@ check_own_socket_thread (void *arg)
xfree (buffer); xfree (buffer);
leave: leave:
xfree (sockname);
if (ctx) if (ctx)
assuan_release (ctx); assuan_release (ctx);
if (rc) if (rc)

View File

@ -1,3 +1,8 @@
2010-03-17 Werner Koch <wk@g10code.com>
* asshelp.c (start_new_gpg_agent) [W32]: Use a named mutex to
avoid starting two agents.
2010-03-12 Werner Koch <wk@g10code.com> 2010-03-12 Werner Koch <wk@g10code.com>
* status.h (STATUS_ENTER): New. * status.h (STATUS_ENTER): New.

View File

@ -231,14 +231,38 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
and thus there is no need for the GPG_AGENT_INFO and thus there is no need for the GPG_AGENT_INFO
envvar. This is possible as we don't have a real unix envvar. This is possible as we don't have a real unix
domain socket but use a plain file and thus there is no domain socket but use a plain file and thus there is no
need to care about non-local file systems. */ need to care about non-local file systems. We use a
named mutex to interlock the spawning. There is just
one problem with that: If gpg-agent needs more than 3
seconds to come up and listen on the socket we might
still spawn another agent. However this is no serious
problem because an agent detects this and handles it.
Thus the mutex merely helps to save resources in the
most common cases. */
const char *argv[3]; const char *argv[3];
HANDLE mutex;
int waitrc;
argv[0] = "--daemon"; argv[0] = "--daemon";
argv[1] = "--use-standard-socket"; argv[1] = "--use-standard-socket";
argv[2] = NULL; argv[2] = NULL;
rc = gnupg_spawn_process_detached (agent_program, argv, NULL); mutex = CreateMutex (NULL, FALSE, "GnuPG_spawn_agent_sentinel");
if (!mutex)
{
log_error ("failed to create the spawn_agent mutex: %s\n",
w32_strerror (-1));
rc = gpg_error (GPG_ERR_GENERAL);
}
else if ((waitrc = WaitForSingleObject (mutex, 5000))
== WAIT_OBJECT_0)
{
rc = assuan_socket_connect (&ctx, sockname, 0);
if (rc)
{
/* Still not available. */
rc = gnupg_spawn_process_detached (agent_program,
argv, NULL);
if (rc) if (rc)
log_debug ("failed to start agent `%s': %s\n", log_debug ("failed to start agent `%s': %s\n",
agent_program, gpg_strerror (rc)); agent_program, gpg_strerror (rc));
@ -247,9 +271,28 @@ start_new_gpg_agent (assuan_context_t *r_ctx,
/* Give the agent some time to prepare itself. */ /* Give the agent some time to prepare itself. */
gnupg_sleep (3); gnupg_sleep (3);
/* Now try again to connect the agent. */ /* Now try again to connect the agent. */
rc = assuan_socket_connect (ctx, sockname, 0, 0); rc = assuan_socket_connect (&ctx, sockname, 0);
} }
} }
if (!ReleaseMutex (mutex))
log_error ("failed to release the spawn_agent mutex: %s\n",
w32_strerror (-1));
}
else if (waitrc == WAIT_TIMEOUT)
{
log_info ("error waiting for the spawn_agent mutex: timeout\n");
rc = gpg_error (GPG_ERR_GENERAL);
}
else
{
log_debug ("error waiting for the spawn_agent mutex: "
"(code=%d) %s\n", waitrc, w32_strerror (-1));
rc = gpg_error (GPG_ERR_GENERAL);
}
if (mutex)
CloseHandle (mutex);
}
#else /*!HAVE_W32_SYSTEM*/ #else /*!HAVE_W32_SYSTEM*/
{ {
const char *pgmname; const char *pgmname;

View File

@ -1,3 +1,14 @@
2010-03-17 Werner Koch <wk@g10code.com>
* command.c (open_card): Return GPG_ERR_NOT_OPERATIONAL if no
card services are available.
(get_reader_slot): Detect no services status.
(cmd_serialno): No reset if there are no services.
(scd_command_handler): Stop scdaemon in that case.
* apdu.c (pcsc_no_service): New.
(open_pcsc_reader_direct): Set it.
(apdu_open_reader): Add arg R_NO_SERVICE.
2010-02-11 Marcus Brinkmann <marcus@g10code.de> 2010-02-11 Marcus Brinkmann <marcus@g10code.de>
From trunk 2009-09-23, 2009-10-16, 2009-11-02, 2009-11-04, 2009-11-05, From trunk 2009-09-23, 2009-10-16, 2009-11-02, 2009-11-04, 2009-11-05,

View File

@ -287,6 +287,9 @@ long (* DLSTDCALL pcsc_transmit) (unsigned long card,
long (* DLSTDCALL pcsc_set_timeout) (unsigned long context, long (* DLSTDCALL pcsc_set_timeout) (unsigned long context,
unsigned long timeout); unsigned long timeout);
/* Flag set if PC/SC returned the no-service error. */
static int pcsc_no_service;
/* Prototypes. */ /* Prototypes. */
static int pcsc_get_status (int slot, unsigned int *status); static int pcsc_get_status (int slot, unsigned int *status);
@ -1487,8 +1490,11 @@ open_pcsc_reader_direct (const char *portstr)
log_error ("pcsc_establish_context failed: %s (0x%lx)\n", log_error ("pcsc_establish_context failed: %s (0x%lx)\n",
pcsc_error_string (err), err); pcsc_error_string (err), err);
reader_table[slot].used = 0; reader_table[slot].used = 0;
if (err == 0x8010001d)
pcsc_no_service = 1;
return -1; return -1;
} }
pcsc_no_service = 0;
err = pcsc_list_readers (reader_table[slot].pcsc.context, err = pcsc_list_readers (reader_table[slot].pcsc.context,
NULL, NULL, &nreader); NULL, NULL, &nreader);
@ -2321,14 +2327,18 @@ unlock_slot (int slot)
error. If PORTSTR is NULL we default to a suitable port (for ctAPI: error. If PORTSTR is NULL we default to a suitable port (for ctAPI:
the first USB reader. For PC/SC the first listed reader). */ the first USB reader. For PC/SC the first listed reader). */
int int
apdu_open_reader (const char *portstr) apdu_open_reader (const char *portstr, int *r_no_service)
{ {
static int pcsc_api_loaded, ct_api_loaded; static int pcsc_api_loaded, ct_api_loaded;
int slot;
if (r_no_service)
*r_no_service = 0;
#ifdef HAVE_LIBUSB #ifdef HAVE_LIBUSB
if (!opt.disable_ccid) if (!opt.disable_ccid)
{ {
int slot, i; int i;
const char *s; const char *s;
slot = open_ccid_reader (portstr); slot = open_ccid_reader (portstr);
@ -2458,7 +2468,11 @@ apdu_open_reader (const char *portstr)
pcsc_api_loaded = 1; pcsc_api_loaded = 1;
} }
return open_pcsc_reader (portstr); slot = open_pcsc_reader (portstr);
if (slot == -1 && r_no_service && pcsc_no_service)
*r_no_service = 1;
return slot;
} }

View File

@ -80,8 +80,8 @@ enum {
#define APDU_CARD_ACTIVE (4) /* Card is active. */ #define APDU_CARD_ACTIVE (4) /* Card is active. */
/* Note , that apdu_open_reader returns no status word but -1 on error. */ /* Note, that apdu_open_reader returns no status word but -1 on error. */
int apdu_open_reader (const char *portstr); int apdu_open_reader (const char *portstr, int *r_no_service);
int apdu_open_remote_reader (const char *portstr, int apdu_open_remote_reader (const char *portstr,
const unsigned char *cookie, size_t length, const unsigned char *cookie, size_t length,
int (*readfnc) (void *opaque, int (*readfnc) (void *opaque,

View File

@ -70,6 +70,10 @@
&& (c)->reader_slot == locked_session->ctrl_backlink->reader_slot) && (c)->reader_slot == locked_session->ctrl_backlink->reader_slot)
/* Flag indicating that the reader has been disabled. */
static int reader_disabled;
/* This structure is used to keep track of open readers (slots). */ /* This structure is used to keep track of open readers (slots). */
struct slot_status_s struct slot_status_s
{ {
@ -394,7 +398,15 @@ get_reader_slot (void)
/* Try to open the reader. */ /* Try to open the reader. */
if (ss->slot == -1) if (ss->slot == -1)
ss->slot = apdu_open_reader (opt.reader_port); {
int no_service_flag;
ss->slot = apdu_open_reader (opt.reader_port, &no_service_flag);
if (no_service_flag)
{
log_info ("no card services - disabling scdaemon\n");
reader_disabled = 1;
}
}
/* Return the slot_table index. */ /* Return the slot_table index. */
return 0; return 0;
@ -409,6 +421,9 @@ open_card (ctrl_t ctrl, const char *apptype)
gpg_error_t err; gpg_error_t err;
int slot; int slot;
if (reader_disabled)
return gpg_error (GPG_ERR_NOT_OPERATIONAL);
/* If we ever got a card not present error code, return that. Only /* If we ever got a card not present error code, return that. Only
the SERIALNO command and a reset are able to clear from that the SERIALNO command and a reset are able to clear from that
state. */ state. */
@ -441,7 +456,7 @@ open_card (ctrl_t ctrl, const char *apptype)
slot = get_reader_slot (); slot = get_reader_slot ();
ctrl->reader_slot = slot; ctrl->reader_slot = slot;
if (slot == -1) if (slot == -1)
err = gpg_error (GPG_ERR_CARD); err = gpg_error (reader_disabled? GPG_ERR_NOT_OPERATIONAL: GPG_ERR_CARD);
else else
{ {
/* Fixme: We should move the apdu_connect call to /* Fixme: We should move the apdu_connect call to
@ -495,7 +510,7 @@ cmd_serialno (assuan_context_t ctx, char *line)
time_t stamp; time_t stamp;
/* Clear the remove flag so that the open_card is able to reread it. */ /* Clear the remove flag so that the open_card is able to reread it. */
if (ctrl->server_local->card_removed) if (!reader_disabled && ctrl->server_local->card_removed)
{ {
if ( IS_LOCKED (ctrl) ) if ( IS_LOCKED (ctrl) )
return gpg_error (GPG_ERR_LOCKED); return gpg_error (GPG_ERR_LOCKED);
@ -1995,7 +2010,7 @@ scd_command_handler (ctrl_t ctrl, int fd)
BUG (); BUG ();
sl->next_session = ctrl->server_local->next_session; sl->next_session = ctrl->server_local->next_session;
} }
stopme = ctrl->server_local->stopme; stopme = ctrl->server_local->stopme || reader_disabled;
xfree (ctrl->server_local); xfree (ctrl->server_local);
ctrl->server_local = NULL; ctrl->server_local = NULL;

View File

@ -139,7 +139,7 @@ main (int argc, char **argv )
if (argc != 1) if (argc != 1)
usage (1); usage (1);
slot = apdu_open_reader (reader_port); slot = apdu_open_reader (reader_port, NULL);
if (slot == -1) if (slot == -1)
exit (1); exit (1);
if (apdu_connect (slot)) if (apdu_connect (slot))