Let scdaemon exit when no reader is available

NIIBE Yutaka gniibe at fsij.org
Tue Dec 4 07:56:59 CET 2012


On 2012-11-22 at 11:08 +0900, NIIBE Yutaka wrote:
> OK, I'll try another approach:
> 
>   (1) (As original proposal) Fix the function
>       update_reader_status_file not to call get_current_reader.  This
>       fix has a impact that the insertion of a card reader will be
>       detected only when user tries to access his card.
> 
>   (2) Fix not to give up in the case of reader_disabled == 1 in the
>       function scd_command_handler.  (In the first place.)
> 
>   (3) (Optionally, or in future) Fix the main routine of scdaemon to
>       enable the timer only when there is a card reader available.
> 
> With this approach, scdaemon will be more robust and it will have same
> good result as "adding exit to scdaemon" patch (mostly).


Here are two changes (#1 and #2 above).

Besides, I think that NEED_PCSC_WRAPPER can be undefined for 2.1 now.


>From 40e42372e9b5be4915a481a2072abe3c877cca68 Mon Sep 17 00:00:00 2001
From: NIIBE Yutaka <gniibe at fsij.org>
Date: Thu, 22 Nov 2012 16:04:51 +0900
Subject: [PATCH 1/2] Don't keep opening unavailable card reader.

* scd/command.c (update_reader_status_file): Don't call
get_current_reader.

--
This fix has a impact that the insertion of a card reader will not be
detected upon the insertion, but will be deferred until user tries to
access his card.
---
 scd/command.c |    5 -----
 1 file changed, 5 deletions(-)

diff --git a/scd/command.c b/scd/command.c
index 17da5b7..932db6c 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -2282,11 +2282,6 @@ update_reader_status_file (int set_card_removed_flag)
   int idx;
   unsigned int status, changed;
 
-  /* Make sure that a reader has been opened.  Like get_current_reader,
-     this part of the code assumes that there is only one reader.  */
-  if (!vreader_table[0].valid)
-    (void)get_current_reader ();
-
   /* Note, that we only try to get the status, because it does not
      make sense to wait here for a operation to complete.  If we are
      busy working with a card, delays in the status file update should
-- 
1.7.10.4

>From 2b33f18592d56a8db38d68f4184cba55f6f8dee7 Mon Sep 17 00:00:00 2001
From: NIIBE Yutaka <gniibe at fsij.org>
Date: Tue, 4 Dec 2012 14:37:56 +0900
Subject: [PATCH 2/2] Revert SCD changes of 2010-05-03.

* scd/apdu.c (pcsc_no_service): Remove.
(open_pcsc_reader_direct, open_pcsc_reader_wrapped): Remove
pcsc_no_service support.
(apdu_open_reader): Remove R_NO_SERVICE.
* scd/apdu.h (apdu_open_reader): Remove R_NO_SERVICE.
* scd/command.c (reader_disabled): Remove.
(get_current_reader): Follow the change of R_NO_SERVICE.
(open_card, cmd_serialno, scd_command_handler): Remove reader_disabled
support.
* scd/sc-copykeys.c (main): Follow the change of R_NO_SERVICE.
--
Daemon should handle all possible cases.  Even if such a difficult
case like reader_disabled, it should not exit.
---
 scd/apdu.c        |   20 +-------------------
 scd/apdu.h        |    2 +-
 scd/command.c     |   23 ++++-------------------
 scd/sc-copykeys.c |    2 +-
 4 files changed, 7 insertions(+), 40 deletions(-)

diff --git a/scd/apdu.c b/scd/apdu.c
index 43c807e..68d4e99 100644
--- a/scd/apdu.c
+++ b/scd/apdu.c
@@ -323,9 +323,6 @@ long (* DLSTDCALL pcsc_control) (unsigned long card,
                                  unsigned long recv_len,
                                  unsigned long *bytes_returned);
 
-/* 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);
@@ -1693,11 +1690,8 @@ open_pcsc_reader_direct (const char *portstr)
       log_error ("pcsc_establish_context failed: %s (0x%lx)\n",
                  pcsc_error_string (err), err);
       reader_table[slot].used = 0;
-      if (err == PCSC_E_NO_SERVICE)
-        pcsc_no_service = 1;
       return -1;
     }
-  pcsc_no_service = 0;
 
   err = pcsc_list_readers (reader_table[slot].pcsc.context,
                            NULL, NULL, &nreader);
@@ -1796,7 +1790,6 @@ open_pcsc_reader_wrapped (const char *portstr)
     {
       log_error ("can't run PC/SC access module '%s': %s\n",
                  wrapperpgm, strerror (errno));
-      pcsc_no_service = 1;
       return -1;
     }
 
@@ -1893,8 +1886,6 @@ open_pcsc_reader_wrapped (const char *portstr)
     ;
 #undef WAIT
 
-  pcsc_no_service = 1;
-
   /* Now send the open request. */
   msgbuf[0] = 0x01; /* OPEN command. */
   len = portstr? strlen (portstr):0;
@@ -1927,15 +1918,11 @@ open_pcsc_reader_wrapped (const char *portstr)
     {
       log_error ("PC/SC returned a too large ATR (len=%lx)\n",
                  (unsigned long)len);
-      pcsc_no_service = 0;
       goto command_failed;
     }
   err = PCSC_ERR_MASK ((msgbuf[5] << 24) | (msgbuf[6] << 16)
                        | (msgbuf[7] << 8 ) | msgbuf[8]);
 
-  if (err != PCSC_E_NO_SERVICE)
-    pcsc_no_service = 0;
-
   if (err)
     {
       log_error ("PC/SC OPEN failed: %s\n", pcsc_error_string (err));
@@ -2817,7 +2804,7 @@ unlock_slot (int slot)
    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, int *r_no_service)
+apdu_open_reader (const char *portstr)
 {
   static int pcsc_api_loaded, ct_api_loaded;
   int slot;
@@ -2825,9 +2812,6 @@ apdu_open_reader (const char *portstr, int *r_no_service)
   if (DBG_READER)
     log_debug ("enter: apdu_open_reader: portstr=%s\n", portstr);
 
-  if (r_no_service)
-    *r_no_service = 0;
-
 #ifdef HAVE_LIBUSB
   if (!opt.disable_ccid)
     {
@@ -2988,8 +2972,6 @@ apdu_open_reader (const char *portstr, int *r_no_service)
     }
 
   slot = open_pcsc_reader (portstr);
-  if (slot == -1 && r_no_service && pcsc_no_service)
-    *r_no_service = 1;
 
   if (DBG_READER)
     log_debug ("leave: apdu_open_reader => slot=%d [pc/sc]\n", slot);
diff --git a/scd/apdu.h b/scd/apdu.h
index 7502546..bf55346 100644
--- a/scd/apdu.h
+++ b/scd/apdu.h
@@ -84,7 +84,7 @@ enum {
 

 /* 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_reader (const char *portstr);
 int apdu_open_remote_reader (const char *portstr,
                              const unsigned char *cookie, size_t length,
                              int (*readfnc) (void *opaque,
diff --git a/scd/command.c b/scd/command.c
index 932db6c..40e61a4 100644
--- a/scd/command.c
+++ b/scd/command.c
@@ -79,10 +79,6 @@
        == locked_session->ctrl_backlink->server_local->vreader_idx))
 

-/* Flag indicating that the reader has been disabled.  */
-static int reader_disabled;
-
-
 /* This structure is used to keep track of user readers.  To
    eventually accommodate this structure for RFID cards, where more
    than one card is used per reader, we name it virtual reader.  */
@@ -444,9 +440,7 @@ get_current_reader (void)
   /* Try to open the reader. */
   if (vr->slot == -1)
     {
-      int no_service_flag;
-
-      vr->slot = apdu_open_reader (opt.reader_port, &no_service_flag);
+      vr->slot = apdu_open_reader (opt.reader_port);
 
       /* If we still don't have a slot, we have no readers.
 	 Invalidate for now until a reader is attached. */
@@ -454,12 +448,6 @@ get_current_reader (void)
 	{
 	  vr->valid = 0;
 	}
-
-      if (no_service_flag)
-        {
-          log_info ("no card services - disabling scdaemon\n");
-          reader_disabled = 1;
-        }
     }
 
   /* Return the vreader index or -1.  */
@@ -474,9 +462,6 @@ open_card (ctrl_t ctrl, const char *apptype)
   gpg_error_t err;
   int vrdr;
 
-  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. */
@@ -512,7 +497,7 @@ open_card (ctrl_t ctrl, const char *apptype)
     vrdr = get_current_reader ();
   ctrl->server_local->vreader_idx = vrdr;
   if (vrdr == -1)
-    err = gpg_error (reader_disabled? GPG_ERR_NOT_OPERATIONAL: GPG_ERR_CARD);
+    err = gpg_error (GPG_ERR_CARD);
   else
     {
       /* Fixme: We should move the apdu_connect call to
@@ -570,7 +555,7 @@ cmd_serialno (assuan_context_t ctx, char *line)
 
   /* Clear the remove flag so that the open_card is able to reread it.  */
  retry:
-  if (!reader_disabled && ctrl->server_local->card_removed)
+  if (ctrl->server_local->card_removed)
     {
       if ( IS_LOCKED (ctrl) )
         return gpg_error (GPG_ERR_LOCKED);
@@ -2122,7 +2107,7 @@ scd_command_handler (ctrl_t ctrl, int fd)
           BUG ();
       sl->next_session = ctrl->server_local->next_session;
     }
-  stopme = ctrl->server_local->stopme || reader_disabled;
+  stopme = ctrl->server_local->stopme;
   xfree (ctrl->server_local);
   ctrl->server_local = NULL;
 
diff --git a/scd/sc-copykeys.c b/scd/sc-copykeys.c
index 0056dd7..3f34d69 100644
--- a/scd/sc-copykeys.c
+++ b/scd/sc-copykeys.c
@@ -139,7 +139,7 @@ main (int argc, char **argv )
   if (argc != 1)
     usage (1);
 
-  slot = apdu_open_reader (reader_port, NULL);
+  slot = apdu_open_reader (reader_port);
   if (slot == -1)
     exit (1);
   if (apdu_connect (slot))
-- 
1.7.10.4







More information about the Gnupg-devel mailing list