nixos/tcsd: several improvements and fixes

- Actually run tcsd as tss/tss
- Install a udev rule to set /dev/tpm* permissions
- Remove systemd-udev-settle dependency, use dev-tpm0.device instead
- Use systemd-tmpfiles to set up the state directory
- Add documentation URI to tcsd.service

This module cannot be easily tested with a NixOS test due to the TPM
dependency. Technically, one could be emulated using swtpm[1], but this
is not packaged in Nixpkgs. If you computer has a real TPM you can do a
passthrough in Qemu, but this requires running the VM as root and of
course it's not determinstic:

$ nix build -f nixos vm --arg configuration '
{
virtualisation.qemu.options = [
"-tpmdev passthrough,id=tpm0,path=/dev/tpm0,cancel-path=/sys/class/tpm/tpm0/cancel"
"-device tpm-tis,tpmdev=tpm0"
];
users.users.root.hashedPassword = "";
services.tcsd.enable = true;
}'

After starting the VM, log in as root, you can check the service has
started with `systemctl status tcsd`.

[1]: https://github.com/stefanberger/swtpm

rnhmjoj 53831270 0c98cef6

Changed files
+22 -13
nixos
modules
services
hardware
+22 -13
nixos/modules/services/hardware/tcsd.nix
···
environment.systemPackages = [ pkgs.trousers ];
-
# system.activationScripts.tcsd =
-
# ''
-
# chown ${cfg.user}:${cfg.group} ${tcsdConf}
-
# '';
+
services.udev.extraRules = ''
+
# Give tcsd ownership of all TPM devices
+
KERNEL=="tpm[0-9]*", MODE="0660", OWNER="${cfg.user}", GROUP="${cfg.group}"
+
# Tag TPM devices to create a .device unit for tcsd to depend on
+
ACTION=="add", KERNEL=="tpm[0-9]*", TAG+="systemd"
+
'';
+
+
systemd.tmpfiles.rules = [
+
# Initialise the state directory
+
"d ${cfg.stateDir} 0770 ${cfg.user} ${cfg.group} - -"
+
];
systemd.services.tcsd = {
-
description = "TCSD";
-
after = [ "systemd-udev-settle.service" ];
+
description = "Manager for Trusted Computing resources";
+
documentation = [ "man:tcsd(8)" ];
+
+
requires = [ "dev-tpm0.device" ];
+
after = [ "dev-tpm0.device" ];
wantedBy = [ "multi-user.target" ];
-
path = [ pkgs.trousers ];
-
preStart =
-
''
-
mkdir -m 0700 -p ${cfg.stateDir}
-
chown -R ${cfg.user}:${cfg.group} ${cfg.stateDir}
-
'';
-
serviceConfig.ExecStart = "${pkgs.trousers}/sbin/tcsd -f -c ${tcsdConf}";
+
+
serviceConfig = {
+
User = cfg.user;
+
Group = cfg.group;
+
ExecStart = "${pkgs.trousers}/sbin/tcsd -f -c ${tcsdConf}";
+
};
};
users.users = optionalAttrs (cfg.user == "tss") {