[gnome-shell] gdm: Compress fingerprint failures events using a timeout



commit 9ecc1a4cd7f15e84898f6649125080d24a2a5e11
Author: Marco Trevisan (TreviƱo) <mail 3v1n0 net>
Date:   Tue Feb 16 04:18:18 2021 +0100

    gdm: Compress fingerprint failures events using a timeout
    
    When a fingerprint failure event happens we may also soon receive a
    conversation-stopped event with an error message (such as in the case
    we hit the MAXRETRIES value), but this is going to be ignored in case we
    are too quick in consider the first failure a verification-failed event
    because that implies disconnecting from all the events and then ignoring
    such signals.
    
    To prevent this, add a small timeout before failing the verification so
    that if we get a further event we will process it.
    
    Part-of: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1683>

 js/gdm/util.js | 25 +++++++++++++++++++++++--
 1 file changed, 23 insertions(+), 2 deletions(-)
---
diff --git a/js/gdm/util.js b/js/gdm/util.js
index ddd03c5f0d..369c0bb331 100644
--- a/js/gdm/util.js
+++ b/js/gdm/util.js
@@ -46,6 +46,7 @@ var DISABLE_USER_LIST_KEY = 'disable-user-list';
 
 // Give user 48ms to read each character of a PAM message
 var USER_READ_TIME = 48;
+const FINGERPRINT_ERROR_TIMEOUT_WAIT = 15;
 
 var MessageType = {
     NONE: 0,
@@ -568,10 +569,30 @@ var ShellUserVerifier = class {
 
         this._queueMessage(serviceName, problem, MessageType.ERROR);
         if (isFingerprint) {
+            // pam_fprintd allows the user to retry multiple (maybe even infinite!
+            // times before failing the authentication conversation.
+            // We don't want this behavior to bypass the max-tries setting the user has set,
+            // so we count the problem messages to know how many times the user has failed.
+            // Once we hit the max number of failures we allow, it's time to failure the
+            // conversation from our side. We can't do that right away, however, because
+            // we may drop pending messages coming from pam_fprintd. In order to make sure
+            // the user sees everything, we queue the failure up to get handled in the
+            // near future, after we've finished up the current round of messages.
             this._failCounter++;
 
-            if (!this._canRetry())
-                this._verificationFailed(serviceName, false);
+            if (!this._canRetry()) {
+                if (this._fingerprintFailedId)
+                    GLib.source_remove(this._fingerprintFailedId);
+
+                const cancellable = this._cancellable;
+                this._fingerprintFailedId = GLib.timeout_add(GLib.PRIORITY_DEFAULT,
+                    FINGERPRINT_ERROR_TIMEOUT_WAIT, () => {
+                        this._fingerprintFailedId = 0;
+                        if (!cancellable.is_cancelled())
+                            this._verificationFailed(serviceName, false);
+                        return GLib.SOURCE_REMOVE;
+                    });
+            }
         }
     }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]