[Gpg4win-commits] r1368 - in trunk: . patches/gnupg2-2.0.14
scm-commit@wald.intevation.org
scm-commit at wald.intevation.org
Wed Mar 17 13:48:00 CET 2010
Author: werner
Date: 2010-03-17 13:47:57 +0100 (Wed, 17 Mar 2010)
New Revision: 1368
Added:
trunk/patches/gnupg2-2.0.14/02-scd-no-service.patch
Modified:
trunk/ChangeLog
trunk/Makefile.am
Log:
scd fix
Modified: trunk/ChangeLog
===================================================================
--- trunk/ChangeLog 2010-03-17 08:34:36 UTC (rev 1367)
+++ trunk/ChangeLog 2010-03-17 12:47:57 UTC (rev 1368)
@@ -1,3 +1,7 @@
+2010-03-17 Werner Koch <wk at g10code.com>
+
+ * patches/gnupg2-2.0.14/02-scd-no-service.patch: New.
+
2010-03-16 Emanuel Schuetze <emanuel.schuetze at intevation.de>
* configure.ac: Change compendium-de date and version (3.0.0-rc1)
Modified: trunk/Makefile.am
===================================================================
--- trunk/Makefile.am 2010-03-17 08:34:36 UTC (rev 1367)
+++ trunk/Makefile.am 2010-03-17 12:47:57 UTC (rev 1368)
@@ -57,6 +57,7 @@
patches/gnupg2-2.0.12/10-inv-sgnr.patch \
patches/gnupg2-2.0.12/11-photoid-sk.patch \
patches/gnupg2-2.0.14/01-encode-s2k.patch \
+ patches/gnupg2-2.0.14/02-scd-no-service.patch \
patches/dirmngr-1.0.3/01-ldaphttp.patch \
patches/gpgol-0.9.91/01-gpgme.patch \
patches/gpa-0.9.0/01-title-prop.patch \
Added: trunk/patches/gnupg2-2.0.14/02-scd-no-service.patch
===================================================================
--- trunk/patches/gnupg2-2.0.14/02-scd-no-service.patch 2010-03-17 08:34:36 UTC (rev 1367)
+++ trunk/patches/gnupg2-2.0.14/02-scd-no-service.patch 2010-03-17 12:47:57 UTC (rev 1368)
@@ -0,0 +1,281 @@
+#! /bin/sh
+patch -p0 -f $* < $0
+exit $?
+
+
+common/
+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.
+
+agent/
+2010-03-17 Werner Koch <wk at g10code.com>
+
+ * call-scd.c (unlock_scd): Send a BYE under certain conditions.
+
+scd/
+2010-02-19 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.
+
+
+
+Index: common/asshelp.c
+===================================================================
+--- common/asshelp.c (revision 5295)
++++ common/asshelp.c (working copy)
+@@ -223,25 +230,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));
+- else
++ 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)
+ {
+- /* 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 (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
++ {
++ 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;
+
+Index: scd/apdu.h
+===================================================================
+--- scd/apdu.h (revision 5295)
++++ scd/apdu.h (working copy)
+@@ -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,
+Index: scd/command.c
+===================================================================
+--- scd/command.c (revision 5295)
++++ scd/command.c (working copy)
+@@ -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;
+
+Index: scd/apdu.c
+===================================================================
+--- scd/apdu.c (revision 5295)
++++ scd/apdu.c (working copy)
+@@ -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;
+ }
+
+
+Index: agent/call-scd.c
+===================================================================
+--- agent/call-scd.c (revision 5295)
++++ agent/call-scd.c (working copy)
+@@ -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 wants to stop. 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",
Property changes on: trunk/patches/gnupg2-2.0.14/02-scd-no-service.patch
___________________________________________________________________
Name: svn:executable
+ *
More information about the Gpg4win-commits
mailing list