LudovicRousseau / pyscard

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

Order of readers in list change arbitrarily #157

Closed spaniardmaximus closed 1 year ago

spaniardmaximus commented 1 year ago

Can't start this ticket without thanking you immensely for putting this module together. The ability to work with python and higher level APIs has opened up a world of possibilities for me, so THANK YOU!!!.

Your system information

Please describe your issue in as much detail as possible:

As I add extra card readers (ACR1252U-DOT and ACM1252U-Z2) into my setup through a USB hub, their order seem to change upon using:

hresult, readers = smartcard.scard.SCardListReaders( hcontext, [] )
     print(readers)

Resulting in:

['ACS ACR1252 CL Reader [ACR1252 Reader PICC] 00 00', 'ACS ACR1252 CL Reader [ACR1252 Reader PICC] 01 00', 'ACS ACR1252 CL Reader [ACR1252 Reader PICC] 02 00']

I actually use the readers as in emulation mode.

I don't know how to target a reader beyond their order in the array. Either after adding an extra reader (same model) or unplugging and plugging back in into the USB hub (or the USB ports of the Rasp Pi), the order could be different.

I need for that order to be constant or an alternative to target the reader.

Steps for reproducing this issue:

The easiest that I can think off.

  1. Plug a ACM1252U-Z2 reader in one USB port.
  2. Enter emulation mode; establish context, list readers, connect (this is where I use the array index), send APDU command with SCardControl, disconnect and release context.
  3. Plug another ACM1252U-Z2 reader in another USB port.
  4. Enter emulation mode as above.
  5. Plug a ACR1252U-DOT reader in another USB port.

That last one seems to become the first (index zero) in the array. We tried other combinations of more ACR1252U-DOT and ACM1252U-Z2 combined and I can't see a pattern other than the former moving first in the array.

LudovicRousseau commented 1 year ago

The readers are listed in the order they are connected. The order will not change (unless the pcscd process is restarted) or you unplug/replug a reader.

If you reader is at index 0 then it will stay at index 0 even after other .SCardListReaders() calls.

See https://blog.apdu.fr/posts/2010/05/what-is-in-pcsc-reader-name/

spaniardmaximus commented 1 year ago

These things seem to have a mind of their own :). I don't seem to find a pattern or reliable order to target. I'm restarting the pcsc service, unplugging and plugging back in in different order and yet, when I think that I'm targeting one reader, it is actually another one.

LudovicRousseau commented 1 year ago

The solution is to use readers with a USB serial number. The serial number will be included in the PC/SC name.

spaniardmaximus commented 1 year ago

Forgive my ignorance, if I get that serial number, how do I pass it to say SCardConnect, for example?

LudovicRousseau commented 1 year ago

See https://blog.apdu.fr/posts/2010/05/what-is-in-pcsc-reader-name/

spaniardmaximus commented 1 year ago

Thanks for the link. I'm afraid that I can't make much out of it. hal-device doesn't seem to be readily available for Raspberry Pi OS?

When trying to get the serial number through lsusb, I get a big fat 0 :) So I can't tell the readers apart. Every time that I plug a new reader/emulator in the usb hub, the order changes. It is driving me insane :)

LudovicRousseau commented 1 year ago

Can you reproduce the problem using a real PC + Debian instead of a Raspberry Pi?

spaniardmaximus commented 1 year ago

The easiest and quickest will be trying on a VM. I'll give it a go...

LudovicRousseau commented 1 year ago

A virtual machine may add strange behaviour on the USB bus. But that is a good idea.

spaniardmaximus commented 1 year ago

So I have the latest stable Debian in a VM and installed all the dependencies as I did for the Raspberry Pi, on its day, as a VM first then it the physical one.

In the VM, I had to mount the USB readers one at the time from the host but it looks like the order of adding the readers was kept. As I was adding them in turn, I kept running my script to target all the previous ones and the new one.

image

spaniardmaximus commented 1 year ago

I still need to check if the order is bound somehow to the physical USB port in the hub attached to the Pi by doing a little switching around.

LudovicRousseau commented 1 year ago

One hypothesis is that on the Raspberry Pi adding more reader generates a reboot of the hub or something like that that reorders the readers. You can list the USB devices using the lsusb command before and after connecting the readers.

spaniardmaximus commented 1 year ago

mmmhhh, so I went step by step checking a reader (emulator as I call them). By the second emulator, the array was out of kilter. They take different device numbers?. The reader/emulator that I was targeting at [0] index, changed to [1].

========= No emulators ===========
Bus 001 Device 013: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 012: ID 1a40:0201 Terminus Technology Inc. FE 2.1 7-port Hub
Bus 001 Device 005: ID 413c:2113 Dell Computer Corp. KB216 Wired Keyboard
Bus 001 Device 004: ID 413c:301a Dell Computer Corp. Dell MS116 Optical Mouse
Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
========= Emulator 1 ===========
Bus 001 Device 014: ID 072f:223e Advanced Card Systems, Ltd ACR1252 Reader ===== Reader array index: 0
Bus 001 Device 013: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 012: ID 1a40:0201 Terminus Technology Inc. FE 2.1 7-port Hub
Bus 001 Device 005: ID 413c:2113 Dell Computer Corp. KB216 Wired Keyboard
Bus 001 Device 004: ID 413c:301a Dell Computer Corp. Dell MS116 Optical Mouse
Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
========= Emulator 2 ===========
Bus 001 Device 018: ID 072f:223e Advanced Card Systems, Ltd ACR1252 Reader
Bus 001 Device 017: ID 072f:223e Advanced Card Systems, Ltd ACR1252 Reader
Bus 001 Device 016: ID 1a40:0101 Terminus Technology Inc. Hub
Bus 001 Device 015: ID 1a40:0201 Terminus Technology Inc. FE 2.1 7-port Hub
Bus 001 Device 005: ID 413c:2113 Dell Computer Corp. KB216 Wired Keyboard
Bus 001 Device 004: ID 413c:301a Dell Computer Corp. Dell MS116 Optical Mouse
Bus 001 Device 003: ID 0424:ec00 Microchip Technology, Inc. (formerly SMSC) SMSC9512/9514 Fast Ethernet Adapter
Bus 001 Device 002: ID 0424:9514 Microchip Technology, Inc. (formerly SMSC) SMC9514 Hub
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
spaniardmaximus commented 1 year ago

Unless that I can find a property that follows them around, e.g. serial number, I won't be able to keep track of them when adding new readers. Even if I find that property, the function SCardConnect only seems to take an integer (array index)???

LudovicRousseau commented 1 year ago

If you look at the lsusb output you see that the USB hub moved from device 12:

Bus 001 Device 012: ID 1a40:0201 Terminus Technology Inc. FE 2.1 7-port Hub

to device 15

Bus 001 Device 015: ID 1a40:0201 Terminus Technology Inc. FE 2.1 7-port Hub

Of course all the devices connected on the hub are also re-enumerated. And the order is then random.

It is a USB issue (hardware or software). PySCard cannot help.

See also https://blog.apdu.fr/posts/2014/04/usb-issues-with-raspberry-pi/