Skip to content

pam: add optional fingerprint authentication#445

Open
rjarry wants to merge 2 commits intoswaywm:masterfrom
rjarry:pam_fprintd
Open

pam: add optional fingerprint authentication#445
rjarry wants to merge 2 commits intoswaywm:masterfrom
rjarry:pam_fprintd

Conversation

@rjarry
Copy link
Copy Markdown

@rjarry rjarry commented Jan 10, 2026

Allow unlocking the screen with a fingerprint reader via pam_fprintd. When enabled with -p/--fingerprint, a child process is spawned that runs in parallel with normal password authentication. Users can unlock with either method, whichever succeeds first.

The fingerprint child blocks on pam_authenticate() using a dedicated swaylock-fingerprint PAM service. On success, it notifies the parent via a pipe. On failure, it retries until a valid fingerprint is detected. The child terminates automatically when the parent exits.

This achieves the same feature than #283 but without any additional dependencies.

@rjarry rjarry force-pushed the pam_fprintd branch 4 times, most recently from ccca3b7 to bfdf45d Compare January 10, 2026 11:38
@rjarry rjarry force-pushed the pam_fprintd branch 2 times, most recently from f1b1f12 to f671322 Compare March 8, 2026 16:28
@hboetes
Copy link
Copy Markdown

hboetes commented Mar 13, 2026

Nice PR. I accidentally happen to maintain a fork of a fork of fork of a fork of this project, which also has a fingerprint scanner, including support for fingerprint scanners which shut down after some time. Perhaps you'd like to take a peek?

https://github.com/hboetes/swaylock-effects

@rjarry
Copy link
Copy Markdown
Author

rjarry commented Mar 13, 2026

Hi @hboetes, thanks for the link. I will have a look.

I wonder, why not contribute your security fixes and quality of life improvements to the original project?

I guess some eye candy things aren't essential and would go against the minimalist nature of sway{,lock}. But security issues should be reported and fixed.

@emersion
Copy link
Copy Markdown
Member

Is there no way to run pam_fprintd in such a way that it runs normal login authentication alongside fprintd?

@rjarry
Copy link
Copy Markdown
Author

rjarry commented Mar 14, 2026

Unfortunately, no. In order to talk to fprintd, you need to start a PAM challenge. In order to avoid any DBUS dependency, I resorted to a separate blocking PAM conversation with only pam_fprintd.so and that sends an "empty" password.

@hboetes
Copy link
Copy Markdown

hboetes commented Mar 14, 2026

Hi @hboetes, thanks for the link. I will have a look.

I wonder, why not contribute your security fixes and quality of life improvements to the original project?

I guess some eye candy things aren't essential and would go against the minimalist nature of sway{,lock}. But security issues should be reported and fixed.

Because I have been using swaylock-effects for ages. I was wondering if the fingerprint scanner code might be useful for the original project, searched around and found your PR, didn't want to rain on your parade, but rather add to it, assuming you might find useful bits in it.

I am not aware where the security problems @ink-splatters and I found and came from, just that they existed in the swaylock-effects code.

@rjarry
Copy link
Copy Markdown
Author

rjarry commented Mar 14, 2026

I was wondering if the fingerprint scanner code might be useful for the original project, searched around and found your PR, didn't want to rain on your parade, but rather add to it, assuming you might find useful bits in it.

Thanks for shining in 👍

I had a quick look at your implementation. It is quite well integrated with actual GUI feedback but unfortunately requires additional libdbus and glib dependencies which swaylock does not have at the moment.

I remember @emersion saying that he preferred to keep the dependencies as lean as possible in #283 which led me to add this PR.

@emersion
Copy link
Copy Markdown
Member

Unfortunately, no. In order to talk to fprintd, you need to start a PAM challenge. In order to avoid any DBUS dependency, I resorted to a separate blocking PAM conversation with only pam_fprintd.so and that sends an "empty" password.

What I mean is that a PAM backend can do all of this dance?

Replace the custom get_pam_auth_error() function with the standard
pam_strerror() call. This provides accurate, localized error messages
from PAM itself rather than a limited set of hardcoded strings.

Signed-off-by: Robin Jarry <robin@jarry.cc>
@rjarry
Copy link
Copy Markdown
Author

rjarry commented Mar 23, 2026

Hey Simon,

I had looked into this and unfortunately a single PAM service with both pam_fprintd.so and pam_unix.so does not work because auth modules run sequentially. Whichever module comes first in the stack blocks waiting for its input (fingerprint scan or password typing), preventing the next one from running until it either succeeds, times out or fails.

To have both methods available simultaneously, you would need to talk to fprintd directly over D-Bus to start and cancel verify operations, which would add libdbus/libglib dependencies. The separate child process with its own PAM conversation avoids that while still allowing both methods to race in parallel.

Let me know if you have another idea I might have missed.

Add optional fingerprint authentication via pam_fprintd. When enabled
with the -p/--fingerprint option, swaylock spawns a child process that
runs a separate PAM conversation using the swaylock-fingerprint service.

The PAM service is configured with max-tries=-1 and timeout=-1 so that
pam_fprintd handles retries internally and the child stays in a single
pam_authenticate() call. If the user sets finite values, swaylock starts
a fresh PAM session when pam_authenticate returns.

Messages from pam_fprintd (finger placement prompts, match failures)
are forwarded to the parent via a pipe and displayed in the indicator
text box. Failed fingerprint attempts do not increment the failed
password counter.

If the conversation function is never called (missing PAM service file
or unavailable device), the child retries with a 1 second delay and
gives up after 3 consecutive failures, displaying a diagnostic message
in the indicator. The child is automatically terminated when the parent
exits via prctl(PR_SET_PDEATHSIG).

Signed-off-by: Robin Jarry <robin@jarry.cc>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Development

Successfully merging this pull request may close these issues.

3 participants