I found another way to do this that is more “proper” and also respects pam_faillock, which locks authentification for 10 minutes after 3 bad tries. The specific way I implemented it though gives you 10s to try fingerprint, and only after that elapses or it fails, gives you the option to use the password. You can use the password first, then fingerprint way, too, of course.
I also have some notes on unlocking with fingerprint in Plasma 5 vs Plasma 6, where they seem to have added native support for both, although it is quite scuffed IMO and needs fixing.
The main reason I investigated this is because I wasn’t happy with the often recommended way of adding the following:
auth sufficient pam_unix.so try_first_pass likeauth nullok
auth sufficient pam_fprintd.so
I used it before and it works, but it seems to a) skip the pam_faillock check so an attacker can try again and again without a 10min check, and b) I do not fully understand likeauth to determine if it is safe to use here.
So here’s my “proper” alternative:
Basic authentification for sudo
To start off, I copied `system-auth` to `system-auth-fprintf` as that is the file specifying the password-based authentification used by all other modules. I added the `pam_fprintd.so` line to run before `pam_unix.so` and edited the success parameters to account for the extra line. Now it looks like this (though I recommend starting with your distributions default):
-- cat system-auth-fprintf
#%PAM-1.0
auth required pam_faillock.so preauth
# Optionally use requisite above if you do not want to prompt for the password
# on locked accounts.
-auth [success=3 default=ignore] pam_systemd_home.so
auth [success=2 default=ignore] pam_fprintd.so max-tries=3 timeout=10
auth [success=1 default=bad] pam_unix.so try_first_pass nullok
auth [default=die] pam_faillock.so authfail
auth optional pam_permit.so
auth required pam_env.so
auth required pam_faillock.so authsucc
# Just to allow using this instead of system-auth for all types
account include system-auth
session include system-auth
Now with this, I can edit any other file to use this authentification on a granular level. E.g. sudo:
-- cat sudo
#%PAM-1.0
auth include system-auth-fprintd
account include system-auth
session include system-auth
And what it does is first ask for fingerprint, three tries (default), with a timeout of 10 seconds (minimum, sadly), and asks for password afterwards. Works wonderfully.
If you want to use the password-first way, this would be it:
-- cat system-auth-fprintf
#%PAM-1.0
auth required pam_faillock.so preauth
# Optionally use requisite above if you do not want to prompt for the password
# on locked accounts.
-auth [success=3 default=ignore] pam_systemd_home.so
auth [success=2 default=ignore] pam_unix.so try_first_pass nullok
auth [success=1 default=bad] pam_fprintd.so max-tries=3 timeout=10
auth [default=die] pam_faillock.so authfail
auth optional pam_permit.so
auth required pam_env.so
auth required pam_faillock.so authsucc
# Just to allow using this instead of system-auth for all types
account include system-auth
session include system-auth
Unlock in Plasma 5 / Other
Now we could apply the same to the unlock session (`kde`) and it would work similarly.
Make a copy of system-login
called system-login-fprintf
, because its auth types are used by both kde (unlocking, via system-local-login) and various others like sddm, login, etc (which should be password only for kwallet decryption).
-- cat system-login-fprintf
#%PAM-1.0
auth required pam_shells.so
auth requisite pam_nologin.so
auth include system-auth-fprintd
account include system-login
password include system-login
session include system-login
Then edit kde
as follows:
-- cat kde
#%PAM-1.0
auth include system-login-fprintd
account include system-local-login
password include system-local-login
session include system-local-login
Now I can use the fingerprint immediately without skipping the password explicitly first, and I can login with the password as well - unfortunately, it gives you exactly 10s to use the fingerprint, and only then allows you to unlock with a password. You can enter it before and hit enter, and it will unlock at exactly 10s (this is because of try_first_pass, it tries the password entered before pam_unix.so
itself even had control). Not optimal. If you used the password-first way, you need to press enter first, but this annoyance is not there if you do need to use the password. Your choice.
Plasma 6
As mentioned before, Plasma 6 seems to have an interesting new way to handle fingerprint unlocking, it seems to use both `kde` and `kde_fingerprint` (probably run in parallel).
However, as noted above, it has a serious issue where a successful fingerprint unlock still counts as a authfail to `pam_faillock.so`, so after three *successful* unlocks with the fingerprint, it denies you access for 10 mins anyway.
I after several tries I successfully modified `kde_fingerprint` to fix this behaviour:
-- cat kde_fingerprint
#%PAM-1.0
auth required pam_shells.so
auth requisite pam_nologin.so
auth requisite pam_faillock.so preauth
# Default behaviour
#-auth required pam_fprintd.so
#auth optional pam_permit.so
# Default behaviour (rewritten)
#auth [success=ok module_unknown=ignore ignore=ignore default=bad] pam_fprintd.so
#auth optional pam_permit.so
# Solution 1 (no faillock support)
#auth [success=ok ignore=ignore default=die] pam_fprintd.so max-tries=3 timeout=65535
#auth optional pam_permit.so
#auth required pam_faillock.so authsucc
# Solution 2 (faillock support)
auth [success=1 ignore=ignore module_unknown=die default=bad] pam_fprintd.so max-tries=3 timeout=65535
auth [default=die] pam_faillock.so authfail
auth optional pam_permit.so
auth required pam_faillock.so authsucc
auth required pam_env.so
account include system-local-login
password required pam_deny.so
session include system-local-login
This finally works as intended, and I can immediately unlock with both, without faillock incorrectly locking it after 3 tries.
I’ll likely submit this as a bug report to kde.
Explanation:
Timeout is disabled, necessary because it starts ticking down as soon as you trigger it, which is suboptimal. You can also set it lower and then catch it using authinfo_unavail - I considered adding authinfo_unavail=die to handle some failures to not trigger pam_faillock, but decided against it since I don’t know if you can exploit that.
Solution 1 skips pam_faillock entirely, e.g. if you fail 3 times, you rely on KDE to never show you the fingerprint again until you unlock - do check yourself if that can be exploited by e.g. going to sleep to give you infinite tries at unlocking with fingerprint without pam_faillock getting in your way.
Solution 2 is recommended and does use pam_faillock, though it still relies on other factors to prevent exploits, e.g. going to sleep needs to not reset the try counter, else you can bypass pam_faillock and try as much as you want.
Unfortunately, it’s not realistic to set max-tries to 1, since this kde implementation doesn’t retry at all, even with a pam_faillock authfail.
In the default KDE implementation, max-tries is “relied” upon to provide a faillock alternative. A proper implementation would retry kde-fingerprint as long as pam_faillock is properly used, and with max-tries=1, to provide a proper faillock.
System Auth:
Unfortunately, `system-auth` is not just used by other files, it's also used directly by e.g. changing system settings, or programs needing privileges temporarily. To allow fingerprint sensor usage there, but not in places where it's inapropriate, is difficult. I copied `system-auth` to `system-auth-pw` and redirected all `auth include system-auth` to that. Then, I modified `system-auth` to use fprint like before (e.g. by auth include `system-auth-fprintd`). Now I can use fingerprint for those as well (e.g. changing password, though interestingly not for adding more fingerprints). I'm not sure this is worth it and I might leave this password-only. Though, the security implications of typing in a password in public might outweigh the implications of a fingerprint here, anyway.