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

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