From ff73f820b1398e5d60b8984b0003db46ad70b8ec 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 97df6d687e..371953cb25 100644
--- a/js/gdm/util.js
+++ b/js/gdm/util.js
@@ -109,6 +109,7 @@ export class ShellUserVerifier extends Signals.EventEmitter {
         this._defaultService = null;
         this._preemptingService = null;
         this._fingerprintReaderType = FingerprintReaderType.NONE;
+        this._fprintStartTime = -1;
 
         this._messageQueue = [];
         this._messageQueueTimeoutId = 0;
@@ -669,6 +670,10 @@ export class ShellUserVerifier extends Signals.EventEmitter {
         this._hold.acquire();
         try {
             this._activeServices.add(serviceName);
+
+            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);
@@ -763,6 +768,7 @@ export class ShellUserVerifier extends Signals.EventEmitter {
                 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);
@@ -829,6 +835,18 @@ export class ShellUserVerifier extends Signals.EventEmitter {
         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.43.2

