[svn] GnuPG - r4965 - in trunk: . scd

svn author wk cvs at cvs.gnupg.org
Tue Mar 24 12:40:57 CET 2009


Author: wk
Date: 2009-03-24 12:40:57 +0100 (Tue, 24 Mar 2009)
New Revision: 4965

Modified:
   trunk/NEWS
   trunk/scd/ChangeLog
   trunk/scd/app-common.h
   trunk/scd/app.c
   trunk/scd/command.c
Log:
Better syncronization of several smartcard sessions.


Modified: trunk/scd/ChangeLog
===================================================================
--- trunk/scd/ChangeLog	2009-03-23 16:17:49 UTC (rev 4964)
+++ trunk/scd/ChangeLog	2009-03-24 11:40:57 UTC (rev 4965)
@@ -1,3 +1,14 @@
+2009-03-24  Werner Koch  <wk at g10code.com>
+
+	* command.c (struct server_local_s): Add flag
+	APP_CTX_MARKED_FOR_RELEASE.
+	(do_reset): Set the flag.
+	(open_card): Act on this flag.
+	* app-common.h (struct app_ctx_s): Add flag NO_REUSE.
+	(application_notify_card_reset): Set the flag.
+	* app.c (select_application, release_application): Take care of
+	that flag.
+
 2009-03-20  Werner Koch  <wk at g10code.com>
 
 	* app-nks.c (keygripstr_from_pk_file): Fix for TCOS 3 cards.

Modified: trunk/NEWS
===================================================================
--- trunk/NEWS	2009-03-23 16:17:49 UTC (rev 4964)
+++ trunk/NEWS	2009-03-24 11:40:57 UTC (rev 4965)
@@ -13,7 +13,9 @@
  * Changed order of the confirmation questions for root certificates
    and stores negative answers in trustlist.txt.
 
+ * Better synchronization of several smartcard sessions.
 
+
 Noteworthy changes in version 2.0.11 (2009-03-03)
 -------------------------------------------------
 

Modified: trunk/scd/app-common.h
===================================================================
--- trunk/scd/app-common.h	2009-03-23 16:17:49 UTC (rev 4964)
+++ trunk/scd/app-common.h	2009-03-24 11:40:57 UTC (rev 4965)
@@ -38,16 +38,20 @@
 struct app_local_s;  /* Defined by all app-*.c.  */
 
 struct app_ctx_s {
-  unsigned int ref_count;  /* Number of connections currently using
-                              this application context.  If this is
-                              not 0 the application has been
-                              initialized and the function pointers
-                              may be used.  Note that for unsupported
-                              operations the particular function
-                              pointer is set to NULL */
+  /* Number of connections currently using this application context.
+     If this is not 0 the application has been initialized and the
+     function pointers may be used.  Note that for unsupported
+     operations the particular function pointer is set to NULL */
+  unsigned int ref_count;
 
-  int slot;         /* Used reader. */
+  /* Flag indicating that a reset has been done for that application
+     and that this context is merely lingering and just should not be
+     reused.  */
+  int no_reuse;            
 
+  /* Used reader slot. */
+  int slot;     
+
   /* If this is used by GnuPG 1.4 we need to know the assuan context
      in case we need to divert the operation to an already running
      agent.  This if ASSUAN_CTX is not NULL we take this as indication

Modified: trunk/scd/app.c
===================================================================
--- trunk/scd/app.c	2009-03-23 16:17:49 UTC (rev 4964)
+++ trunk/scd/app.c	2009-03-24 11:40:57 UTC (rev 4965)
@@ -173,6 +173,10 @@
   /* FIXME: We are ignoring any error value here.  */
   lock_reader (slot); 
 
+  /* Mark application as non-reusable.  */
+  if (lock_table[slot].app)
+    lock_table[slot].app->no_reuse = 1;
+
   /* Deallocate a saved application for that slot, so that we won't
      try to reuse it.  If there is no saved application, set a flag so
      that we won't save the current state. */
@@ -241,6 +245,16 @@
         return gpg_error (GPG_ERR_CONFLICT);
       }
 
