https://bugs.kde.org/show_bug.cgi?id=506567

--- Comment #13 from Caballo Juan <[email protected]> ---
Ah, nevermind :(. Unfortunately, the udev hack doesn't appear to work reliably
because the klockscreen component also has some logic that seems flawed. Good
thing is that I managed to somehow fix it with the udev hack and by handling
some corner cases in klockscreen. I also came up with a reliable way to
reproduce this error with current plasma (6.4.5):

1. Restart fprintd service to start with a clean slate (systemctl restart
fprintd), or kill fprintd with pkill
2. Lock the screen (at this point, the "(or press your fingerprint)" thing will
appear. Do not unlock with fingerprint.
3. Either close the lid or hit the lockscreen suspend button, or do whatever
anything t
4. Wake the computer up again. At this point, it appears that no matter what,
even if the fprintd service is restarted to make it work again, klockscreen
won't "detect" fprintd is up again. So even if the fprintd hack were to be
used, klockscreen's auth logic is slightly bugged because it won't retry to use
fprintd again. It permanently "thinks" the fprintd thing is dead.

I'm a developer, although I have absolutely 0.000% C++/Qt experience whatsoever
but I came up with the following patch and it has worked fairly well for me. I
must say however, that it appears to increment the PAM faillock count by 2
(this was already an issue for me even without the patches - though vanilla
klockscreen only increased the count by 1, so this underlying bug might be
caused due to klockscreen triggering a pam error or something). 

Note to KDE devs: I'm willing to help you fix this issue.

```
diff --git a/greeter/pamauthenticator.cpp b/greeter/pamauthenticator.cpp
index 077831d..d5b9963 100644
--- a/greeter/pamauthenticator.cpp
+++ b/greeter/pamauthenticator.cpp
@@ -132,6 +132,9 @@ int PamWorker::converse(int n, const struct pam_message
**msg, struct pam_respon
             // if there's only the info message, let's predict the prompts too
             const QString info = QString::fromLocal8Bit(msg[i]->msg);
             qCDebug(KSCREENLOCKER_GREET, "[PAM worker %s] Message: Info
message: %s", qUtf8Printable(c->m_service), qUtf8Printable(info));
+            // If fingerprint device sends info message, it's now available
+            c->m_unavailable = false;
+            Q_EMIT c->unavailabilityChanged(c->m_unavailable);
             Q_EMIT c->infoMessage(info);
             break;
         }
@@ -159,7 +162,7 @@ PamWorker::~PamWorker()

 void PamWorker::authenticate()
 {
-    if (m_inAuthenticate || m_unavailable) {
+    if (m_inAuthenticate) {
         return;
     }
     m_inAuthenticate = true;
@@ -177,6 +180,8 @@ void PamWorker::authenticate()
     if (rc == PAM_SUCCESS) {
         rc = pam_setcred(m_handle, PAM_REFRESH_CRED);
         /* ignore errors on refresh credentials. If this did not work we use
the old ones. */
+        m_unavailable = false;
+        Q_EMIT unavailabilityChanged(m_unavailable);
         Q_EMIT succeeded();
     } else if (rc == PAM_AUTHINFO_UNAVAIL || rc == PAM_MODULE_UNKNOWN) {
         m_unavailable = true;
@@ -309,7 +314,7 @@ bool PamAuthenticator::isBusy() const

 bool PamAuthenticator::isAvailable() const
 {
-    return m_inAuthentication && !m_unavailable;
+    return !m_unavailable;
 }

 PamAuthenticator::NoninteractiveAuthenticatorTypes
PamAuthenticator::authenticatorType() const
diff --git a/greeter/pamauthenticators.cpp b/greeter/pamauthenticators.cpp
index e9e925a..f1f6348 100644
--- a/greeter/pamauthenticators.cpp
+++ b/greeter/pamauthenticators.cpp
@@ -18,6 +18,7 @@ struct PamAuthenticators::Private {
     AuthenticatorsState state = AuthenticatorsState::Idle;
     bool graceLocked = false;
     bool hadPrompt = false;
+    bool interactiveCancelledByFingerprint = false;

     void recomputeNoninteractiveAuthenticationTypes()
     {
@@ -51,7 +52,11 @@
PamAuthenticators::PamAuthenticators(std::unique_ptr<PamAuthenticator>
&&interac
         qCDebug(KSCREENLOCKER_GREET) << "PamAuthenticators: Failure from
interactive authenticator" << qUtf8Printable(d->interactive->service());
         setState(AuthenticatorsState::Idle);
         d->cancelNoninteractive();
-        Q_EMIT failed(PamAuthenticator::NoninteractiveAuthenticatorType::None,
d->interactive.get());
+        // Don't emit failed if interactive was cancelled due to fingerprint
becoming available
+        if (!d->interactiveCancelledByFingerprint) {
+            Q_EMIT
failed(PamAuthenticator::NoninteractiveAuthenticatorType::None,
d->interactive.get());
+        }
+        d->interactiveCancelledByFingerprint = false;
     });
     connect(d->interactive.get(), &PamAuthenticator::loginFailedDelayStarted,
this, [this](const uint uSecDelay) noexcept -> void {
         qCDebug(KSCREENLOCKER_GREET) << "PamAuthenticators: Delay started on
login failure for interactive authenticator" <<
qUtf8Printable(d->interactive->service())
@@ -83,6 +88,8 @@
PamAuthenticators::PamAuthenticators(std::unique_ptr<PamAuthenticator>
&&interac
                 d->hadPrompt = true;
                 Q_EMIT hadPromptChanged();
             }
+            // Mark that interactive will be cancelled due to fingerprint
becoming available
+            d->interactiveCancelledByFingerprint = true;
             qCDebug(KSCREENLOCKER_GREET) << "PamAuthenticators: Info message
from non-interactive authenticator" <<
qUtf8Printable(noninteractive->service());
             Q_EMIT noninteractiveInfo(noninteractive->authenticatorType(),
noninteractive.get());
         });
```

-- 
You are receiving this mail because:
You are watching all bug changes.

Reply via email to