[GUIDE/SOLVED] Sudo and Login with Fingerprint Reader under KDE/Arch Linux

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.
6 Likes