Blame SOURCES/coolkey-fix-token-removal-failure.patch

a2763b
Fix insertion/removal detection
a2763b
a2763b
pcsc now errors out of the SCardGetStatusChange call with
a2763b
SCARD_E_UNKNOWN_READER if any of the passed readers aren't known.
a2763b
This includes readers that were very recently forgotton about because
a2763b
a user just disconnected them.
a2763b
a2763b
(See
a2763b
 http://anonscm.debian.org/viewvc/pcsclite/trunk/PCSC/src/winscard_clnt.c?r1=5858&r2=5881
a2763b
for the change to pcsc)
a2763b
a2763b
Unfortunately, this means SECMOD_WaitForAnyTokenEvent will fail with a
a2763b
SC_NO_EVENT error if a user removes their smartcard at the wrong time.
a2763b
a2763b
This patch changes coolkey to detect removed readers before calling
a2763b
SCardGetStatusChange, so that it can handle the removal itself.
a2763b
a2763b
diff -up coolkey-1.1.0/src/coolkey/slot.cpp.fix coolkey-1.1.0/src/coolkey/slot.cpp
a2763b
--- coolkey-1.1.0/src/coolkey/slot.cpp.fix	2013-05-22 16:23:41.728846957 -0400
a2763b
+++ coolkey-1.1.0/src/coolkey/slot.cpp	2013-05-22 17:09:59.813958927 -0400
a2763b
@@ -279,24 +279,22 @@ SlotList::updateReaderList()
a2763b
      * don't recognize.
a2763b
      */
a2763b
 
a2763b
-    /* first though, let's check to see if any previously removed readers have 
a2763b
-     * come back from the dead. If the ignored bit has been set, we do not need
a2763b
-     * it any more.
a2763b
-    */
a2763b
+    /* Iterate through all the readers to see if we need to make unavailable any
a2763b
+     * freshly removed readers. Also, see if any previously removed
a2763b
+     * readers have come back from the dead and don't need to be ignored.
a2763b
+     */
a2763b
 
a2763b
     const char *curReaderName = NULL;
a2763b
     unsigned long knownState = 0;
a2763b
     for(int ri = 0 ; ri < numReaders; ri ++)  {
a2763b
-       
a2763b
         knownState = CKYReader_GetKnownState(&readerStates[ri]);
a2763b
-        if( !(knownState & SCARD_STATE_IGNORE))  {
a2763b
-            continue;
a2763b
-        }
a2763b
- 
a2763b
+
a2763b
         curReaderName =  CKYReader_GetReaderName(&readerStates[ri]); 
a2763b
         if(readerNameExistsInList(curReaderName,&readerNames)) {
a2763b
             CKYReader_SetKnownState(&readerStates[ri], knownState & ~SCARD_STATE_IGNORE); 
a2763b
-                 
a2763b
+        } else {
a2763b
+            if (!(knownState & SCARD_STATE_UNAVAILABLE))
a2763b
+                CKYReader_SetKnownState(&readerStates[ri], knownState | SCARD_STATE_UNAVAILABLE | SCARD_STATE_CHANGED);
a2763b
         }
a2763b
     } 
a2763b
 
a2763b
@@ -1238,6 +1236,32 @@ SlotList::waitForSlotEvent(CK_FLAGS flag
a2763b
 	    throw;
a2763b
 	}
a2763b
 
a2763b
+	/* Before round-tripping to the daemon for the duration of the
a2763b
+	 * timeout, first see if we lost any readers, and pick a slot
a2763b
+	 * from that set to return
a2763b
+	 */
a2763b
+	for (i=0; i < numReaders; i++) {
a2763b
+	    unsigned long knownState = CKYReader_GetKnownState(&readerStates[i]);
a2763b
+
a2763b
+	    if ((knownState & SCARD_STATE_UNAVAILABLE) &&
a2763b
+		(knownState & SCARD_STATE_CHANGED)) {
a2763b
+		CKYReader_SetKnownState(&readerStates[i], knownState & ~SCARD_STATE_CHANGED);
a2763b
+		readerListLock.releaseLock();
a2763b
+		*slotp = slotIndexToID(i);
a2763b
+		found = TRUE;
a2763b
+		break;
a2763b
+	    }
a2763b
+	}
a2763b
+
a2763b
+	if (found) {
a2763b
+	    break;
a2763b
+	}
a2763b
+
a2763b
+	if (shuttingDown) {
a2763b
+	    readerListLock.releaseLock();
a2763b
+	    break;
a2763b
+	}
a2763b
+
a2763b
 	if (myNumReaders != numReaders) {
a2763b
 	    if (myReaderStates) {
a2763b
 		delete [] myReaderStates;