+  /* Don't use a non-reusable marked application.  */
+  if (app && app->no_reuse)
+    {
+      unlock_reader (slot);
+      log_info ("lingering application `%s' in use by reader %d"
+                " - can't switch\n",
+                app->apptype? app->apptype:"?", slot);
+      return gpg_error (GPG_ERR_CONFLICT);
+    }
+
   /* If we don't have an app, check whether we have a saved
      application for that slot.  This is useful so that a card does
      not get reset even if only one session is using the card - this
@@ -278,7 +292,7 @@
       unlock_reader (slot);
       return 0; /* Okay: We share that one. */
     }
-
+  
   /* Need to allocate a new one.  */
   app = xtrycalloc (1, sizeof *app);
   if (!app)
@@ -458,7 +472,15 @@
 
   if (lock_table[slot].last_app)
     deallocate_app (lock_table[slot].last_app);
-  lock_table[slot].last_app = lock_table[slot].app;
+  if (app->no_reuse)
+    {
+      /* If we shall not re-use the application we can't save it for
+         later use. */
+      deallocate_app (app);
+      lock_table[slot].last_app = NULL;
+    }
+  else
+    lock_table[slot].last_app = lock_table[slot].app;
   lock_table[slot].app = NULL;
   unlock_reader (slot);
 }

Modified: trunk/scd/command.c
===================================================================
--- trunk/scd/command.c	2009-03-23 16:17:49 UTC (rev 4964)
+++ trunk/scd/command.c	2009-03-24 11:40:57 UTC (rev 4965)
@@ -112,6 +112,10 @@
      continue operation. */
   int card_removed;        
 
+  /* Flag indicating that the application context needs to be released
+     at the next opportunity.  */
+  int app_ctx_marked_for_release;
+
   /* A disconnect command has been sent.  */
   int disconnect_allowed;
 
@@ -165,7 +169,7 @@
 
 
 /* Update the CARD_REMOVED element of all sessions using the reader
-   given by SLOT to VALUE  */
+   given by SLOT to VALUE.  */
 static void
 update_card_removed (int slot, int value)
 {
@@ -274,11 +278,24 @@
   if (!(slot == -1 || (slot >= 0 && slot < DIM(slot_table))))
     BUG ();
 
-  /* If there is an active application, release it. */
+  /* If there is an active application, release it.  Tell all other
+     sessions using the same application to release the
+     application.  */
   if (ctrl->app_ctx)
     {
       release_application (ctrl->app_ctx);
       ctrl->app_ctx = NULL;
+      if (send_reset)
+        {
+          struct server_local_s *sl;
+          
+          for (sl=session_list; sl; sl = sl->next_session)
+            if (sl->ctrl_backlink
+                && sl->ctrl_backlink->reader_slot == slot)
+              {
+                sl->app_ctx_marked_for_release = 1;
+              }
+        }
     }
 
   /* If we want a real reset for the card, send the reset APDU and
@@ -397,14 +414,23 @@
   if ( IS_LOCKED (ctrl) )
     return gpg_error (GPG_ERR_LOCKED);
 
-  if (ctrl->app_ctx)
+  /* If the application has been marked for release do it now.  We
+     can't do it immediately in do_reset because the application may
+     still be in use.  */
+  if (ctrl->server_local->app_ctx_marked_for_release)
     {
-      /* Already initialized for one specific application.  Need to
-         check that the client didn't requested a specific application
-         different from the one in use. */
-      return check_application_conflict (ctrl, apptype);
+      ctrl->server_local->app_ctx_marked_for_release = 0;
+      release_application (ctrl->app_ctx);
+      ctrl->app_ctx = NULL;
     }
 
+  /* If we are already initialized for one specific application we
+     need to check that the client didn't requested a specific
+     application different from the one in use before we continue. */
+  if (ctrl->app_ctx)
+    return check_application_conflict (ctrl, apptype);
+
+  /* Setup the slot and select the application.  */
   if (ctrl->reader_slot != -1)
     slot = ctrl->reader_slot;
   else




More information about the Gnupg-commits mailing list