Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Feature] Support parallel unlocking with fingerprint and password #258

Closed
Jackaed opened this issue Apr 5, 2024 · 35 comments · Fixed by #514
Closed

[Feature] Support parallel unlocking with fingerprint and password #258

Jackaed opened this issue Apr 5, 2024 · 35 comments · Fixed by #514

Comments

@Jackaed
Copy link

Jackaed commented Apr 5, 2024

The only thing I've seen that supports this correctly so far is GDM, which runs 2 PAM sessions in parallel, one for fingerprint, one for password. This makes the whole "press enter to trigger the prompt" song and dance unnecessary.

I'm unsure of how this actually works in terms of implementation, but only that it is possible (since GDM can do it).

Would be very nice if Hyprlock could support it.

@PaideiaDilemma
Copy link
Collaborator

Running two pam conversations in parallel sound weird xD.

You could check out #205.
There is a guy who uses pam-fprint-grosshack to make it work.

@Jackaed
Copy link
Author

Jackaed commented Apr 7, 2024

pam-fprint-grosshack is called that for a reason - PAM is strictly a serial authentication mechanism.

The correct way of doing parallel authentication is through two PAM sessions.

@PaideiaDilemma
Copy link
Collaborator

PaideiaDilemma commented Apr 7, 2024

Idk if there is a correct way of doing parallel authentication xD
But you might be right that having two conversations is the better solution.

You could get two pam sessions by running a script together with hyprlock that then sends SIGUSR1 to unlock hyprlock I guess.

@discapes
Copy link

discapes commented Apr 21, 2024

presenting ~/.local/bin/mylock

#!/bin/sh
set -euo pipefail
(
until fprintd-verify -f right-ring-finger; do
    echo "Failed to verify fingerprint at $(date)" | systemd-cat
done
echo "Unlocked at $(date)" | systemd-cat
pkill -USR1 hyprlock
) &
exec hyprlock

Remember to remove the fprintd module from pam

@Jackaed
Copy link
Author

Jackaed commented Apr 21, 2024

This kinda works ish? It's pretty prone to causing just a dangling fprintd-verify, say if you authenticate with a password instead, which will make your fingerprint sensor unusable until you kill that task. I wouldn't reccomend it.

@discapes
Copy link

@Jackaed good observation, I don't really use fprintd for anything else 😄. To fix the dangling fprint-verify, remove the exec and add these two lines:

kill $(jobs -p)
pkill fprintd-verify

@Jackaed
Copy link
Author

Jackaed commented Apr 24, 2024

Oh I just realised, this code REALLY doesn't work, since fprintd-verify still returns on a no-match, just with different output.

@discapes
Copy link

That's why there's the until loop
https://linuxize.com/post/bash-until-loop/

@Jackaed
Copy link
Author

Jackaed commented Apr 24, 2024

No but that until loop still breaks if an incorrect finger is used, as fprint still returns with a non-zero exit code. You can fix it by adding | grep "verify-match" to the condition.

@discapes
Copy link

In bash, if the exit code is non-zero, it usually means a failure.
fprintd-verify also works like this and returns 0 for success, and 1 for failure.

❯ fprintd-verify -f right-ring-finger
Using device /net/reactivated/Fprint/Device/0
Listing enrolled fingers:
 - #0: right-ring-finger
Verify started!
Verifying: right-ring-finger
Verify result: verify-match (done)                                              /1.1s
❯ echo $?
0                                                                               /0.0s
❯ fprintd-verify -f right-ring-finger
Using device /net/reactivated/Fprint/Device/0
Listing enrolled fingers:
 - #0: right-ring-finger
Verify started!
Verifying: right-ring-finger
Verify result: verify-no-match (done)                                           /2.0s
❯ echo $?
1

The until loop works such that it runs the command until the exit code is 0.

@discapes
Copy link

You should've tested it

@Jackaed
Copy link
Author

Jackaed commented Apr 24, 2024

My fprintd doesn't behave this way - I get an exit code of 0 on a match or on a non-match. Not sure why this is different on my machine.

I'm on nixos with nixpkgs unstable, what OS are you running? In general doing it this way is still really inconsistent and behaves weirdly when interacting with things like sleep, so for anyone else reading this thread, I wouldn't recommend doing things this way.

@discapes
Copy link

Interesting if it behaves that way. I'm using fprintd-1.94.2-8.fc39.x86_64 from Fedora. Also, I'm aware the script is a bit of a hack and I'm not forcing anyone to use it. I still don't see any major problems though, since according to the rules of bash it is impossible to unlock the computer without fprintd-verify returning 0.

I'd like to know how it "behaves weirdly" with sleep, since usually sleeping is completely transparent to processes.

@niksingh710
Copy link

For me, the current issue is that if I type my password and press enter, it waits for my fingerprint to unlock.

Here is a sway lock implementation that fixes that
https://github.com/SL-RU/swaylock-fprintd

@Jackaed
Copy link
Author

Jackaed commented Apr 26, 2024

@discapes I think it's more or less working as intended now - I'm now using the script with the modifications for my distro (specifically adding the grep) and it seems to work fine with sleep.

In terms of not making it wait for fingerprint, if you're using the fprintd-verify script you can remove the fprint pam module and it should allow you to enter a password and have it work correctly, or let you use your fingerprint and have that work correctly.

I still think this should be implemented inside of hyprlock, as this still is a bit of a hack and requires a decent amount of setup, but for now this is fine.

@niksingh710
Copy link

@Jackaed can you share the method you are using or the script?

@Jackaed
Copy link
Author

Jackaed commented Apr 28, 2024

Currently using what I've modified from what @discapes sent

#!/bin/sh
set -euo pipefail
if [ -f /tmp/locked ] ; then exit ; fi
touch /tmp/locked
(
until fprintd-verify | grep "verify-match"; do
    echo "Failed to verify fingerprint at $(date)" | systemd-cat
done
echo "Unlocked at $(date)" | systemd-cat
pkill -USR1 hyprlock
) &
hyprlock
rm /tmp/locked
kill $(jobs -p)
pkill fprintd-verify

The /tmp/locked stuff is just to ensure that you don't end up with multiple instances of hyprlock going at a given time. Use this at your own risk, I'm not responsible for anything that happens as this being potentially insecure - although I'm comfortable enough with it to use it myself.

@niksingh710
Copy link

@Jackaed for me pkill -USR1 hyprlock is never getting executed i even tried it with grep verify-no-match to check if it unlocks even if the fingerprint is not verifying but no luck.
only getting it unlocked by password input.

@Jackaed
Copy link
Author

Jackaed commented May 11, 2024

sorry this is impossible for me to debug when it's not my own system. make sure that pkill works as intended and that your fprintd-verify gives the output required.

@b4shful
Copy link

b4shful commented Aug 11, 2024

