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

Unable to list readers inside flatpak, when pcscd runs on host. #118

Closed
bnordgren opened this issue Feb 8, 2022 · 20 comments
Closed

Unable to list readers inside flatpak, when pcscd runs on host. #118

bnordgren opened this issue Feb 8, 2022 · 20 comments

Comments

@bnordgren
Copy link

Versions

  • smart card reader driver name and version: pcsc-lite-ccid v 1.5.0 (flatpak), pcsc-lite-ccid v 1.4.36 (host)
  • pcsc-lite version: 1.9.5
  • the output of the command /usr/sbin/pcscd --version
[root@mine smartcard_test]# /usr/sbin/pcscd --version
pcsc-lite version 1.9.5.
Copyright (C) 1999-2002 by David Corcoran <[email protected]>.
Copyright (C) 2001-2018 by Ludovic Rousseau <[email protected]>.
Copyright (C) 2003-2004 by Damien Sauveron <[email protected]>.
Report bugs to <[email protected]>.
Enabled features: Linux x86_64-redhat-linux-gnu libsystemd serial usb libudev usbdropdir=/usr/lib64/pcsc/drivers ipcdir=/run/pcscd filter configdir=/etc/reader.conf.d

Platform

  • Fedora Silverblue 35
  • PCSC-lite, pkcs11-tool, v. 1.9.5
  • (HP keyboard model KUS1206):
Bus 003 Device 006: ID 03f0:104a HP, Inc HP USB Smartcard CCID Keyboard
Bus 003 Device 002: ID 03f0:104a HP, Inc HP USB Smartcard CCID Keyboard
  • Smart card name: Unknown, US Government PIV

