undismissable, unclickable polkit authentication agent dialog after session lock/unlock if PAM authorize action without password
Affected version
Tested on:
- Archlinux
- 3.38.3
- Wayland
Bug still present on 2021-02-09 master: 6a2ed852
Bug summary
Notes:
- It's a reopen + correction + completion of issue #1467 (closed)
- It may be related to https://bugs.launchpad.net/ubuntu/+source/gnome-shell/+bug/1824874
- It may be related to https://www.reddit.com/r/gnome/comments/fscvql/authentication_required_window/
I have a yubikey (an usb dongle to authenticate myself on my computer).
I configured my /etc/pam.d/system-auth
like the following so when my yubikey is plugged I don't need to type my password to be authenticated:
auth sufficient pam_yubico.so mode=challenge-response
auth required pam_unix.so try_first_pass nullok
auth optional pam_permit.so
(So I can run sudo commands without password prompt)
When I use pkexec
(or any command using polkit, eg. systemctl
) gnome polkit authentication prompt is not displayed, and the command is run as intended.
max@host % pkexec whoami
root
But then, if I lock/unlock my session, the prompt is displayed, but I can't type any password nor make it disappear. Which is very annoying since it will always be in front of all the other applications.
(See the "Relevant logs, screenshots, screencasts etc." section for deeper explanation and a dirty fix)
Steps to reproduce
Edit your /etc/pam.d/system-auth, add auth sufficient pam_permit.so
before auth required pam_unix.so
:
…
auth sufficient pam_permit.so
auth required pam_unix.so try_first_pass nullok
auth optional pam_permit.so
…
Run pkexec whoami
, lock your session loginctl lock-session
and unlock it.
What happened
The "authentication is needed" dialog appear at the top left corner of the screen. This dialog is undismissable. The only solution I found to get rid of it is to restart gdm.
What did you expect to happen
The "authentication is needed" dialog should never appear.
Relevant logs, screenshots, screencasts etc.
I modifier the polkitAgent.js file of gnome-shell to try to understand what append: polkitAgent_log.js
Here is a normal authentication (without my yubikey, so I use my password):
# I run `pkexec whoami`
22:51:06 gnome-shell[1302]: _init start
22:51:06 gnome-shell[1302]: _onUserChanged start
22:51:06 gnome-shell[1302]: _onUserChanged 4
22:51:06 gnome-shell[1302]: _initiateSession start
22:51:06 gnome-shell[1302]: _destroySession start
22:51:06 gnome-shell[1302]: _destroySession end
22:51:06 gnome-shell[1302]: _initiateSession end
22:51:06 gnome-shell[1302]: _onUserChanged end
22:51:06 gnome-shell[1302]: _init end
# pam_unix (I think) request a session start
22:51:06 gnome-shell[1302]: _onSessionRequest start
# the dialog is open
22:51:06 gnome-shell[1302]: _ensureOpen start
22:51:06 gnome-shell[1302]: _ensureOpen end
22:51:06 gnome-shell[1302]: _onSessionRequest end
# I type my password
22:51:11 gnome-shell[1302]: _onEntryActivate start
22:51:11 gnome-shell[1302]: _onEntryActivate end
# and get authenticated
22:51:11 gnome-shell[1302]: _onSessionCompleted start
# the authentication if marked as done
22:51:11 gnome-shell[1302]: _emitDone start
22:51:11 gnome-shell[1302]: _emitDone in
22:51:11 gnome-shell[1302]: _emitDone end
22:51:11 gnome-shell[1302]: _onSessionCompleted end
# and the dialog is closed
22:51:11 gnome-shell[1302]: _onDialogClosed start
22:51:11 gnome-shell[1302]: _destroySession start
22:51:11 gnome-shell[1302]: _destroySession 1
22:51:11 gnome-shell[1302]: _destroySession end
22:51:11 gnome-shell[1302]: _onDialogClosed end
Here is an abnormal authentication (with my yubikey):
# I run `pkexec whoami`
22:46:29 gnome-shell[5696]: _init start
22:46:29 gnome-shell[5696]: _onUserChanged start
22:46:29 gnome-shell[5696]: _onUserChanged 4
22:46:29 gnome-shell[5696]: _initiateSession start
22:46:29 gnome-shell[5696]: _destroySession start
22:46:29 gnome-shell[5696]: _destroySession end
22:46:29 gnome-shell[5696]: _initiateSession end
22:46:29 gnome-shell[5696]: _onUserChanged end
22:46:29 gnome-shell[5696]: _init end
# pam_yubico authenticate me
22:46:29 gnome-shell[5696]: _onSessionCompleted start
# the authentication if marked as done
22:46:29 gnome-shell[5696]: _emitDone start
22:46:29 gnome-shell[5696]: _emitDone in
22:46:29 gnome-shell[5696]: _emitDone end
22:46:29 gnome-shell[5696]: _onSessionCompleted end
# later I lock/unlock session and the dialog appear
22:47:25 gnome-shell[5696]: _onUserChanged start
22:47:25 gnome-shell[5696]: _onUserChanged 4
22:47:25 gnome-shell[5696]: _onUserChanged 5
22:47:25 gnome-shell[5696]: _onUserChanged start
22:47:25 gnome-shell[5696]: _onUserChanged 4
22:47:25 gnome-shell[5696]: _onUserChanged 5
22:47:25 gnome-shell[5696]: _onUserChanged start
22:47:25 gnome-shell[5696]: _onUserChanged 4
22:47:25 gnome-shell[5696]: _onUserChanged 5
During the authentication process only _onSessionCompleted is call (_onSessionRequest, _ensureOpen, _onDialogClosed… are never called). So AuthenticationDialog object isn't clean properly.
I made this dirty patch to ensure _onDialogClosed is called after _emitDone if _ensureOpen was never called:
diff --git a/js/ui/components/polkitAgent.js b/js/ui/components/polkitAgent.js
index e8f3b30f4..0416edcf5 100644
--- a/js/ui/components/polkitAgent.js
+++ b/js/ui/components/polkitAgent.js
@@ -29,6 +29,7 @@ var AuthenticationDialog = GObject.registerClass({
this.actionId = actionId;
this.message = description;
this.userNames = userNames;
+ this._ensureOpenWasCalled = false;
this._sessionUpdatedId = Main.sessionMode.connect('updated', () => {
this.visible = !Main.sessionMode.isLocked;
@@ -178,6 +179,7 @@ var AuthenticationDialog = GObject.registerClass({
}
_ensureOpen() {
+ this._ensureOpenWasCalled = true;
// NOTE: ModalDialog.open() is safe to call if the dialog is
// already open - it just returns true without side-effects
if (!this.open(global.get_current_time())) {
@@ -203,6 +205,9 @@ var AuthenticationDialog = GObject.registerClass({
if (!this._doneEmitted) {
this._doneEmitted = true;
this.emit('done', dismissed);
+ if (!this._ensureOpenWasCalled) {
+ this._onDialogClosed();
+ }
}
}
I didn't make it a PR as I am not a JS or gnome shell developer, and there is certainly some corner case I didn't think of, it's more a proof of concept (but so far it works for me).
Here is an authentication with my yubikey, with the patched applied (+ the logs):
23:10:56 gnome-shell[1304]: _init start
23:10:56 gnome-shell[1304]: _onUserChanged start
23:10:56 gnome-shell[1304]: _onUserChanged 4
23:10:56 gnome-shell[1304]: _initiateSession start
23:10:56 gnome-shell[1304]: _destroySession start
23:10:56 gnome-shell[1304]: _destroySession end
23:10:56 gnome-shell[1304]: _initiateSession end
23:10:56 gnome-shell[1304]: _onUserChanged end
23:10:56 gnome-shell[1304]: _init end
23:10:56 gnome-shell[1304]: _onSessionCompleted start
23:10:56 gnome-shell[1304]: _emitDone start
23:10:56 gnome-shell[1304]: _emitDone in
23:10:56 gnome-shell[1304]: _onDialogClosed start
23:10:56 gnome-shell[1304]: _destroySession start
23:10:56 gnome-shell[1304]: _destroySession 1
23:10:56 gnome-shell[1304]: _destroySession end
23:10:56 gnome-shell[1304]: _onDialogClosed end
23:10:56 gnome-shell[1304]: _emitDone end
23:10:56 gnome-shell[1304]: _onSessionCompleted end