[svn] GnuPG - r5324 - in branches/STABLE-BRANCH-2-0: agent common scd
svn author wk
cvs at cvs.gnupg.org
Mon May 3 13:10:50 CEST 2010
Author: wk
Date: 2010-05-03 13:10:49 +0200 (Mon, 03 May 2010)
New Revision: 5324
Modified:
branches/STABLE-BRANCH-2-0/agent/ChangeLog
branches/STABLE-BRANCH-2-0/agent/call-scd.c
branches/STABLE-BRANCH-2-0/agent/gpg-agent.c
branches/STABLE-BRANCH-2-0/common/ChangeLog
branches/STABLE-BRANCH-2-0/common/asshelp.c
branches/STABLE-BRANCH-2-0/scd/ChangeLog
branches/STABLE-BRANCH-2-0/scd/apdu.c
branches/STABLE-BRANCH-2-0/scd/apdu.h
branches/STABLE-BRANCH-2-0/scd/command.c
branches/STABLE-BRANCH-2-0/scd/sc-copykeys.c
Log:
Collected changes
Modified: branches/STABLE-BRANCH-2-0/agent/ChangeLog
===================================================================
--- branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-04-27 14:11:41 UTC (rev 5323)
+++ branches/STABLE-BRANCH-2-0/agent/ChangeLog 2010-05-03 11:10:49 UTC (rev 5324)
@@ -1,3 +1,12 @@
+2010-05-03 Werner Koch <wk at g10code.com>
+
+ * gpg-agent.c (check_own_socket_thread): Do not release SOCKNAME
+ too early.
+
+2010-03-17 Werner Koch <wk at g10code.com>
+
+ * call-scd.c (unlock_scd): Send a BYE under certain conditions.
+
2010-02-19 Werner Koch <wk at g10code.com>
* call-pinentry.c (start_pinentry): Remove a translation prefix.
Modified: branches/STABLE-BRANCH-2-0/common/ChangeLog
===================================================================
--- branches/STABLE-BRANCH-2-0/common/ChangeLog 2010-04-27 14:11:41 UTC (rev 5323)
+++ branches/STABLE-BRANCH-2-0/common/ChangeLog 2010-05-03 11:10:49 UTC (rev 5324)
@@ -1,3 +1,8 @@
+2010-03-17 Werner Koch <wk at g10code.com>
+
+ * asshelp.c (start_new_gpg_agent) [W32]: Use a named mutex to
+ avoid starting two agents.
+
2010-03-12 Werner Koch <wk at g10code.com>
* status.h (STATUS_ENTER): New.
Modified: branches/STABLE-BRANCH-2-0/scd/ChangeLog
===================================================================
--- branches/STABLE-BRANCH-2-0/scd/ChangeLog 2010-04-27 14:11:41 UTC (rev 5323)
+++ branches/STABLE-BRANCH-2-0/scd/ChangeLog 2010-05-03 11:10:49 UTC (rev 5324)
@@ -1,3 +1,14 @@
+2010-03-17 Werner Koch <wk at 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 at g10code.de>
From trunk 2009-09-23, 2009-10-16, 2009-11-02, 2009-11-04, 2009-11-05,
Modified: branches/STABLE-BRANCH-2-0/agent/call-scd.c
===================================================================
--- branches/STABLE-BRANCH-2-0/agent/call-scd.c 2010-04-27 14:11:41 UTC (rev 5323)
+++ branches/STABLE-BRANCH-2-0/agent/call-scd.c 2010-05-03 11:10:49 UTC (rev 5324)
@@ -176,6 +176,17 @@
static int
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)
{
log_error ("unlock_scd: invalid lock count (%d)\n",
Modified: branches/STABLE-BRANCH-2-0/agent/gpg-agent.c
===================================================================
--- branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-04-27 14:11:41 UTC (rev 5323)
+++ branches/STABLE-BRANCH-2-0/agent/gpg-agent.c 2010-05-03 11:10:49 UTC (rev 5324)
@@ -2101,7 +2101,6 @@
check_own_socket_running++;
rc = assuan_new (&ctx);
- xfree (sockname);
if (rc)
{
log_error ("can't allocate assuan context: %s\n", gpg_strerror (rc));
@@ -2137,6 +2136,7 @@
xfree (buffer);
leave:
+ xfree (sockname);
if (ctx)
assuan_release (ctx);
if (rc)
Modified: branches/STABLE-BRANCH-2-0/common/asshelp.c
===================================================================
--- branches/STABLE-BRANCH-2-0/common/asshelp.c 2010-04-27 14:11:41 UTC (rev 5323)
+++ branches/STABLE-BRANCH-2-0/common/asshelp.c 2010-05-03 11:10:49 UTC (rev 5324)
@@ -231,25 +231,68 @@
and thus there is no need for the GPG_AGENT_INFO
envvar. This is possible as we don't have a real unix
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];
+ HANDLE mutex;
+ int waitrc;
argv[0] = "--daemon";
argv[1] = "--use-standard-socket";
argv[2] = NULL;
- rc = gnupg_spawn_process_detached (agent_program, argv, NULL);
- if (rc)
- log_debug ("failed to start agent `%s': %s\n",
- agent_program, gpg_strerror (rc));
+ 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)
+ log_debug ("failed to start agent `%s': %s\n",
+ agent_program, gpg_strerror (rc));
+ else
+ {
+ /* Give the agent some time to prepare itself. */
+ gnupg_sleep (3);
+ /* Now try again to connect the agent. */
+ 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
{
- /* Give the agent some time to prepare itself. */
- gnupg_sleep (3);
- /* Now try again to connect the agent. */
- rc = assuan_socket_connect (ctx, sockname, 0, 0);
+ 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*/
{
const char *pgmname;
Modified: branches/STABLE-BRANCH-2-0/scd/apdu.c
===================================================================
--- branches/STABLE-BRANCH-2-0/scd/apdu.c 2010-04-27 14:11:41 UTC (rev 5323)
+++ branches/STABLE-BRANCH-2-0/scd/apdu.c 2010-05-03 11:10:49 UTC (rev 5324)
@@ -287,7 +287,10 @@
long (* DLSTDCALL pcsc_set_timeout) (unsigned long context,
unsigned long timeout);
+/* Flag set if PC/SC returned the no-service error. */
+static int pcsc_no_service;
+
/* Prototypes. */
static int pcsc_get_status (int slot, unsigned int *status);
static int reset_pcsc_reader (int slot);
@@ -1487,8 +1490,11 @@
log_error ("pcsc_establish_context failed: %s (0x%lx)\n",
pcsc_error_string (err), err);
reader_table[slot].used = 0;
+ if (err == 0x8010001d)
+ pcsc_no_service = 1;
return -1;
}
+ pcsc_no_service = 0;
err = pcsc_list_readers (reader_table[slot].pcsc.context,
NULL, NULL, &nreader);
@@ -2321,14 +2327,18 @@
error. If PORTSTR is NULL we default to a suitable port (for ctAPI:
the first USB reader. For PC/SC the first listed reader). */
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;
+ int slot;
+ if (r_no_service)
+ *r_no_service = 0;
+
#ifdef HAVE_LIBUSB
if (!opt.disable_ccid)
{
- int slot, i;
+ int i;
const char *s;
slot = open_ccid_reader (portstr);
@@ -2458,7 +2468,11 @@
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;
}
Modified: branches/STABLE-BRANCH-2-0/scd/apdu.h
===================================================================
--- branches/STABLE-BRANCH-2-0/scd/apdu.h 2010-04-27 14:11:41 UTC (rev 5323)
+++ branches/STABLE-BRANCH-2-0/scd/apdu.h 2010-05-03 11:10:49 UTC (rev 5324)
@@ -80,8 +80,8 @@
#define APDU_CARD_ACTIVE (4) /* Card is active. */
-/* Note , that apdu_open_reader returns no status word but -1 on error. */
-int apdu_open_reader (const char *portstr);
+/* Note, that apdu_open_reader returns no status word but -1 on error. */
+int apdu_open_reader (const char *portstr, int *r_no_service);
int apdu_open_remote_reader (const char *portstr,
const unsigned char *cookie, size_t length,
int (*readfnc) (void *opaque,
Modified: branches/STABLE-BRANCH-2-0/scd/command.c
===================================================================
--- branches/STABLE-BRANCH-2-0/scd/command.c 2010-04-27 14:11:41 UTC (rev 5323)
+++ branches/STABLE-BRANCH-2-0/scd/command.c 2010-05-03 11:10:49 UTC (rev 5324)
@@ -70,6 +70,10 @@
&& (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). */
struct slot_status_s
{
@@ -394,7 +398,15 @@
/* Try to open the reader. */
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 0;
@@ -409,6 +421,9 @@
gpg_error_t err;
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
the SERIALNO command and a reset are able to clear from that
state. */
@@ -441,7 +456,7 @@
slot = get_reader_slot ();
ctrl->reader_slot = slot;
if (slot == -1)
- err = gpg_error (GPG_ERR_CARD);
+ err = gpg_error (reader_disabled? GPG_ERR_NOT_OPERATIONAL: GPG_ERR_CARD);
else
{
/* Fixme: We should move the apdu_connect call to
@@ -495,7 +510,7 @@
time_t stamp;
/* 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) )
return gpg_error (GPG_ERR_LOCKED);
@@ -1995,7 +2010,7 @@
BUG ();
sl->next_session = ctrl->server_local->next_session;
}
- stopme = ctrl->server_local->stopme;
+ stopme = ctrl->server_local->stopme || reader_disabled;
xfree (ctrl->server_local);
ctrl->server_local = NULL;
Modified: branches/STABLE-BRANCH-2-0/scd/sc-copykeys.c
===================================================================
--- branches/STABLE-BRANCH-2-0/scd/sc-copykeys.c 2010-04-27 14:11:41 UTC (rev 5323)
+++ branches/STABLE-BRANCH-2-0/scd/sc-copykeys.c 2010-05-03 11:10:49 UTC (rev 5324)
@@ -139,7 +139,7 @@
if (argc != 1)
usage (1);
- slot = apdu_open_reader (reader_port);
+ slot = apdu_open_reader (reader_port, NULL);
if (slot == -1)
exit (1);
if (apdu_connect (slot))
More information about the Gnupg-commits
mailing list