From 22df9fa5e3c973d5a194f2bbdbcdd4a64511bc93 Mon Sep 17 00:00:00 2001
From: Benjamin Berg <bberg@redhat.com>
Date: Wed, 28 Apr 2021 16:50:03 +0200
Subject: [PATCH] gdm: Work around failing fingerprint auth

On Fedora we have the problem that fingerprint auth fails immediately if
the PAM configuration has not been updated and no prints are enrolled.

So, consider a verification failure within one second to be a service
failure instead.
---
 js/gdm/util.js | 18 ++++++++++++++++++
 1 file changed, 18 insertions(+)

diff --git a/js/gdm/util.js b/js/gdm/util.js
index b02cd4d73..118a05100 100644
--- a/js/gdm/util.js
+++ b/js/gdm/util.js
@@ -157,6 +157,7 @@ var ShellUserVerifier = class {
             null,
             null,
             Gio.DBusProxyFlags.DO_NOT_LOAD_PROPERTIES);
+        this._fprintStartTime = -1;
         this._smartcardManager = SmartcardManager.getSmartcardManager();
 
         // We check for smartcards right away, since an inserted smartcard
@@ -543,6 +544,10 @@ var ShellUserVerifier = class {
     async _startService(serviceName) {
         this._hold.acquire();
         try {
+            if (serviceName == FINGERPRINT_SERVICE_NAME) {
+                this._fprintStartTime = GLib.get_monotonic_time();
+            }
+
             if (this._userName) {
                 await this._userVerifier.call_begin_verification_for_user(
                     serviceName, this._userName, this._cancellable);
@@ -624,6 +629,7 @@ var ShellUserVerifier = class {
                 const cancellable = this._cancellable;
                 this._fingerprintFailedId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
                     FINGERPRINT_ERROR_TIMEOUT_WAIT, () => {
+                        log("Generating _verificationFailed!");
                         this._fingerprintFailedId = 0;
                         if (!cancellable.is_cancelled())
                             this._verificationFailed(serviceName, false);
@@ -689,6 +695,18 @@ var ShellUserVerifier = class {
         if (serviceName === FINGERPRINT_SERVICE_NAME) {
             if (this._fingerprintFailedId)
                 GLib.source_remove(this._fingerprintFailedId);
+
+            // On Fedora we have the problem that fingerprint auth fails
+            // immediately if the PAM configuration has not been updated and no
+            // prints are enrolled.
+            // So, consider a verification failure within one second to be a service
+            // failure instead.
+            if (this._fprintStartTime > GLib.get_monotonic_time() - GLib.USEC_PER_SEC) {
+                log("Fingerprint service failed almost immediately, considering it unavailable.");
+                log("Please fix your configuration by running: authselect select --force sssd with-fingerprint with-silent-lastlog");
+                this._onServiceUnavailable(this._client, serviceName, null);
+                return;
+            }
         }
 
         // For Not Listed / enterprise logins, immediately reset
-- 
2.31.1

