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: <https://gitlab.gnome.org/GNOME/gnome-shell/-/merge_requests/1622>
This commit is contained in:
Marco Trevisan (Treviño) 2021-02-02 15:08:10 +01:00 committed by Marge Bot
parent c936ca3ea0
commit 0ccb8e27d4

View File

@ -224,6 +224,7 @@ var ShellUserVerifier = class {
_clearUserVerifier() { _clearUserVerifier() {
if (this._userVerifier) { if (this._userVerifier) {
this._disconnectSignals();
this._userVerifier.run_dispose(); this._userVerifier.run_dispose();
this._userVerifier = null; this._userVerifier = null;
} }
@ -431,13 +432,31 @@ var ShellUserVerifier = class {
} }
_connectSignals() { _connectSignals() {
this._userVerifier.connect('info', this._onInfo.bind(this)); this._disconnectSignals();
this._userVerifier.connect('problem', this._onProblem.bind(this)); this._signalIds = [];
this._userVerifier.connect('info-query', this._onInfoQuery.bind(this));
this._userVerifier.connect('secret-info-query', this._onSecretInfoQuery.bind(this)); let id = this._userVerifier.connect('info', this._onInfo.bind(this));
this._userVerifier.connect('conversation-stopped', this._onConversationStopped.bind(this)); this._signalIds.push(id);
this._userVerifier.connect('reset', this._onReset.bind(this)); id = this._userVerifier.connect('problem', this._onProblem.bind(this));
this._userVerifier.connect('verification-complete', this._onVerificationComplete.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() { _getForegroundService() {
@ -581,6 +600,8 @@ var ShellUserVerifier = class {
(this._reauthOnly || (this._reauthOnly ||
this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY)); this._failCounter < this._settings.get_int(ALLOWED_FAILURES_KEY));
this._disconnectSignals();
if (canRetry) { if (canRetry) {
if (!this.hasPendingMessages) { if (!this.hasPendingMessages) {
this._retry(); this._retry();