[plasma/kscreenlocker] greeter: pamauthenticator: detect slow broken services more reliably
Harald Sitter <[email protected]>
| Newsgroups | gmane.comp.kde.cvs |
|---|---|
| Message-ID | <[email protected]> |
Git commit cc1ee1ad5cbd13a1ec7f6fd9f040fea357ad3277 by Harald Sitter.
Committed on 18/08/2026 at 11:15.
Pushed by sitter into branch 'master'.
pamauthenticator: detect slow broken services more reliably
M +19 -1 greeter/pamauthenticator.cpp
M +2 -0 greeter/pamauthenticator.h
https://invent.kde.org/plasma/kscreenlocker/-/commit/cc1ee1ad5cbd13a1ec7f6fd9f040fea357ad3277
diff --git a/greeter/pamauthenticator.cpp b/greeter/pamauthenticator.cpp
index 32c454f8..833405da 100644
--- a/greeter/pamauthenticator.cpp
+++ b/greeter/pamauthenticator.cpp
@@ -62,7 +62,25 @@ PamAuthenticator::PamAuthenticator(const QString &service, const QString &user,
});
// Failed is not a persistent state. When a view provides authentication that will either result in failure or success,
// failure simply means that the prompt is getting delayed.
- connect(d, &PamWorker::failed, this, &PamAuthenticator::failed);
+ connect(d, &PamWorker::failed, this, [this] {
+ // Guard against particularly broken PAM services. For example when pam-u2f doesn't find a token because it is
+ // not plugged in it will fail the authentication, but it will do it so slowly that the timing checks in the
+ // worker itself don't bite.
+ // Here we can keep a higher level view of the failures and if need be break the loop by marking us unavailable.
+ auto now = QDateTime::currentDateTimeUtc();
+ if (now - m_lastFailed < 2s) {
+ m_failedCount++;
+ if (m_failedCount > 3) {
+ m_unavailable = true;
+ Q_EMIT availableChanged();
+ }
+ } else {
+ m_failedCount = 0;
+ }
+ m_lastFailed = now;
+
+ Q_EMIT failed();
+ });
connect(d, &PamWorker::loginFailedDelayStarted, this, &PamAuthenticator::loginFailedDelayStarted);
m_thread.start();
diff --git a/greeter/pamauthenticator.h b/greeter/pamauthenticator.h
index d3831a38..aa562f60 100644
--- a/greeter/pamauthenticator.h
+++ b/greeter/pamauthenticator.h
@@ -117,6 +117,8 @@ private:
bool m_unlocked = false;
bool m_unavailable = false;
bool m_inPasswordDelay = false;
+ uint m_failedCount = 0;
+ QDateTime m_lastFailed = QDateTime::currentDateTimeUtc();
NoninteractiveAuthenticatorTypes m_authenticatorType;
// Tiny problem with bare bones QThread: when we shut down we want to clean up
// our subprocess correctly, but doing that means running a function on the thread