Version 2.3.2 of pcsc-lite (New version of pcsc-lite: 2.3.2)
introduced a new way to ignore a smart card reader.
The patch
included in pcsc-lite is from Valtteri Vuorikoski and I will quote his
git commit message in this article.
Use case
"This is similar to the existing filtering support provided by
PCSCLITE_FILTER_IGNORE_READER_NAMES
(Remove and/or customize PC/SC reader names), but allows using the
full range of udev rules to match specific devices. For example, if you
have several Yubikeys and one is attached to a specific USB port that is
being forwarded to a virtual machine (viz. it should not be touched by
programs on the host machine), this facility allows setting a rule to
keep pcscd away from that Yubikey. Yubikeys attached to other ports keep
working normally."
udev
By default pcsc-lite uses libudev to detect readers events (plug or unplug
of a USB reader). The idea is to use a flag set by udev to tell
pcsc-lite to ignore a reader.
Example rule that targets a Yubikey attached to a specific USB port and causes
pcscd to ignore that device:
ACTION!="remove|unbind", SUBSYSTEM=="usb", ATTR{idVendor}=="1050",
ATTR{idProduct}=="0406", KERNEL=="1-2.3", ENV{PCSCLITE_IGNORE}="1"
The KERNEL
match targets a USB device attached to port 3 of a hub on
port 2 of USB bus 1, and rule sets property PCSCLITE_IGNORE
to cause
the device to be ignored.
The reader with idVendor=0x1050 and idProduct=0x0406 is
the YubiKey FIDO+CCID from Yubico.
Or if you want to ignore any reader connected to USB port 1-3:
ACTION!="remove|unbind", SUBSYSTEM=="usb", KERNEL=="1-3", ENV{PCSCLITE_IGNORE}="1"
You put the above rule is a file /etc/udev/rules.d/foobar.rules
and
voila.
Config
To know what value for KERNEL=
to use you can run udevadm monitor
and connect a USB reader. You will get something like:
$ udevadm monitor
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent
KERNEL[2022.067560] add /devices/pci0000:00/0000:00:14.0/usb1/1-3 (usb)
KERNEL[2022.069016] change /devices/pci0000:00/0000:00:14.0/usb1/1-3 (usb)
KERNEL[2022.069332] add /devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0 (usb)
KERNEL[2022.069416] bind /devices/pci0000:00/0000:00:14.0/usb1/1-3 (usb)
UDEV [2022.690370] add /devices/pci0000:00/0000:00:14.0/usb1/1-3 (usb)
UDEV [2022.695881] change /devices/pci0000:00/0000:00:14.0/usb1/1-3 (usb)
UDEV [2022.700310] add /devices/pci0000:00/0000:00:14.0/usb1/1-3/1-3:1.0 (usb)
UDEV [2022.728691] bind /devices/pci0000:00/0000:00:14.0/usb1/1-3 (usb)
You can see the "1-3" information to use in the .rules
file.
Debug
To debug your configuration and check the new field PCSCLITE_IGNORE
is
correctly set you can use udevadm monitor --property
and you get
something like:
$ udevadm monitor --property
monitor will print the received events for:
UDEV - the event which udev sends out after rule processing
KERNEL - the kernel uevent
KERNEL[2265.405075] add /devices/pci0000:00/0000:00:14.0/usb1/1-3 (usb)
ACTION=add
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-3
SUBSYSTEM=usb
DEVNAME=/dev/bus/usb/001/015
DEVTYPE=usb_device
PRODUCT=8e6/3437/100
TYPE=0/0/0
BUSNUM=001
DEVNUM=015
SEQNUM=4692
MAJOR=189
MINOR=14
[...]
UDEV [2266.066186] bind /devices/pci0000:00/0000:00:14.0/usb1/1-3 (usb)
ACTION=bind
DEVPATH=/devices/pci0000:00/0000:00:14.0/usb1/1-3
SUBSYSTEM=usb
DEVNAME=/dev/bus/usb/001/015
DEVTYPE=usb_device
DRIVER=usb
PRODUCT=8e6/3437/100
TYPE=0/0/0
BUSNUM=001
DEVNUM=015
SEQNUM=4695
USEC_INITIALIZED=2265405122
ID_BUS=usb
ID_MODEL=USB_SmartCard_Reader
ID_MODEL_ENC=USB\x20SmartCard\x20Reader
ID_MODEL_ID=3437
ID_SERIAL=Gemplus_USB_SmartCard_Reader
ID_VENDOR=Gemplus
ID_VENDOR_ENC=Gemplus
ID_VENDOR_ID=08e6
ID_REVISION=0100
ID_USB_MODEL=USB_SmartCard_Reader
ID_USB_MODEL_ENC=USB\x20SmartCard\x20Reader
ID_USB_MODEL_ID=3437
ID_USB_SERIAL=Gemplus_USB_SmartCard_Reader
ID_USB_VENDOR=Gemplus
ID_USB_VENDOR_ENC=Gemplus
ID_USB_VENDOR_ID=08e6
ID_USB_REVISION=0100
ID_USB_INTERFACES=:0b0000:
ID_VENDOR_FROM_DATABASE=Gemalto (was Gemplus)
ID_MODEL_FROM_DATABASE=GemPC Twin SmartCard Reader
ID_PATH_WITH_USB_REVISION=pci-0000:00:14.0-usbv2-0:3
ID_PATH=pci-0000:00:14.0-usb-0:3
ID_PATH_TAG=pci-0000_00_14_0-usb-0_3
ID_SMARTCARD_READER=1
ID_FOR_SEAT=usb-pci-0000_00_14_0-usb-0_3
SYSTEMD_WANTS=smartcard.target
SYSTEMD_USER_WANTS=smartcard.target
PCSCLITE_IGNORE=1
MAJOR=189
MINOR=14
TAGS=:uaccess:security-device:seat:systemd:
CURRENT_TAGS=:uaccess:security-device:seat:systemd:
In pcscd logs I get:
04337722 [140613033731776] ../src/hotplug_libudev.c:656:HPEstablishUSBNotifications() USB Device add
00000411 [140613033731776] ../src/hotplug_libudev.c:299:get_driver() Looking for a driver for VID: 0x08E6, PID: 0x3437, path: /dev/bus/usb/001/016
00000303 [140613033731776] ../src/hotplug_libudev.c:417:HPAddDevice() Device Gemalto PC Twin Reader at /dev/bus/usb/001/016 (1-3:1.0) has PCSCLITE_IGNORE set: ignored
And I do not see the PC/SC reader with pcsc_scan
command:
$ pcsc_scan -r
No reader found.
Conclusion
I am sure you will find other use cases for this new feature.
Thanks to Valtteri Vuorikoski for the patch. If you have ideas of
changes or improvements for pcsc-lite do not hesitate to submit them.