mirror of
https://github.com/AvengeMedia/DankMaterialShell.git
synced 2026-06-28 14:05:21 -04:00
fix(lock): show the faillock lockout reason instead of "incorrect password" (#2669)
When pam_faillock locks the account (DMS authenticates through the system PAM stack: /etc/pam.d/login -> system-auth), the lock screen kept showing the generic "Incorrect password - try again" even though the real cause is a lockout, so a correct password looks rejected and only a reboot (which clears the tmpfs /run/faillock tally) appears to help. See #2647. The previous onMessageChanged only matched the *English* faillock strings ("The account is locked ...") and then wiped that text again on the trailing pam_unix "Password:" prompt. On a non-English system (e.g. German) the strings never matched, so the lockout was never surfaced at all. Detect the notice by position rather than by text: pam emits its informational messages within an attempt before the password prompt. Collect every non-prompt info message and, once the prompt arrives, surface the collected lines (minus the prompt itself) as lockMessage. If the stack short-circuits without ever prompting (e.g. pam_faillock preauth configured as requisite), the notice is surfaced on completion instead. This is locale-independent. A per-attempt flag keeps the message stable across repeated locked attempts and retires it when an attempt completes without a lockout (faillock reset / unlock_time elapsed). Fixes #2647
This commit is contained in:
@@ -23,6 +23,9 @@ Scope {
|
|||||||
property string u2fPendingMode
|
property string u2fPendingMode
|
||||||
property string buffer
|
property string buffer
|
||||||
|
|
||||||
|
property var attemptInfoMessages: []
|
||||||
|
property bool lockoutAnnouncedThisAttempt: false
|
||||||
|
|
||||||
signal flashMsg
|
signal flashMsg
|
||||||
signal unlockRequested
|
signal unlockRequested
|
||||||
|
|
||||||
@@ -118,23 +121,37 @@ Scope {
|
|||||||
configDirectory: (dankshellConfigWatcher.loaded || nixosMarker.loaded || root.runningFromNixStore) ? "/etc/pam.d" : Quickshell.shellDir + "/assets/pam"
|
configDirectory: (dankshellConfigWatcher.loaded || nixosMarker.loaded || root.runningFromNixStore) ? "/etc/pam.d" : Quickshell.shellDir + "/assets/pam"
|
||||||
|
|
||||||
onMessageChanged: {
|
onMessageChanged: {
|
||||||
if (message.startsWith("The account is locked")) {
|
// collected by position, not text, so it works in any locale
|
||||||
root.lockMessage = message;
|
if (message.length > 0 && !responseRequired)
|
||||||
} else if (root.lockMessage && message.endsWith(" left to unlock)")) {
|
root.attemptInfoMessages = root.attemptInfoMessages.concat([message]);
|
||||||
root.lockMessage += "\n" + message;
|
|
||||||
} else if (root.lockMessage && message && message.length > 0) {
|
|
||||||
root.lockMessage = "";
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
onResponseRequiredChanged: {
|
onResponseRequiredChanged: {
|
||||||
if (!responseRequired)
|
if (!responseRequired)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
const notice = root.attemptInfoMessages.filter(m => m !== message);
|
||||||
|
if (notice.length > 0) {
|
||||||
|
root.lockMessage = notice.join("\n");
|
||||||
|
root.lockoutAnnouncedThisAttempt = true;
|
||||||
|
}
|
||||||
|
root.attemptInfoMessages = [];
|
||||||
|
|
||||||
respond(root.buffer);
|
respond(root.buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
onCompleted: res => {
|
onCompleted: res => {
|
||||||
|
// requisite preauth can lock without ever prompting; surface it here too
|
||||||
|
if (!root.lockoutAnnouncedThisAttempt) {
|
||||||
|
if (root.attemptInfoMessages.length > 0) {
|
||||||
|
root.lockMessage = root.attemptInfoMessages.join("\n");
|
||||||
|
root.lockoutAnnouncedThisAttempt = true;
|
||||||
|
} else {
|
||||||
|
root.lockMessage = "";
|
||||||
|
}
|
||||||
|
root.attemptInfoMessages = [];
|
||||||
|
}
|
||||||
|
|
||||||
if (res === PamResult.Success) {
|
if (res === PamResult.Success) {
|
||||||
if (!root.unlockInProgress) {
|
if (!root.unlockInProgress) {
|
||||||
fprint.abort();
|
fprint.abort();
|
||||||
@@ -168,6 +185,8 @@ Scope {
|
|||||||
|
|
||||||
function onActiveChanged() {
|
function onActiveChanged() {
|
||||||
if (passwd.active) {
|
if (passwd.active) {
|
||||||
|
root.attemptInfoMessages = [];
|
||||||
|
root.lockoutAnnouncedThisAttempt = false;
|
||||||
passwdActiveTimeout.restart();
|
passwdActiveTimeout.restart();
|
||||||
} else {
|
} else {
|
||||||
passwdActiveTimeout.running = false;
|
passwdActiveTimeout.running = false;
|
||||||
@@ -393,6 +412,8 @@ Scope {
|
|||||||
root.u2fPending = false;
|
root.u2fPending = false;
|
||||||
root.u2fPendingMode = "";
|
root.u2fPendingMode = "";
|
||||||
root.lockMessage = "";
|
root.lockMessage = "";
|
||||||
|
root.attemptInfoMessages = [];
|
||||||
|
root.lockoutAnnouncedThisAttempt = false;
|
||||||
root.resetAuthFlows();
|
root.resetAuthFlows();
|
||||||
fprint.checkAvail();
|
fprint.checkAvail();
|
||||||
u2f.checkAvail();
|
u2f.checkAvail();
|
||||||
|
|||||||
Reference in New Issue
Block a user