I received a bug report about "Unable to list readers inside flatpak, when pcscd runs on host." complaining that a smart card reader is not accessible from inside a flatpak sandbox.
I then discovered many other flatpak issues regarding smart cards access in https://github.com/flathub:
- Flatpak Apps and SmartCard or Security Device
- Smart Card Support
- Flatpak support for smart cards (yubikey)
- Help with Smartcards
- opensc support
Teams cannot access my PIV card to login
I never used flatpak so I start by trying to reproduce the problem.
- GNU/Linux Debian testing
- flatpak 1.12.4-1
- pcscd 1.9.5-1
The idea is to run pcsc_scan from a flatpak sandbox using the pcscd daemon on the host. This is possible since the flatpak patch "Add support for PCSC socket".
Since the daemon (pcscd) and the client library (libpcsclite.so.1) use a socket (/run/pcscd/pcscd.comm by default) to communicate we just have to export the socket in the sandbox to allow the communication.
The important part for that is:
finish-args: - --socket=pcsc
app-id: fr.apdu.pcsc_scan runtime: org.freedesktop.Platform runtime-version: '21.08' sdk: org.freedesktop.Sdk command: pcsc_scan.sh finish-args: - --socket=pcsc modules: - name: pcsc-lite config-opts: - --disable-libudev - --disable-libsystemd - --without-systemdsystemunitdir - --disable-serial - --disable-usb - --disable-documentation cleanup: - '/include' - '/bin/pcsc-spy' - '/lib/libpcscspy*' - '/lib/pkg-config' - '/share/doc' - '/share/man' post-install: - rm /app/sbin/pcscd - rmdir /app/sbin || true sources: - type: archive url: https://pcsclite.apdu.fr/files/pcsc-lite-1.9.5.tar.bz2 sha256: 9ee3f9b333537562177893559ad4f7b8d5c23ebe828eef53056c02db14049d08 - name: pcsc-tools cleanup: - '/bin/gscriptor' - '/bin/scriptor' - '/bin/ATR_analysis' - '/share/pcsc' - '/share/man' sources: - type: archive url: http://ludovic.rousseau.free.fr/softwares/pcsc-tools/pcsc-tools-1.6.0.tar.bz2 sha256: 651c8dd74bcb33db4c16935ce5d80dd1aa6eb20ba9d5c4b9631a098326ef8b9f - name: pcsc_scan.sh buildsystem: simple build-commands: - install -D pcsc_scan.sh /app/bin/pcsc_scan.sh sources: - type: file path: pcsc_scan.sh
By default pscs_scan calls ATR_analysis which is a
Perl script. I do not want to include Perl in my sandbox so I create a wrapper
to call pcsc_scan with the
-n argument to disable
the use of ATR_analysis.
#!/bin/sh pcsc_scan -n
$ flatpak-builder --user --install build-dir fr.apdu.pcsc_scan.yml [...]
$ flatpak run fr.apdu.pcsc_scan Using reader plug'n play mechanism Scanning present readers... 0: Gemalto PC Twin Reader 00 00 Fri Feb 11 17:55:17 2022 Reader 0: Gemalto PC Twin Reader 00 00 Event number: 6 Card state: Card inserted, Shared Mode, ATR: 3B A7 00 40 18 80 65 A2 08 01 01 52
It works fine. Youpi!
You need to use the same protocol version for the pcsc-lite daemon and the pcsc-lite client.
If not then pcscd will complain with something like:
Journalctl : Jan 16 16:24:42 nuc01.lan pcscd: 99999999 winscard_svc.c:383:ContextThread() Client protocol is 4:4 Jan 16 16:24:42 nuc01.lan pcscd: 00000040 winscard_svc.c:385:ContextThread() Server protocol is 4:3
The protocol version major & minor is defined in winscard_msg.h.
- 4.4 since pcsc-lite 1.8.24, Oct 2018
- 4.3 since pcsc-lite 1.8.9, Oct 2013
- 4.2 since pcsc-lite 1.6.5, Dec 2010
- 4.1 since pcsc-lite 1.6.5, Dec 2010
- 4.0 since pcsc-lite 1.6.0, May 2010
So if the server side is older than 1.8.24 (Oct 2018) and the client side is newer you have a problem.
For example Ubuntu 18.04 LTS provides pcscd 1.8.23-1. This can be problematic.
Reproducing the problem
To check that I modified the file fr.apdu.pcsc_scan.yml to build pcsc-lite 1.8.23 instead of the latest version 1.9.5.
The build is successful but the execution fails with:
$ flatpak run fr.apdu.pcsc_scan SCardEstablishContext: Service was stopped.
And in the logs on the host I see:
$ journalctl --unit=pcscd [...] févr. 11 18:55:07 debian pcscd: 00000006 winscard_svc.c:361:ContextThread() Received command: CMD_VERSION from client 8 févr. 11 18:55:07 debian pcscd: 00000004 winscard_svc.c:373:ContextThread() Client is protocol version 4:3 févr. 11 18:55:07 debian pcscd: 00000001 winscard_svc.c:382:ContextThread() Communication protocol mismatch! févr. 11 18:55:07 debian pcscd: 00000002 winscard_svc.c:384:ContextThread() Client protocol is 4:3 févr. 11 18:55:07 debian pcscd: 00000001 winscard_svc.c:386:ContextThread() Server protocol is 4:4 févr. 11 18:55:07 debian pcscd: 00000002 winscard_svc.c:396:ContextThread() CMD_VERSION rv=0x8010001E for client 8
Here the server is using version 4.4 but the client is using version 4.3.
The error code 0x8010001E is SCARD_E_SERVICE_STOPPED.
The solution is simple: use the same protocol version on both sides.
If your host is using an old pcsc-lite using the internal protocol 4.3 then include an old (between 1.8.9 and 1.8.23) pcsc-lite in your flatpak image.
I know this is not perfect. It is then not possible to provide an application in one flatpak and deploy it everywhere and anywhere.
The protocol between the daemon and the client is internal to pcsc-lite. It has not been designed to be interoperable with something else, including older versions of pcsc-lite itself.
pcsc-lite is free software. So you are free to install whatever version you want.