Subject: [bug#56797] [PATCH] gnu: services: fprintd: Add PAM configuration.

From: Maya <[email-masked]>
Date: Wed, 27 Jul 2022 15:57:39 +0000

Added a feature to fprintd-service-type to allow unlocking PAM modules (ie. gdm login, gnome polkit etc.) by fingerprint.

---

 gnu/services/authentication.scm | 49 +++++++++++++++++++++++++++++++--
 1 file changed, 46 insertions(+), 3 deletions(-)

diff --git a/gnu/services/authentication.scm b/gnu/services/authentication.scm
index f7becdfafb..5737c15f4c 100644
--- a/gnu/services/authentication.scm
+++ b/gnu/services/authentication.scm
@@ -44,9 +44,50 @@ (define-module (gnu services authentication)
             nslcd-configuration?
             nslcd-service-type))

-(define-configuration fprintd-configuration
+(define-configuration/no-serialization fprintd-configuration
   (fprintd      (file-like fprintd)
-                "The fprintd package"))
+                "The fprintd package")
+  (unlock-gdm?
+   (boolean #t)
+   "Generate PAM configuration that unlocks gdm with fprintd.")
+  (unlock-other
+   (list '("polkit-1" "sddm")) ;; polkit-1 is the name of a PAM module for GNOME polkit
+   "List of other PAM modules that can be unlocked with fprintd.
+
+This depends on your desktop configuration. If you for example want GNOME prompts to be unlocked by fingerprint, you add @code{polkit-1} to this list. (This is enabled by default.)
+"))
+
+(define (fprintd-pam-other-services config fprintd-module)
+  (lambda (pam)
+    (if (member (pam-service-name pam)
+                (fprintd-configuration-unlock-other config))
+        (let ((sufficient
+               (pam-entry
+                (control "sufficient")
+                (module fprintd-module))))
+          (pam-service
+           (inherit pam)
+           (auth (cons sufficient (pam-service-auth pam)))))
+        pam)))
+
+(define (fprintd-pam-gdm-services fprintd-module)
+  (list
+   (pam-service
+    (inherit (unix-pam-service "gdm-fingerprint"
+                               #:login-uid? #t))
+    (auth (list
+           (pam-entry
+            (control "required")
+            (module fprintd-module)))))))
+
+(define (fprintd-pam-services config)
+  (let ((fprintd-module
+         #~(string-append #$(fprintd-configuration-fprintd config) "/lib/security/pam_fprintd.so")))
+    (cons
+     (fprintd-pam-other-services config fprintd-module)
+     (if fprintd-configuration-unlock-gdm?
+         (fprintd-pam-gdm-services fprintd-module)
+         '()))))

 (define (fprintd-dbus-service config)
   (list (fprintd-configuration-fprintd config)))
@@ -57,7 +98,9 @@ (define fprintd-service-type
                  (list (service-extension dbus-root-service-type
                                           fprintd-dbus-service)
                        (service-extension polkit-service-type
-                                          fprintd-dbus-service)))
+                                          fprintd-dbus-service)
+                       (service-extension pam-root-service-type
+                                          fprintd-pam-services)))
                 (default-value (fprintd-configuration))
                 (description
                  "Run fprintd, a fingerprint management daemon.")))
--
2.37.0

I sincerely that the gdm pam module is correct. Guix uses non-standard way of defining pam services and it was hard for me to decipher needed contents for gdm-fingerprint. /However, I tested it on my laptop and it works! My only concern is security/

I chose the most usual modules to unlock by fingerprint, if you think that the list is missing something or has something that should not be there, let me know!

With wishes for zero-bug code,
Maya