1 { config, lib, pkgs, ... }:
3 cfg = config.services.pcscd;
4 cfgFile = pkgs.writeText "reader.conf" config.services.pcscd.readerConfig;
6 package = if config.security.polkit.enable
7 then pkgs.pcscliteWithPolkit
10 pluginEnv = pkgs.buildEnv {
11 name = "pcscd-plugins";
12 paths = map (p: "${p}/pcsc/drivers") config.services.pcscd.plugins;
17 options.services.pcscd = {
18 enable = lib.mkEnableOption "PCSC-Lite daemon, to access smart cards using SCard API (PC/SC)";
20 plugins = lib.mkOption {
21 type = lib.types.listOf lib.types.package;
22 defaultText = lib.literalExpression "[ pkgs.ccid ]";
23 example = lib.literalExpression "[ pkgs.pcsc-cyberjack ]";
24 description = "Plugin packages to be used for PCSC-Lite.";
27 readerConfig = lib.mkOption {
28 type = lib.types.lines;
31 FRIENDLYNAME "Some serial reader"
33 LIBPATH /path/to/serial_reader.so
37 Configuration for devices that aren't hotpluggable.
39 See {manpage}`reader.conf(5)` for valid options.
43 extraArgs = lib.mkOption {
44 type = lib.types.listOf lib.types.str;
46 description = "Extra command line arguments to be passed to the PCSC daemon.";
50 config = lib.mkIf config.services.pcscd.enable {
51 environment.etc."reader.conf".source = cfgFile;
53 environment.systemPackages = [ package ];
54 systemd.packages = [ package ];
56 services.pcscd.plugins = [ pkgs.ccid ];
58 systemd.sockets.pcscd.wantedBy = [ "sockets.target" ];
60 systemd.services.pcscd = {
61 environment.PCSCLITE_HP_DROPDIR = pluginEnv;
63 # If the cfgFile is empty and not specified (in which case the default
64 # /etc/reader.conf is assumed), pcscd will happily start going through the
65 # entire confdir (/etc in our case) looking for a config file and try to
66 # parse everything it finds. Doesn't take a lot of imagination to see how
67 # well that works. It really shouldn't do that to begin with, but to work
68 # around it, we force the path to the cfgFile.
70 # https://github.com/NixOS/nixpkgs/issues/121088
71 serviceConfig.ExecStart = [ "" "${lib.getExe package} -f -x -c ${cfgFile} ${lib.escapeShellArgs cfg.extraArgs}" ];