From 46f155749dc3e76be9d2f3972361243288776440 Mon Sep 17 00:00:00 2001 From: Manuel Bluhm Date: Thu, 4 Apr 2024 21:41:34 +0400 Subject: [PATCH] Add fingerprint functionality to guivm - module with qemu rules, required packages and services, and polkit/pam configs; conditionally applied to guivmExtraModules - allows ghaf user to enroll and verify fingerprints - works with swaylock, sudo, systemctl (note: swaylock needs to be enabled) - swaylock works with password w/o fingerprint, when fp is enrolled it allows either password or fp. To use fp auth, press Enter and then do fp auth Further work required: - persistent fingerprint data storage required - proper integration with login manager (when ready) - potential enrollment application - swaylock bugs have been observed (some even w/o fingerprint) Signed-off-by: Manuel Bluhm --- modules/hardware/lenovo-x1/default.nix | 1 + modules/hardware/lenovo-x1/modules/fprint.nix | 94 +++++++++++++++++++ targets/lenovo-x1/everything.nix | 1 + targets/lenovo-x1/guivmExtraModules.nix | 42 +++++---- 4 files changed, 119 insertions(+), 19 deletions(-) create mode 100644 modules/hardware/lenovo-x1/modules/fprint.nix diff --git a/modules/hardware/lenovo-x1/default.nix b/modules/hardware/lenovo-x1/default.nix index fda48e4eb..af90c4e2a 100644 --- a/modules/hardware/lenovo-x1/default.nix +++ b/modules/hardware/lenovo-x1/default.nix @@ -4,5 +4,6 @@ imports = [ ./definitions ./ax88179_178a.nix + ./modules/fprint.nix ]; } diff --git a/modules/hardware/lenovo-x1/modules/fprint.nix b/modules/hardware/lenovo-x1/modules/fprint.nix new file mode 100644 index 000000000..3016198b2 --- /dev/null +++ b/modules/hardware/lenovo-x1/modules/fprint.nix @@ -0,0 +1,94 @@ +# Copyright 2022-2024 TII (SSRC) and the Ghaf contributors +# SPDX-License-Identifier: Apache-2.0 +{ + config, + lib, + pkgs, + ... +}: let + cfg = config.ghaf.hardware.fprint; +in + with lib; { + options.ghaf.hardware.fprint = { + enable = mkEnableOption "Enable fingerprint reader support"; + qemuExtraArgs = mkOption { + type = types.listOf types.str; + default = []; + description = '' + Extra arguments to pass to Qemu when enabling the fingerprint reader. + This is useful for passing USB device information to Qemu. + ''; + }; + extraConfigurations = mkOption { + type = types.attrsOf types.anything; + default = {}; + description = '' + Extra configurations to enable when enabling the fingerprint reader. + This is useful for enabling services and packages related to the fingerprint reader. + ''; + }; + }; + + config = mkIf cfg.enable { + ghaf.hardware.fprint = { + qemuExtraArgs = [ + # Fingerprint reader + "-device" + "qemu-xhci" + "-device" + "usb-host,hostbus=3,hostport=6" + ]; + + extraConfigurations = { + # Enable service and package for fingerprint reader + services.fprintd.enable = true; + environment.systemPackages = with pkgs; [fprintd]; + + # Enable polkit and add rules + ghaf.systemd.withPolkit = true; + security = { + polkit = { + enable = true; + debug = true; + # Polkit rules for fingerprint reader + extraConfig = '' + // Allow user to verify fingerprints + polkit.addRule(function(action, subject) { + if (action.id == "net.reactivated.fprint.device.verify" && + subject.user == "ghaf") { + return polkit.Result.YES; + } + }); + // Allow user to enroll fingerprints + polkit.addRule(function(action, subject) { + if (action.id == "net.reactivated.fprint.device.enroll" && + subject.user == "ghaf") { + return polkit.Result.YES; + } + }); + ''; + }; + # PAM rules for swaylock fingerprint reader + pam.services = { + swaylock.text = '' + # Account management. + account required pam_unix.so + + # Authentication management. + auth sufficient pam_unix.so likeauth try_first_pass + auth sufficient ${pkgs.fprintd}/lib/security/pam_fprintd.so + auth required pam_deny.so + + # Password management. + password sufficient pam_unix.so nullok sha512 + + # Session management. + session required pam_env.so conffile=/etc/pam/environment readenv=0 + session required pam_unix.so + ''; + }; + }; + }; + }; + }; + } diff --git a/targets/lenovo-x1/everything.nix b/targets/lenovo-x1/everything.nix index 2cbb0911d..ecd501669 100644 --- a/targets/lenovo-x1/everything.nix +++ b/targets/lenovo-x1/everything.nix @@ -62,6 +62,7 @@ hardware.generation = generation; hardware.ax88179_178a.enable = true; hardware.tpm2.enable = true; + hardware.fprint.enable = true; # Kernel hardening host.kernel.hardening.enable = false; diff --git a/targets/lenovo-x1/guivmExtraModules.nix b/targets/lenovo-x1/guivmExtraModules.nix index f05634662..f249173f0 100644 --- a/targets/lenovo-x1/guivmExtraModules.nix +++ b/targets/lenovo-x1/guivmExtraModules.nix @@ -150,24 +150,28 @@ boot.initrd.kernelModules = ["i915"]; microvm.qemu = { - extraArgs = [ - # Lenovo X1 Lid button - "-device" - "button" - # Lenovo X1 battery - "-device" - "battery" - # Lenovo X1 AC adapter - "-device" - "acad" - # Connect sound device to hosts pulseaudio socket - "-audiodev" - "pa,id=pa1,server=unix:/run/pulse/native" - ]; + extraArgs = + [ + # Lenovo X1 Lid button + "-device" + "button" + # Lenovo X1 battery + "-device" + "battery" + # Lenovo X1 AC adapter + "-device" + "acad" + # Connect sound device to hosts pulseaudio socket + "-audiodev" + "pa,id=pa1,server=unix:/run/pulse/native" + ] + ++ lib.optionals configH.ghaf.hardware.fprint.enable configH.ghaf.hardware.fprint.qemuExtraArgs; }; }; -in [ - guivmPCIPassthroughModule - guivmVirtioInputHostEvdevModule - guivmExtraConfigurations -] +in + [ + guivmPCIPassthroughModule + guivmVirtioInputHostEvdevModule + guivmExtraConfigurations + ] + ++ lib.optionals configH.ghaf.hardware.fprint.enable [configH.ghaf.hardware.fprint.extraConfigurations]