[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