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

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