LudovicRousseau / pyscard

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

Global PCSCContext doesn't handle Smart Card Reader Manager restart #27

Closed dainnilsson closed 5 years ago

dainnilsson commented 8 years ago

Since the PCSCContext is global this gets into a broken state if the smart card service restarts. This is especially a problem on Windows, as starting with Windows 8 the service automatically shuts down when the last reader is unplugged, and re-started when one is inserted. On Linux this can be reproduced by restarting pcscd. I currently have a workaround for this where I catch the ListReadersException and then manually unset the context with PCSCContext.instance = None, which causes a new one to be created upon invoking System.readers() again.

I have reproduced this using pyscard 1.9.4 on both Python 2.7 and 3.5

Steps to reproduce:

>>> from smartcard import System
>>> System.readers()
['A connected reader']

Now, unplug and re-insert the reader on Windows (or restart pcscd on Linux)...

>>> System.readers()
Traceback ...<snip>...
smartcard.pcsc.PCSCException.ListReadersException: 'Failure to list readers: The Smart Card Resource Manager has shut down.'
>>> from smartcard.pcsc.PCSCContext import PCSCContext
>>> PCSCContext.instance = None
>>> System.readers()
['A connected reader']
LudovicRousseau commented 8 years ago

Restarting pcscd will break any PC/SC application. I am not surprised.

I am more surprised by the Windows behaviour. Can you write a simple C test program for me? Something like:

SCARDCONTEXT hContext;
DWORD dwReaders;
LONG rv;
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM, NULL, NULL, &hContext);
// unplug + replug reader
rv = SCardListReaders(hContext, NULL, NULL, &dwReaders);

According to your observations the smart card service should be restarted and SCardListReaders() should fail. Do you confirm this behaviour on Windows?

dainnilsson commented 8 years ago

I have now confirmed this does indeed happen on Windows:

//Program start, one reader connected
//Context is established, variables are printed:
rv is 0
dwReaders is 0
hContext is cd010000

//Here I unplug and replug...
//Readers are listed, variables are printed:
rv is 8010001e
dwReaders is 0
hContext is cd010000
LudovicRousseau commented 8 years ago

I would say it is a bug in Microsoft PC/SC. Unless you find a Microsoft documentation indicating that the hContext can become invalid at any time.

ghost commented 5 years ago

Old issue, but I am writing an app with this library and if you monitor the exception event in your app, you will capture the exception raised when you unplug the reader. Just recreate an instance of the class you use to monitor the reader.

LudovicRousseau commented 5 years ago

@johnhorst are you (like @dainnilsson) also using Windows?

What is the exception you get when you unplug the reader?

MarcelRobitaille commented 5 years ago

@johnhorst Could you please provide more information about your solution?

LudovicRousseau commented 5 years ago

The problem was also confirmed in https://github.com/LudovicRousseau/pyscard/issues/74

Windows is stupid to stop the PC/SC manager on reader unplug while application are still using it. I will try to think about a solution since many people are affected by this bug. Suggestions and patches are welcome.

LudovicRousseau commented 5 years ago

Fixed in https://github.com/LudovicRousseau/pyscard/commit/bf906d3bc00bc929b05a3a10aabcf349138032d6