Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Windows smartcard service is started only once #114

Closed
antonio-fr opened this issue Jun 10, 2021 · 2 comments
Closed

Windows smartcard service is started only once #114

antonio-fr opened this issue Jun 10, 2021 · 2 comments

Comments

@antonio-fr
Copy link

Following, the BitLogiK investigation on the following issue #93, I open one issue here for clarity, to get a fresh start benefit.

I investigated, wrote a small demo minimum reproducible script, and also found a workaround. Here are all the details.

Your system information

  • Operating system used:
    Windows 10 Pro 64 bit - 10.0.19042 Build 19042
  • pyscard version:
    2.0.0
  • Python versions:
    CPython 3.6.8 64 bit and also
    CPython 3.8.8 64 bit

But I think this happens whatever the Windows version, and whatever the Python version.

Please describe your issue in as much detail as possible:

Some context : we develop a Windows application that only connects to the card "on demand", on specific and external events. This Pageant compatible app is reaching the smartcard when there's a signature request (from a WM_COPYDATA message), the application is connecting to a Yubico PIV applet and get the signature. It only connects to the card at startup, to read the public key, and then it connects at each signature request , from time to time. So it is not always connected, all day long to a card. This doesn't use resource, and the user can use her card for other things, or even removes it between signatures. Sadly, coupled with the fact that Yubico is a reader itself, this is the exact case of this issue : when a user removes her card, then at the second connection it fails.

It happens when the reader is disconnected after a first initial pyscard session. Whatever the disconnection is brutal (during data exchange), gentle (operations finished), or after a nicely deletion of the card connection object, the Windows software can't reconnect to the smartcard and throws this error.
After closing and starting again the Windows software, pyscard can reconnect to the reader. It is like pyscard can't start (or doesn't detect it is down) the card resource manager afterwards, as it does initially on the first card request.

Annoying, since some USB keys as the Yubico act as a full reader and not a single card, and when user removes it, Windows stops the card manager, the source of this issue with pyscard, and this is exacerbated with these kind of USB dongles.

Windows is stopping the smartcard manager service when one disconnects the last reader. This service is started only once by PySCard. When reconnecting to a reader/card after a smartcard service shut down, PyScard is throwing
smartcard.Exceptions.ListReadersException: Failed to list readers: The Smart Card Resource Manager has shut down. (0x-7FEFFFE2)

Pyscard CardRequest should restart the card manager, as it did at first "loading" start.

The following code makes the card service started at first time, but then fails to detect the shutdown, or the need to start it again. So the second time this is called, it throws the exception to report the smartcard manager has shut down.

cardrequest = CardRequest(timeout=2, cardType=card_atr)
cardrequest.waitforcard()

Steps for reproducing this issue:

That gives :

$ python3.8 PyscardIssue.py

Connect a YubiKey, and press RETURN

A YubiKey detected :
 - SN xxxxxxxx

Disconnect all the reader, all Yubikeys, and press RETURN

Reconnect a Yubikey, and press RETURN

Traceback (most recent call last):
  File "PyscardIssue.py", line 72, in <module>
    print_yubis()
  File "PyscardIssue.py", line 56, in print_yubis
    yubi_SN = get_yubico_serial()
  File "PyscardIssue.py", line 46, in get_yubico_serial
    cardservice = cardrequest.waitforcard()
  File "C:\Users\user\AppData\Local\Programs\Python\Python38\lib\site-packages\smartcard\CardRequest.py", line 69, in waitforcard
    return self.pcsccardrequest.waitforcard()
  File "C:\Users\user\AppData\Local\Programs\Python\Python38\lib\site-packages\smartcard\pcsc\PCSCCardRequest.py", line 125, in waitforcard
    readernames = self.getReaderNames()
  File "C:\Users\user\AppData\Local\Programs\Python\Python38\lib\site-packages\smartcard\pcsc\PCSCCardRequest.py", line 90, in getReaderNames
    raise ListReadersException(hresult)
smartcard.Exceptions.ListReadersException: Failed to list readers: The Smart Card Resource Manager has shut down.  (0x-7FEFFFE2)

If you don't have any Yubikey, that code can probably be modified to run with other cards. Note that you have to disconnect the reader, not only the card. With Yubikey, the reader and card are packed together, and this is easy to manipulate for this issue.

Workaround

During the investigation, it was quite hard to reproduce it. Sometimes the issue did not happen. So there was some kind of methods that triggers it, and some others work right. I finally found that when performing a readers listing, this turns up the smart card service, and the issue is not happening. So I finally added smartcard.System.readers() just before connecting to the card, and the issue is circumvented. This can be seen effective there. So we kind of fix the issue at the app level with this change.

@LudovicRousseau
Copy link
Owner

Nice analysis.
I will try to see if I can reproduce the problem and work on a fix.

LudovicRousseau added a commit that referenced this issue Jun 11, 2021
On Windows, when the last reader is removed the PC/SC manager is
stopped. A PC/SC call will receive SCARD_E_SERVICE_STOPPED.

The idea here is to renew the PC/SC context in getReaderNames().

Thanks to Lemon Gong for the patch
"fix #74: plugout the last device will raise an smartcard.Exceptions #93"
https://github.com/LudovicRousseau/pyscard/pull/93/files

This change should also fix:
- "Plugout an PCSC device will raise ListReadersException(hresult) on windows #74"
  #74
- "Windows smartcard service is started only once #114"
  #114
@LudovicRousseau
Copy link
Owner

Should be fixed now.
Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants