From 0ccb8e27d455f2b102a4d40852971f601cbc9ba7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marco=20Trevisan=20=28Trevi=C3=B1o=29?= Date: Tue, 2 Feb 2021 15:08:10 +0100 Subject: [PATCH] gdm: Disconnect user verifier signals on destruction and verification failed When a verification session has failed we may want to wait for the user to have completed all the waiting queries and to have read all the incoming messages, however during such time an user verifier should not be allowed to queue further messages to the UI, as we're about to completely stop the identification or start a new one. Unfortunately this is not true because we're still connected to the identifier signals, and so we may still show messages. This is particularly true when using the fingerprint PAM module as it may restart the authentication while we're in the process of stopping it. So, keep track of all the signals we've connected to, and disconnect on verification failed and during cancel/clear operations. Part-of: --- js/gdm/util.js | 35 ++++++++++++++++++++++++++++------- 1 file changed, 28 insertions(+), 7 deletions(-) diff --git a/js/gdm/util.js b/js/gdm/util.js index 048e2bf5e..587a2c941 100644 --- a/js/gdm/util.js +++ b/js/gdm/util.js @@ -224,6 +224,7 @@ var ShellUserVerifier = class { _clearUserVerifier() { if (this._userVerifier) { + this._disconnectSignals(); this._userVerifier.run_dispose(); this._userVerifier = null; } @@ -431,13 +432,31 @@ var ShellUserVerifier = class { } _connectSignals() { - this._userVerifier.connect('info', this._onInfo.bind(this)); - this._userVerifier.connect('problem', this._onProblem.bind(this)); - this._userVerifier.connect('info-query', this._onInfoQuery.bind(this)); - this._userVerifier.connect('secret-info-query', this._onSecretInfoQuery.bind(this)); - this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this)); - this._userVerifier.connect('reset', this._onReset.bind(this)); - this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this)); + this._disconnectSignals(); + this._signalIds = []; + + let id = this._userVerifier.connect('info', this._onInfo.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('problem', this._onProblem.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('info-query', this._onInfoQuery.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('secret-info-query', this._onSecretInfoQuery.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('reset', this._onReset.bind(this)); + this._signalIds.push(id); + id = this._userVerifier.connect('verification-complete', this._onVerificationComplete.bind(this)); + this._signalIds.push(id); + } + + _disconnectSignals() { + if (!this._signalIds || !this._userVerifier) + return; + + this._signalIds.forEach(s => this._userVerifier.disconnect(s)); + this._signalIds = []; } _getForegroundService() { @@ -581,6 +600,8 @@ var ShellUserVerifier = class { (this._reauthOnly || this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY)); + this._disconnectSignals(); + if (canRetry) { if (!this.hasPendingMessages) { this._retry();