LudovicRousseau / pyscard

pyscard smartcard library for python
http://pyscard.sourceforge.net/
GNU Lesser General Public License v2.1
396 stars 113 forks source link

Failed to list readers: The Smart Card Resource Manager is not running #153

Closed mbokil closed 1 year ago

mbokil commented 1 year ago

Your system information

Please describe your issue in as much detail as possible:

Describe what you expected should happen. Removing the smart card reader and plugging it back in should pickup the readers list change Describe what did happen. The app fails to connect to a Yubikey NFC reader after the user unplugs and reconnects the NFC reader. I have seen in previous bugs this problem is related to Windows sub optimal decision to stop the smart card driver when the last NFC reader is removed. The same app works perfectly on Linux. Was hoping there is a way to add a watcher for the The Smart Card Resource Manager is not running event so I can reinitialize the app. The workaround I gave to users was to restart the app when disconnecting the NFC reader and avoid unplugging the NFC reader.

Traceback (most recent call last):
  File "C:\Users\markb\AppData\Local\Programs\Python\Python311\Lib\site-packages\smartcard\CardMonitoring.py", line 163, in run
    currentcards = self.cardrequest.waitforcardevent()
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\markb\AppData\Local\Programs\Python\Python311\Lib\site-packages\smartcard\CardRequest.py", line 72, in waitforcardevent
    return self.pcsccardrequest.waitforcardevent()
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\markb\AppData\Local\Programs\Python\Python311\Lib\site-packages\smartcard\pcsc\PCSCCardRequest.py", line 296, in waitforcardevent
    readernames = self.getReaderNames()
                  ^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\markb\AppData\Local\Programs\Python\Python311\Lib\site-packages\smartcard\pcsc\PCSCCardRequest.py", line 98, in getReaderNames
    raise ListReadersException(hresult)
smartcard.Exceptions.ListReadersException: Failed to list readers: The Smart Card Resource Manager is not running.  (0x8010001D)
Traceback (most recent call last):
  File "C:\Users\markb\AppData\Local\Programs\Python\Python311\Lib\site-packages\smartcard\ReaderMonitoring.py", line 169, in run
    currentReaders = self.readerProc()
                     ^^^^^^^^^^^^^^^^^
  File "C:\Users\markb\AppData\Local\Programs\Python\Python311\Lib\site-packages\smartcard\System.py", line 41, in readers
    return smartcard.reader.ReaderFactory.ReaderFactory.readers(groups)
           ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\markb\AppData\Local\Programs\Python\Python311\Lib\site-packages\smartcard\reader\ReaderFactory.py", line 58, in readers
    zreaders += fm(groups)
                ^^^^^^^^^^
  File "C:\Users\markb\AppData\Local\Programs\Python\Python311\Lib\site-packages\smartcard\pcsc\PCSCReader.py", line 112, in readers
    pcsc_readers = __PCSCreaders__(hcontext, groups)
                   ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "C:\Users\markb\AppData\Local\Programs\Python\Python311\Lib\site-packages\smartcard\pcsc\PCSCReader.py", line 50, in __PCSCreaders__
    raise ListReadersException(hresult)
smartcard.pcsc.PCSCExceptions.ListReadersException: Failed to list readers: The Smart Card Resource Manager is not running.  (0x8010001D)

Steps for reproducing this issue:

  1. Create an app with a ReaderObserver and CardObserver
  2. Unplug the NFC reader
  3. Plug the reader back in and exception occurs Failed to list readers: The Smart Card Resource Manager is not running
LudovicRousseau commented 1 year ago

Again this stupid Windows bug as seen in https://github.com/LudovicRousseau/pyscard/pull/75, https://github.com/LudovicRousseau/pyscard/issues/27 or https://github.com/LudovicRousseau/pyscard/issues/74

I will try to do something. Do not hesitate to propose a fix :-)

mbokil commented 1 year ago

Yeah it is irritating they changed this behavior in Windows. I read through your blog article about this issue and testing workarounds sleeping for a second and rechecking the readers list. I was thinking if the platform is Windows and the The Smart Card Resource Manager is not running exception happens possibly a polling function starts running every second until the exception clears. Not horrible but not great.

LudovicRousseau commented 1 year ago

In your case you get the error 0x8010001D SCARD_E_NO_SERVICE and not the (expected on Windows) error 0x8010001E SCARD_E_SERVICE_STOPPED. I have a special case for SCARD_E_SERVICE_STOPPED in https://github.com/LudovicRousseau/pyscard/blob/master/smartcard/pcsc/PCSCReader.py#L113

Microsoft changed Windows to return SCARD_E_NO_SERVICE instead of SCARD_E_SERVICE_STOPPED when the last reader is removed?

mbokil commented 1 year ago

I only get 0x8010001D SCARD_E_NO_SERVICE. I have the latest Windows service pack. Possibly they changed it. Can it be added as an additional exception to look for? Now that I know where the code is I will try and modify it and see if I can patch it to work on my system.

LudovicRousseau commented 1 year ago

Can you try the version from https://github.com/LudovicRousseau/pyscard-debug and confirm it fixes the issue? You can get pre-build binaries from https://muscle.apdu.fr/pyscard/artifact.zip

mbokil commented 1 year ago

Confirming your fix worked. I saw it capture the no service exception and restart the context. I made a pull request here I added more exception handling so I could see the no service exception for debugging in my project https://github.com/LudovicRousseau/pyscard/pull/154

LudovicRousseau commented 1 year ago

Problem fixed in https://github.com/LudovicRousseau/pyscard/commit/5fd9a76d06148f25ab35635af4966c63928033c9 included in PySCard 2.0.6