<html xmlns:v="urn:schemas-microsoft-com:vml" xmlns:o="urn:schemas-microsoft-com:office:office" xmlns:w="urn:schemas-microsoft-com:office:word" xmlns:m="http://schemas.microsoft.com/office/2004/12/omml" xmlns="http://www.w3.org/TR/REC-html40">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
<meta name="Generator" content="Microsoft Word 15 (filtered medium)">
<style><!--
/* Font Definitions */
@font-face
        {font-family:"Cambria Math";
        panose-1:2 4 5 3 5 4 6 3 2 4;}
@font-face
        {font-family:Calibri;
        panose-1:2 15 5 2 2 2 4 3 2 4;}
/* Style Definitions */
p.MsoNormal, li.MsoNormal, div.MsoNormal
        {margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
a:link, span.MsoHyperlink
        {mso-style-priority:99;
        color:blue;
        text-decoration:underline;}
a:visited, span.MsoHyperlinkFollowed
        {mso-style-priority:99;
        color:purple;
        text-decoration:underline;}
p.MsoNoSpacing, li.MsoNoSpacing, div.MsoNoSpacing
        {mso-style-priority:1;
        margin:0cm;
        margin-bottom:.0001pt;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
p.msonormal0, li.msonormal0, div.msonormal0
        {mso-style-name:msonormal;
        mso-margin-top-alt:auto;
        margin-right:0cm;
        mso-margin-bottom-alt:auto;
        margin-left:0cm;
        font-size:11.0pt;
        font-family:"Calibri",sans-serif;}
span.E-MailFormatvorlage19
        {mso-style-type:personal-reply;
        font-family:"Calibri",sans-serif;
        color:#1F497D;}
.MsoChpDefault
        {mso-style-type:export-only;
        font-size:10.0pt;}
@page WordSection1
        {size:612.0pt 792.0pt;
        margin:70.85pt 70.85pt 2.0cm 70.85pt;}
div.WordSection1
        {page:WordSection1;}
--></style><!--[if gte mso 9]><xml>
<o:shapedefaults v:ext="edit" spidmax="1026" />
</xml><![endif]--><!--[if gte mso 9]><xml>
<o:shapelayout v:ext="edit">
<o:idmap v:ext="edit" data="1" />
</o:shapelayout></xml><![endif]-->
</head>
<body lang="DE" link="blue" vlink="purple">
<div class="WordSection1">
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D;mso-fareast-language:EN-US">Hi!<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D;mso-fareast-language:EN-US">Did you consider using ACLs instead of changing owner and group? However I must admit I never tried it with devices.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D;mso-fareast-language:EN-US">So my idea was to add an ACL for pcscd when the service is in use and drop that right if the service is not active.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D;mso-fareast-language:EN-US">You could even query the ACL to use it as “locked flag”.<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D;mso-fareast-language:EN-US">Kind regards,<o:p></o:p></span></p>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D;mso-fareast-language:EN-US">Ulrich Windl<o:p></o:p></span></p>
</div>
<p class="MsoNormal"><span lang="EN-US" style="color:#1F497D;mso-fareast-language:EN-US"><o:p> </o:p></span></p>
<div style="border:none;border-left:solid blue 1.5pt;padding:0cm 0cm 0cm 4.0pt">
<div>
<div style="border:none;border-top:solid #E1E1E1 1.0pt;padding:3.0pt 0cm 0cm 0cm">
<p class="MsoNormal"><b>From:</b> systemd-devel <systemd-devel-bounces@lists.freedesktop.org>
<b>On Behalf Of </b>Ran Benita<br>
<b>Sent:</b> Monday, February 17, 2025 1:02 PM<br>
<b>To:</b> systemd-devel@lists.freedesktop.org<br>
<b>Subject:</b> [EXT] [systemd-devel] Best practice for giving a system daemon access to smartcard readers<o:p></o:p></p>
</div>
</div>
<p class="MsoNormal"><o:p> </o:p></p>
<div>
<p class="MsoNormal">Hi,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I am working on improving the security of the pcscd smartcard daemon by<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">running it with a system user instead of root (the pcsclite author<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">indicated support for this). I'd like to ask for advice on a particular point.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"># Background<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">For those who have never heard of it, pcscd[0][1] is part of a daemon/<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">shared library pair implementing the standard PC/SC API for<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">communicating with smartcards, this API is used on UNIX, Windows<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">and macOS. Smartcard readers almost all use the USB CCID (0x0b) class,<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">with some custom ones using the proprietary (0xff) class. The daemon<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">connects to smartcard readers using libusb. Clients connect via unix<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">socket. The daemon is socket-activated by default.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">[0] <a href="https://pcsclite.apdu.fr/">https://pcsclite.apdu.fr</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">[1] <a href="https://github.com/LudovicRousseau/PCSC">https://github.com/LudovicRousseau/PCSC</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Currently, this daemon is a big pile of C code running as root. The PC/SC<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">architecture involves the daemon calling into driver shared libraries to<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">perform the actual communication with the smartcard readers. These days<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">only one such is used widely, CCID[2][3].<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">[2] <a href="https://ccid.apdu.fr/">https://ccid.apdu.fr</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">[3] <a href="https://github.com/LudovicRousseau/CCID">https://github.com/LudovicRousseau/CCID</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">The CCID driver enumerates a long list of USB vendor/product pairs it<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">supports, and ignores others. This list includes all common smartcard readers.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">It can be extended by end users.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">[4] /usr/lib/pcsc/drivers/<a href="http://ifd-ccid.bundle/Contents/Info.plist">ifd-ccid.bundle/Contents/Info.plist</a><o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal"># Switching to non-root user<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">The way my WIP patches implement this is:<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">- The pcsc package creates a `pcscd` system user/group.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">- The ccid package installs udev rules making `pcscd` the owner/group of<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">all CCID devices (+ the few ones using the proprietary class by vendor/<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">product).<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">My question is, is it not considered "rude" for a particular package to<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">take ownership of these devices, when other processes might want to use<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">them as well? pcsclite is pretty standard but I'm not sure.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">I noticed that the default udev rules already match smartcard reader<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">devices, set `ENV{ID_SMARTCARD_READER}=3D1` and add<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">`security-device` and `uaccess` tags.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">The pcscd daemon cannot run as a user service and take advantage of the<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">uaccess tag because it needs to handle cross-user dynamic exclusive access<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">locking (transactions) and such, so it must run as a system service.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">It seems better to me to give the device permissions to e.g. a `smartcard`<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">group instead of a `pcscd` group, and make `pcscd` user a member of that.<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">This is more neutral for other users. But how to coordinate this? It seems<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">inappeopriate for pcsclite to create such a group itself?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Another option I thought about is to only give the `pcscd` user ACL<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">permissions for the devices instead of full ownership, but I don't think udev<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal">supports this?<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Would appreciate any advice on best practices for this!<o:p></o:p></p>
</div>
<div>
<p class="MsoNormal"><o:p> </o:p></p>
</div>
<div>
<p class="MsoNormal">Ran<o:p></o:p></p>
</div>
</div>
</div>
</body>
</html>