Issue

  • What do you do? Run pcscd on host using systemctl. Then run pkcs11-tool -L from the host as well as inside a simple exemplar flatpak container. (see Smart Card Support flatpak/flatpak#4723)
  • What result do you expect? I expect to see a list of the system's smart card readers.
  • What result do you get instead? I see the correct list when running the command on the host. I see "Available slots: No slots." when running from inside the container.

This seems similar to the OP's problem on #59--where no full log was ever posted--in that the daemon and the clients are running in different namespaces. The subsequent discussion apparently resulted in a situation where the daemon and the clients both ran inside the docker container, and direct access to the USB device was provided to the daemon running inside the container.

Log

Two logs are produced:

  1. host.txt where I ran the client on the host (which works, so no error is expected to be seen there).
  2. flatpak.txt where I ran the client inside the flatpak container. (this captures the problem)
@LudovicRousseau
Copy link
Owner

In the two logs hosts.txt and flatpak.txt I see not error.
In both cases you should be able to see the reader using pcsc_scan. See https://ludovicrousseau.blogspot.com/2014/03/level-1-smart-card-support-on-gnulinux.html

I see that you NEVER introduced a smart card in the HP reader.

Note that pkcs11-tool -L does not list the smart card readers, but "Display a list of available slots on the token.". So if no token/card is inserted the list is empty.

@bnordgren
Copy link
Author

I see that you NEVER introduced a smart card in the HP reader.

Don't know what to say to that. This has been my daily driver since 2018. Both readers get used regularly by apps loaded directly on the host with a package manager. There wasn't a card in the reader at the time of the test, but the client software can't even find the readers (when run in a container), much less cards in the reader. It's operation from within containers that's an issue.

Note that pkcs11-tool -L does not list the smart card readers, but "Display a list of available slots on the token.". So if no token/card is inserted the list is empty.

The slots are listed regardless of whether a card is inserted. The error is that inside the flatpak, no slots are listed, whereas on the host, they show up as they should.

On the host:

[bnordgren@mine ~]$ pkcs11-tool -L
Available slots:
Slot 0 (0x0): Hewlett Packard HP USB Smartcard CCID Keyboard [HP Smartcard ...
  (empty)
Slot 1 (0x4): Hewlett Packard HP USB Smartcard CCID Keyboard [HP Smartcard ...
  (empty)

In the flatpak:

[📦 com.example.SmartCard ~]$ pkcs11-tool -L
Available slots:
No slots.

I agree there is nothing that says "ERROR" in the logs, and always running pcscd on the host results in correct discovery of the hardware. But clients of the pcscd daemon are not doing the expected thing when the client runs inside a container (docker, flatpak, etc.) while the server is on the host.

pcsc_scan is not installed on my system or in the flatpak. My understanding is that this tries to access the hardware directly to see what is attached to the computer. I do not believe code inside the container has direct access to the reader hardware, and the thrust of this ticket is not to provide such access in order to run a 2nd pcscd inside a container. I believe the failure here is that software inside containers of various types have difficulty acting as clients to the pcscd server running on the host. If my understanding of pcsc_scan is flawed, I can try to install it to provide additional debug output.

@LudovicRousseau
Copy link
Owner

pcsc_scan is a normal PC/SC application. And it is much more simpler than OpenSC.
That would really help to have the output of pcsc_scan run from inside a flatpak container.

I will also try to play with flatpak but I don't know when.

@bnordgren
Copy link
Author

Ok. Updated the exemplar flatpak with pcsc-tools and here's the output when running inside the flatpak on my machine:

[📦 com.example.SmartCard ~]$ pcsc_scan -V
PC/SC device scanner
V 1.6.0 (c) 2001-2018, Ludovic Rousseau <[email protected]>
[📦 com.example.SmartCard ~]$ pcsc_scan 
Using reader plug'n play mechanism
Scanning present readers...
Waiting for the first reader... SCardGetStatusChange: Unknown error: 0x53204253

@LudovicRousseau
Copy link
Owner

The error code 0x53204253 is very very strange.
In fact it is not part of the possible error codes.

I will try to reproduce the issue on my side.

@bnordgren
Copy link
Author

Looks like it's this call that causes the bad/mystery return value:

https://github.com/LudovicRousseau/pcsc-tools/blob/c6e9fa746d00e08fc71c57c79e305669ff2e3106/pcsc_scan.c#L628

@LudovicRousseau
Copy link
Owner

I just wrote this
https://ludovicrousseau.blogspot.com/2022/02/accessing-smart-cards-from-inside.html

But I have no idea where the value 0x53204253 comes from.
Are you trying to mix 32-bits and 64-bits?

Can you provide a pcscd log as described in https://pcsclite.apdu.fr/#support ?

@bnordgren
Copy link
Author

"Mixing" 32 and 64 bits should only become an issue if something other than messages were traversing the socket. But I'll check:

[📦 com.example.SmartCard ~]$ file /app/bin/pcsc_scan
/app/bin/pcsc_scan: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=942e5eccdf08746464862d4492ee4d79e5bdf0d7, for GNU/Linux 3.2.0, stripped
[📦 com.example.SmartCard ~]$ exit
[bnordgren@mine src]$ file /usr/sbin/pcscd 
/usr/sbin/pcscd: ELF 64-bit LSB pie executable, x86-64, version 1 (SYSV), dynamically linked, interpreter /lib64/ld-linux-x86-64.so.2, BuildID[sha1]=0adf7b0b1d487e030a8ed4c1ca128d3316536bc9, for GNU/Linux 3.2.0, stripped

I made a new pcscd log here: pcsc_scan_log.txt

I'll try building your flatpak to see if that fixes things.

@bnordgren
Copy link
Author

No joy. Building your flatpak leads to:

[bnordgren@mine src]$ flatpak run fr.apdu.pcsc_scan
Using reader plug'n play mechanism
Scanning present readers...
Waiting for the first reader... SCardGetStatusChange: Unknown error: 0x53204253

I made a pcscd log for this too:
fr.apdu.pcsc_scan.log

The only difference I can see is that my build line included --force-clean and one other option necessary for building inside a "toolbox" (essentially a podman container). Aside from that, we should be compiling the exact same code, with the exact same config options, linking to the exact same libraries (courtesy org.freedesktop.Platform), and providing the exact same isolation (via the finish-args). The difference has to be something to do with the daemon or the daemon's environment.

⬢[bnordgren@toolbox smartcard_test]$ flatpak-builder --user --install --force-clean  --disable-rofiles-fuse build-dir fr.apdu.pcsc_scan.yml

@LudovicRousseau
Copy link
Owner

I see from your logs that you started the flatpak container "many" times. Exact?
It looks like you started a pcsc_scan on the host (and not in the container). Exact?

Do you use custom build of pcsc-lite on the host?

@bnordgren
Copy link
Author

I see from your logs that you started the flatpak container "many" times. Exact?

Not during the course of a single log file. For each trial, I started pcscd on the host, there was a bunch of output, then I started the container once, observed the error message, then hit ^C on pcscd in the terminal. The actual output from the container is pretty far down in the file. Not sure exactly what else on the system is talking to pcscd, but it includes at least the instance of Google Chrome I'm using to update this issue.

It looks like you started a pcsc_scan on the host (and not in the container). Exact?
Do you use custom build of pcsc-lite on the host?

pcsc_scan is not installed on the host. It only exists inside the two flatpaks which have been built. The host only contains software installed from Fedora 35 RPMs--no custom builds there.

[bnordgren@mine smartcard_test]$ which pcsc_scan
/usr/bin/which: no pcsc_scan in (/usr/local/bin:/usr/local/sbin:/usr/bin:/usr/sbin:/home/bnordgren/.local/bin:/home/bnordgren/bin)
[bnordgren@mine smartcard_test]$ rpm -qa | grep pcsc
pcsc-lite-libs-1.9.5-1.fc35.x86_64
pcsc-lite-ccid-1.4.36-2.fc35.x86_64
pcsc-lite-1.9.5-1.fc35.x86_64

@LudovicRousseau
Copy link
Owner

I found the problem.
Fedora patches pcsc-lite to increase the number of readers.

I extracted the patch from the package sources https://fedora.pkgs.org/35/fedora-updates-x86_64/pcsc-lite-libs-1.9.5-1.fc35.x86_64.rpm.html

diff -up ./src/PCSC/pcsclite.h.in.readers_32 ./src/PCSC/pcsclite.h.in
--- ./src/PCSC/pcsclite.h.in.readers_32	2018-08-20 16:02:17.708302410 -0700
+++ ./src/PCSC/pcsclite.h.in	2018-08-20 16:02:49.462500967 -0700
@@ -281,7 +281,7 @@ extern const SCARD_IO_REQUEST g_rgSCardT
 
 #define PCSCLITE_VERSION_NUMBER		"@VERSION@"	/**< Current version */
 /** Maximum readers context (a slot is count as a reader) */
-#define PCSCLITE_MAX_READERS_CONTEXTS			16
+#define PCSCLITE_MAX_READERS_CONTEXTS			48
 
 #define MAX_READERNAME			128
 
diff -up ./src/PCSC/pcsclite.h.readers_32 ./src/PCSC/pcsclite.h
--- ./src/PCSC/pcsclite.h.readers_32	2018-08-20 16:02:30.993385481 -0700
+++ ./src/PCSC/pcsclite.h	2018-08-20 16:03:00.061567242 -0700
@@ -281,7 +281,7 @@ extern const SCARD_IO_REQUEST g_rgSCardT
 
 #define PCSCLITE_VERSION_NUMBER		"1.9.5"	/**< Current version */
 /** Maximum readers context (a slot is count as a reader) */
-#define PCSCLITE_MAX_READERS_CONTEXTS			16
+#define PCSCLITE_MAX_READERS_CONTEXTS			48
 
 #define MAX_READERNAME			128

You need to apply the same patch on pcsc-lite inside the flatpak container.

@Erick555
Copy link

Does this patch included in server break compatibility with all clients which use pcsc without the patch? If yes then does it also break them in the opposite way (server unpatched, client patched)?

@bnordgren
Copy link
Author

You totally rock!

I updated my simple flatpak with the patch from the Fedora RPMS and behold:

[📦 com.example.SmartCard ~]$ pcsc_scan -n
Using reader plug'n play mechanism
Scanning present readers...
0: Hewlett Packard HP USB Smartcard CCID Keyboard [HP Smartcard Keyboard] (14102700000051) 00 00
1: Hewlett Packard HP USB Smartcard CCID Keyboard [HP Smartcard Keyboard] (00000741000006) 01 00
 
Sat Feb 12 09:49:04 2022
 Reader 0: Hewlett Packard HP USB Smartcard CCID Keyboard [HP Smartcard Keyboard] (14102700000051) 00 00
  Event number: 0
  Card state: Card removed, 
 Reader 1: Hewlett Packard HP USB Smartcard CCID Keyboard [HP Smartcard Keyboard] (00000741000006) 01 00
  Event number: 0
  Card state: Card removed, 

You totally solved my problem / answered my question, so I'll close this! But we did expose something that may be common in the context of containers, be they flatpaks, docker containers, or other: it's going to be common to be running code packaged differently outside a container vs within. Should we open a separate feature request to make the client/server libraries robust against a peer which has different constants defined? Perhaps the message length could be used as an indicator to detect this problem and fail gracefully, or recover what is possible to recover?

Thanks again for all your help!!

LudovicRousseau added a commit that referenced this issue Feb 12, 2022
If the option -v|--version is used then pcscd displays 2 constant
values: MAX_READERNAME & PCSCLITE_MAX_READERS_CONTEXTS

It is interesting to display PCSCLITE_MAX_READERS_CONTEXTS because
Fedora includes a patch to increase the value from 16 (default) to 48.

This change will help diagnose problems like Fedora + flatpak
#118
@LudovicRousseau
Copy link
Owner

Should we open a separate feature request to make the client/server libraries robust against a peer which has different constants defined? Perhaps the message length could be used as an indicator to detect this problem and fail gracefully, or recover what is possible to recover?

The message length is NOT exchanged between the server and the client. This is (was) not needed since both sides know the length.

If the client tries to read more data than the server sent then the client will be blocked. This would be the case with a Fedora client talking to an unpatched server.

I could improve the protocol to make it more robust. But then I would have to change the protocol version and we would have protocol mismatch errors like in flatpak/flatpak#4066 again. Maybe not the best idea.

@Erick555
Copy link

Does fedora patch make sense to be added to upstream pcsc?

@LudovicRousseau
Copy link
Owner

@bnordgren
Copy link
Author

I do like the notion of using a list instead of a static array, as mentioned in your blog post. Without a list, any decision about a maximum number of readers is final, and will eventually lead to patches like the fedora one, or like the 96 smartcard reader post you link to. A list lets everyone use what they have, whatever that is.

Protocol mismatch errors are not precisely the issue. A lack of backwards compatibility is the issue, which in this case seems pretty easy to manage. There's already a rudimentary protocol negotiation phase of the connection. What is necessary is that an outcome other than "my way or the highway" becomes possible. For instance, I can view older webpages in an HTML 5 compatible browser, and I can connect to postgresql database servers with newer or older clients. After they agree on what procotol they're going to speak, they start speaking it.

In this case, nearly everything between the current protocol and the posited future protocol is the same, but the transfer of lists of readers becomes a transfer of the list of detected readers, rather than just blindly flushing a buffer of unknown fullness down the socket and assuming that the remote side has the same size buffer as the local side.

The current state of affairs is that we have uncovered an error condition which is not handled gracefully. Providing something other than a core dump and an impossible error code would be ideal. I think the mechanism to detect and report this error condition would also make this issue moot and handle these differences as a matter of course...so there's that.

It's also possible we can file an issue with the Fedora packagers to ask that they consider a different means of supporting the high-smart card reader crowd.

@bnordgren
Copy link
Author

Entered a bugzilla for this, stating the choice and referring the packagers back to this issue and your well-written blog. Cross fingers we'll see what they say.

https://bugzilla.redhat.com/show_bug.cgi?id=2054826

@Sorunome
Copy link

Sorunome commented Nov 11, 2022

Heya, still kinda got the issue, sadly. The host is fedora37, for the flatpak the patch is applied. The error code is a different one, though:

[📦 cz.identitaobcena.eObcanka tmp]$ pcsc_scan -n                     
Using reader plug'n play mechanism
Scanning present readers...
Waiting for the first reader... SCardGetStatusChange: Unknown error: 0x00303020

EDIT: Nevermind, had the patch file accidentally in the long location so it wasn't loaded. But now it is working!

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

4 participants