Came across this issue and wanted to ask if the situation has changed at all? I've been using pam-fprint-grosshack and it's not all that reliable (sometimes it works, sometimes I have to press enter and then wait for JUST the right amount of time (but not too early, or not too late?!?!).

@winkelnp
Copy link

winkelnp commented Aug 19, 2024

I found a workaround that seems to work for me on the equivalent swaylock issue: swaywm/swaylock#61 (comment)

you essentially add

auth    sufficient      pam_unix.so       try_first_pass likeauth nullok
auth    sufficient      pam_fprintd.so

to the top of your /etc/pam.d/hyprlock file
I'm not sure if this adds any security issues, but it works a charm for me so far… (you do however need to disable ignore-empty-input in your hyprlock.conf and entering a wrong password just fails silently)

@baykalokandemir
Copy link

I found a workaround that seems to work for me on the equivalent swaylock issue: swaywm/swaylock#61 (comment)

you essentially add

auth    sufficient      pam_unix.so       try_first_pass likeauth nullok
auth    sufficient      pam_fprintd.so

to the top of your /etc/pam.d/hyprlock file I'm not sure if this adds any security issues, but it works a charm for me so far… (you do however need to disable ignore-empty-input in your hyprlock.conf and entering a wrong password just fails silently)

This seems to work, ish? Unless i enter a wrong password in advance, i can't seem to trigger it to unlock. Works fine after wrong password though.

@winkelnp
Copy link

I found a workaround that seems to work for me on the equivalent swaylock issue: swaywm/swaylock#61 (comment)
you essentially add

auth    sufficient      pam_unix.so       try_first_pass likeauth nullok
auth    sufficient      pam_fprintd.so

to the top of your /etc/pam.d/hyprlock file I'm not sure if this adds any security issues, but it works a charm for me so far… (you do however need to disable ignore-empty-input in your hyprlock.conf and entering a wrong password just fails silently)

This seems to work, ish? Unless i enter a wrong password in advance, i can't seem to trigger it to unlock. Works fine after wrong password though.

You still need to press enter (on empty input) to trigger pam

@Jackaed
Copy link
Author

Jackaed commented Aug 29, 2024

You can do that correctly strictly with PAM, which is fine - but having a parallel mechanism would be far superior if it can be implemented.

@b4shful
Copy link

b4shful commented Aug 29, 2024

@Jackaed yeah for sure - also I have a feeling that pam-fprint-grosshack may have grossed its last hack - or maybe not, but it did stop working completely on me today (some dbus error, could be a me problem, but pam_fprintd works fine). So it's definitely overdue.

@enesbala5
Copy link

I am new to the Linux space - is this really that difficult to implement to Hyprlock directly?

Why should the user have to configure something like this - which is basic UX. Half the time my fingerprint doesn't work. This is not a small "annoyance". It's actually unusable right now.

@PaideiaDilemma
Copy link
Collaborator

Fprintd provides a dbus API, which could be used by hyprlock. That would probably work a lot better than the pam module.

Besides dbus, AFAIK there are quite a few hassles implementing it.

But yeah fingerprint support on linux is bad. I think it can be blamed on PAM and windows only fp devices. The fp sensor on my laptop does not have a working fprint driver, so I will likely not dive into this.

@enesbala5
Copy link

Is there any alternative right now to Hyprlock - which can be used along Hyprland - that doesn't have this problem?

@fiskhest
Copy link

Is there any alternative right now to Hyprlock - which can be used along Hyprland - that doesn't have this problem?

If I understand the question correctly, https://github.com/SL-RU/swaylock-fprintd

@enesbala5
Copy link

Is there any alternative right now to Hyprlock - which can be used along Hyprland - that doesn't have this problem?

If I understand the question correctly, https://github.com/SL-RU/swaylock-fprintd

Thank you for the response. I am on NixOS right now - so maybe will try this later.

At this point I'm willing to remove the lock screen all together. I'd rather that than have my laptop "freeze" anytime I try unlocking it.

@FearlessSpiff
Copy link

Currently using what I've modified from what @discapes sent

#!/bin/sh
set -euo pipefail
if [ -f /tmp/locked ] ; then exit ; fi
touch /tmp/locked
(
until fprintd-verify | grep "verify-match"; do
    echo "Failed to verify fingerprint at $(date)" | systemd-cat
done
echo "Unlocked at $(date)" | systemd-cat
pkill -USR1 hyprlock
) &
hyprlock
rm /tmp/locked
kill $(jobs -p)
pkill fprintd-verify

The /tmp/locked stuff is just to ensure that you don't end up with multiple instances of hyprlock going at a given time. Use this at your own risk, I'm not responsible for anything that happens as this being potentially insecure - although I'm comfortable enough with it to use it myself.

I am just reading this but have no way to test it yet. What happens when you unlock by password? This will then just run until the next lock? And thus you need the lock file? I might not understand it correctly. :D

@el-Basketo
Copy link

el-Basketo commented Sep 27, 2024

I think I got password + fingerprint parallel unlocking to work without needing to modify Hyprlock.

The idea is so simple that I don't know if it is genius or if it introduces major security flaws... Please tell me what you think of it.

The idea is... Just add this widget to your hyprlock.conf!

# parallel check of fingerprint
# will not generate any visuals on the lock screen
label {
    text = cmd[update:0:0] until fprintd-verify -f right-index-finger; do :; done; pkill -USR1 hyprlock
}

Inspired by the above shell script by discapes #258 (comment), and the rest of this conversation.

This feels like a cleaner way to do it with our current means, please correct me if I'm completely going off the rails...

Also removes the need for spaghetti checks like #258 (comment)
(no offense, as we say in engineering, the best part is not part)

An improvement would be to leverage the SIGUSR2 capabilities of hyprlock to display feedback from the fprint-verify command. I have a couple ideas on how to do it (replacing the noop : with useful commands), but I need that sanity check before jumping in :P

EDIT 1: cmd[update:0:1] --> cmd[update:0:0], duh...

EDIT 2: PS: the only thing that bugs me with this approach, is that fprintd-verify is slower than when fprint is called the normal way, from a pam module. At least this is the case with my reader.

EDIT 3: This method does create orphan sh processes if the screen is unlocked via password. I thought all of hyprlock's children would die when it exits, including the until? I do need help for killing the stray processes.

EDIT 4: During my testing, I managed to get hyprlock to freeze. It wouldn't respond to USR1, nor react to keypresses. The cause is unknown thus far. I manually killed it, and got to discover the wholesomely derpy "Oopsie daisy" screen, nice one xD

@PaideiaDilemma
Copy link
Collaborator

If anybody has time, please go and test @moggiesir's MR (#514).

@b4shful
Copy link

b4shful commented Oct 22, 2024

amazing work from @moggiesir - very excited to have this added and get rid of the workarounds 💖💗

Some guidance on migrating

Remove old stuff from the pam config file

The new version (0.5.0) of Hyprlock adds parallel authentication, and there is no longer any need for pam_fprintd or pam-fprint-grosshack

Many users are using various workarounds (see the above comments on this issue), so you might have /etc/pam.d/hyprlock files something like:

Examples of the old workarounds

(Collapsed for readability, click headings to expand)

pam_fprintd (installed with fprintd)

/etc/pam.d/hyprlock

# PAM configuration file for hyprlock
# the 'login' configuration file (see /etc/pam.d/login)
auth	sufficient	pam_unix.so	try_first_pass likeauth nullok
auth	sufficient	pam_fprintd.so
auth	include 	login
pam-fprint-grosshack

(Source)

/etc/pam.d/hyprlock

# PAM configuration file for hyprlock
# the 'login' configuration file (see /etc/pam.d/login)
auth	sufficient	pam_fprintd_grosshack.so
auth	sufficient	pam_unix.so try_first_pass nullok
auth	include 	login

Default hyprlock pam file (you can revert to this after upgrading to 0.5.0)

With this new parallel auth support, you can go back to using the default pam file.

hyprlock default pam file

/etc/pam.d/hyprlock

# PAM configuration file for hyprlock
# the 'login' configuration file (see /etc/pam.d/login)

auth        include     login

Configure hyprlock

You will also need to configure Hyprlock to enable fingerprint support (it is disabled by default).
The new update adds three config settings to hyprlock.conf:

image

For more information, see the Hyprlock wiki page.

Note: you might need to wait some time for Hyprlock to be updated in your distro's repositories before you can get the new version

@Jackaed
Copy link
Author

Jackaed commented Oct 22, 2024

Thanks guys! This works incredibly well. Very glad that this has been implemented, this is now by far the best locking utility on linux.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.