NixOS / nixpkgs

Nix Packages collection & NixOS
MIT License
17.09k stars 13.39k forks source link

Enabling `fprintd` prevents authentication with password in graphical applications #171136

Open skeleten opened 2 years ago

skeleten commented 2 years ago

Describe the bug

When enabling fprint using the services.fprintd.enable option results in graphical applications, in particular GDM and the KDE Lockscreen only prompting for a fingerprint and no longer being able to login with the password.

Steps To Reproduce

Steps to reproduce the behavior:

  1. Enable fprint and enroll a fingerprint
  2. Try logging in with password in GDM

Expected behavior

Login using a password (using the pam_unix module) should still be accepted

Additional context

The root cause of this issue seems to be the order of modules in the generated PAM configuration files. Currently it puts the fprint module before the pam_unix module when the other way around would be more sensible. I currently get the following within my PAM config files (e.g. /etc/pam.d/login

# Authentication management.
auth sufficient /nix/store/qxm4vwif9dfry30q3x7lhvhkm0klz4n5-fprintd-1.92.0/lib/security/pam_fprintd.so
auth sufficient pam_unix.so nullok  likeauth try_first_pass
auth required pam_deny.so

# ...

A more sensible ordering would be like this

# Authentication management.
auth sufficient pam_unix.so nullok  likeauth try_first_pass
auth sufficient /nix/store/qxm4vwif9dfry30q3x7lhvhkm0klz4n5-fprintd-1.92.0/lib/security/pam_fprintd.so
auth required pam_deny.so

This is also documented on the Arch-Wiki

Notify maintainers

No maintainers are listed in the nixos/modules/security/pam.nix module

Metadata

Please run nix-shell -p nix-info --run "nix-info -m" and paste the result.

I am using the nixos-21.11 channel.

symphorien commented 2 years ago

I don't know for GDM, but lightdm and xfce-screensaver have in common that after you fail authenticating with the fingerprint reader, they accept a password. Doesn't that work for you?

skeleten commented 2 years ago

I am afraid not, The KDE Lockscreen will simply claim a failure to authenticate

symphorien commented 2 years ago

That sounds like a bug in the kde lockscreen imo. Could you open an issue upstream? Such a solution would not require regressing user experience for all other users like the solution in #171140

emmettbutler commented 2 years ago

I experience the same issue with fprintd enabled under GDM. Opened a ticket on GDM's bug tracker https://gitlab.gnome.org/GNOME/gdm/-/issues/804#note_1535112.

skeleten commented 2 years ago

That sounds like a bug in the kde lockscreen imo. Could you open an issue upstream? Such a solution would not require regressing user experience for all other users like the solution in #171140

The proposed changes would alter the behaviour of PAM to require first a failed fingerprint authentication before proceeding to password authentication instead of vice versa. Since this is quite a change in behaviour, I agree that my proposed changes in #171140 would indeed be a regression that should not be merged carelessly

symphorien commented 2 years ago

Current behavior I have with the xfce lock screen is:

jbhardman commented 1 year ago

Same issue on GDM. Password entry is not allowed at any point. If fingerprint fails, or someone else is trying, they can't get in.

nixos-discourse commented 1 year ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/fingerprint-reader-with-gnome/23422/8

Hermitter commented 1 year ago

I'm also having the same issue for first time logins. Subsequent logins accept my password and work, but they have long delays that wait until a "verification time out" message shows up.

arbv commented 1 year ago

Yeah, that causing issues for me as well.

arbv commented 1 year ago

Oh, I seem to have found a solution (at least, for GDM). Here is the main bit:

security.pam.services.login.fprintAuth = false; # See "/etc/pam.d" if you want to disable fingerprinting for more stuff in a similar way
security.pam.services.gdm-fingerprint.fprintAuth = true; # "/etc/pam.d/gdm-fingerprint" is  not created by default

Personally, I have disabled fingerprinting for 'sudo', 'su' and a lot more stuff. IMO, fingerprinting should be disabled by default for most of the services, not enabled, in order to not confuse people.

arbv commented 1 year ago

Aaand I have found even better solution, as the one above does not allow me to log-in into the account with fingerprinting sensor (but does allow to unlock). We need to write a proper configuration for /etc/pam.d/gdm-fingerprint case. So:

security.pam.services.login.fprintAuth = false;
# similarly to how other distributions handle the fingerprinting login
security.pam.services.gdm-fingerprint = lib.mkIf (config.services.fprintd.enable) {
      text = ''
        auth       required                    pam_shells.so
        auth       requisite                   pam_nologin.so
        auth       requisite                   pam_faillock.so      preauth
        auth       required                    ${pkgs.fprintd}/lib/security/pam_fprintd.so
        auth       optional                    pam_permit.so
        auth       required                    pam_env.so
        auth       [success=ok default=1]      ${pkgs.gnome.gdm}/lib/security/pam_gdm.so
        auth       optional                    ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so

        account    include                     login

        password   required                    pam_deny.so

        session    include                     login
        session    optional                    ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start
      '';
    };
};

Hopefully, that will help somebody.

emmettbutler commented 1 year ago

@arbv That config makes my auth experience a lot nicer (commit)! The long timeout on fingerprint reading and password checking is gone now. I'm using GDM. Thanks!

arbv commented 1 year ago

@arbv That config makes my auth experience a lot nicer (commit)! The long timeout on fingerprint reading and password checking is gone now. I'm using GDM. Thanks!

You are welcome! You may also want to disable fingerprinting for polkit-1, too (so that GUI apps asking for permission elevation would ask you for a password too).

mkohler commented 1 year ago

Hopefully, that will help somebody

Yes, that is a huge improvement for me on GDM on a Framework 13. Even though this is getting out of scope of the original issue, I'll mention what your PAM configuration fixes for me in case others end up here with the same problems.

Prior to using the PAM configuration above, I was seeing these issues:

.gnome-shell-wr[3080]: Fingerprint service failed almost immediately, considering it unavailable.
.gnome-shell-wr[3080]: Please fix your configuration by running: authselect select --force sssd with-fingerprint with-silent-lastlog

With the PAM configuration @arbv posted, I get appropriate text prompts in GDM and the message "Failed to match fingerprint" shakes back-and-forth immediately if it fails to match. And if it does match, then login is immediate.

arbv commented 1 year ago

@mkohler Glad to hear that it helped you and thank you for your thorough investigation. I looked up these things on Arch and replicated the configuration as closely as I could.

In my opinion, fingerprinting auth support in NixOS is done in the most mindless way possible: basically it is implemented in the same generic way as other auth methods without giving a thought if it applies in this case or not. I can understand why it is this way, but the whole situation is still frustrating.

panda2134 commented 1 year ago

Aaand I have found even better solution, as the one above does not allow me to log-in into the account with fingerprinting sensor (but does allow to unlock). We need to write a proper configuration for /etc/pam.d/gdm-fingerprint case. So:

security.pam.services.login.fprintAuth = false;
# similarly to how other distributions handle the fingerprinting login
security.pam.services.gdm-fingerprint = lib.mkIf (config.services.fprintd.enable) {
      text = ''
        auth       required                    pam_shells.so
        auth       requisite                   pam_nologin.so
        auth       requisite                   pam_faillock.so      preauth
        auth       required                    ${pkgs.fprintd}/lib/security/pam_fprintd.so
        auth       optional                    pam_permit.so
        auth       required                    pam_env.so
        auth       [success=ok default=1]      ${pkgs.gnome.gdm}/lib/security/pam_gdm.so
        auth       optional                    ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so

        account    include                     login

        password   required                    pam_deny.so

        session    include                     login
        session    optional                    ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start
      '';
    };
};

Hopefully, that will help somebody.

This is awesome. Can you PR these code into nixpkgs?

nyabinary commented 12 months ago

Yeah please do!

nixos-discourse commented 9 months ago

This issue has been mentioned on NixOS Discourse. There might be relevant details there:

https://discourse.nixos.org/t/fingerprint-auth-gnome-gdm-wont-allow-typing-password/35295/2

tlvince commented 7 months ago

Does anyone hit the following in GNOME after logging in with fingerprint with the above workaround?

The login keyring did not get unlocked when you logged into your computer.

dawidd6 commented 7 months ago

Yes. That is because login keyring is encrypted with your user password by default. Logging in with fingerprint does not involve any password in the process and the keyring does not get automatically unlocked because of that. There is an insecure way of "fixing" that by setting the login keyring password to an empty value, which causes it to be stored unencrypted on disk. I wouldn't advise on doing that though. Concluding, Linux desktop does not seem to be well equipped for fingerprint login at the moment without compromising security and without any password involved. Please do correct me if I'm wrong 😄.

bashfulrobot commented 5 months ago

Aaand I have found even better solution, as the one above does not allow me to log-in into the account with fingerprinting sensor (but does allow to unlock). We need to write a proper configuration for /etc/pam.d/gdm-fingerprint case. So:

security.pam.services.login.fprintAuth = false;
# similarly to how other distributions handle the fingerprinting login
security.pam.services.gdm-fingerprint = lib.mkIf (config.services.fprintd.enable) {
      text = ''
        auth       required                    pam_shells.so
        auth       requisite                   pam_nologin.so
        auth       requisite                   pam_faillock.so      preauth
        auth       required                    ${pkgs.fprintd}/lib/security/pam_fprintd.so
        auth       optional                    pam_permit.so
        auth       required                    pam_env.so
        auth       [success=ok default=1]      ${pkgs.gnome.gdm}/lib/security/pam_gdm.so
        auth       optional                    ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so

        account    include                     login

        password   required                    pam_deny.so

        session    include                     login
        session    optional                    ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start
      '';
    };
};

Hopefully, that will help somebody.

This is awesome. Can you PR these code into nixpkgs?

@panda2134 / @arbv Is this still working for you? It was for me up until a few days ago.

Thank you.

Is this still working for you? It was for me up until a few days ago.

Thank you.

alyraffauf commented 5 months ago

Hi, still experiencing this bug on nixos-unstable (24.05) and the fix @arbv provided made everything work as expected for me.

 - system: `"x86_64-linux"`
 - host os: `Linux 6.8.0, NixOS, 24.05 (Uakari), 24.05.20240312.0ad13a6`
 - multi-user?: `yes`
 - sandbox: `yes`
 - version: `nix-env (Nix) 2.18.1`
 - nixpkgs: `/nix/store/k5l01g2zwhysjyl5zjvg5zxnj0lyxpp1-source`
panda2134 commented 5 months ago

Aaand I have found even better solution, as the one above does not allow me to log-in into the account with fingerprinting sensor (but does allow to unlock). We need to write a proper configuration for /etc/pam.d/gdm-fingerprint case. So:

security.pam.services.login.fprintAuth = false;
# similarly to how other distributions handle the fingerprinting login
security.pam.services.gdm-fingerprint = lib.mkIf (config.services.fprintd.enable) {
      text = ''
        auth       required                    pam_shells.so
        auth       requisite                   pam_nologin.so
        auth       requisite                   pam_faillock.so      preauth
        auth       required                    ${pkgs.fprintd}/lib/security/pam_fprintd.so
        auth       optional                    pam_permit.so
        auth       required                    pam_env.so
        auth       [success=ok default=1]      ${pkgs.gnome.gdm}/lib/security/pam_gdm.so
        auth       optional                    ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so

        account    include                     login

        password   required                    pam_deny.so

        session    include                     login
        session    optional                    ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start
      '';
    };
};

Hopefully, that will help somebody.

This is awesome. Can you PR these code into nixpkgs?

@panda2134 / @arbv Is this still working for you? It was for me up until a few days ago.

Thank you.

Is this still working for you? It was for me up until a few days ago.

Thank you.

Yeah it's still working as it did before.

arbv commented 5 months ago

@panda2134 Yes, the fix is still working for me.

Svenum commented 4 months ago

Any news for KDE + SDDM?

nyabinary commented 4 months ago

Hopefully, that will help somebody

Yes, that is a huge improvement for me on GDM on a Framework 13. Even though this is getting out of scope of the original issue, I'll mention what your PAM configuration fixes for me in case others end up here with the same problems.

Prior to using the PAM configuration above, I was seeing these issues:

* no feedback from fingerprint reader until a successful match happens and login starts

* I would _always_ get a failed fingerprint message on the gnome login screen before I could login successfully

* Once I got a successful fingerprint reading, it would take ~20s to login. I think this behavior started with NixOS 23.05 but I never figured out what caused it.

* The following messages in the logs `journalctl _UID=1000`
.gnome-shell-wr[3080]: Fingerprint service failed almost immediately, considering it unavailable.
.gnome-shell-wr[3080]: Please fix your configuration by running: authselect select --force sssd with-fingerprint with-silent-lastlog

With the PAM configuration @arbv posted, I get appropriate text prompts in GDM and the message "Failed to match fingerprint" shakes back-and-forth immediately if it fails to match. And if it does match, then login is immediate.

Exactly same issue here :3 Someone should continue #282322 work.

TheRealGramdalf commented 4 months ago

Aaand I have found even better solution, as the one above does not allow me to log-in into the account with fingerprinting sensor (but does allow to unlock). We need to write a proper configuration for /etc/pam.d/gdm-fingerprint case. So:

security.pam.services.login.fprintAuth = false;
# similarly to how other distributions handle the fingerprinting login
security.pam.services.gdm-fingerprint = lib.mkIf (config.services.fprintd.enable) {
      text = ''
        auth       required                    pam_shells.so
        auth       requisite                   pam_nologin.so
        auth       requisite                   pam_faillock.so      preauth
        auth       required                    ${pkgs.fprintd}/lib/security/pam_fprintd.so
        auth       optional                    pam_permit.so
        auth       required                    pam_env.so
        auth       [success=ok default=1]      ${pkgs.gnome.gdm}/lib/security/pam_gdm.so
        auth       optional                    ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so

        account    include                     login

        password   required                    pam_deny.so

        session    include                     login
        session    optional                    ${pkgs.gnome.gnome-keyring}/lib/security/pam_gnome_keyring.so auto_start
      '';
    };
};

Hopefully, that will help somebody.

Is there any chance you would be willing to write a configuration for sddm? It seems like you're already familiar with pam (at least more than I am, anyhow).

The relevant archwiki page is here, but I'm not quite sure what to do exactly - with my current NixOS configuration, the contents of /etc/pam.d/sddm are:

auth      substack      login
account   include       login
password  substack      login
session   include       login

and /etc/pam.d/login is:

# Account management.
account required pam_unix.so # unix (order 10900)

# Authentication management.
auth sufficient /nix/store/sw7kvbgpx58dmqnimqwbv3gw6zjdlgnp-fprintd-1.94.2/lib/security/pam_fprintd.so # fprintd (order 11300)
auth sufficient pam_unix.so likeauth nullok try_first_pass # unix (order 11500)
auth required pam_deny.so # deny (order 12300)

# Password management.
password sufficient pam_unix.so nullok yescrypt # unix (order 10200)

# Session management.
session required pam_env.so conffile=/etc/pam/environment readenv=0 # env (order 10100)
session required pam_unix.so # unix (order 10200)
session required pam_loginuid.so # loginuid (order 10300)
session required /nix/store/k491acz8rcfhrpivv0rg6q83a14zss2j-linux-pam-1.6.0/lib/security/pam_lastlog.so silent # lastlog (order 10700)
session optional /nix/store/4npvfi1zh3igsgglxqzwg0w7m2h7sr9b-systemd-255.4/lib/security/pam_systemd.so # systemd (order 12000)

This is with fprintd enabled, and it currently does some weird stuff - from what I can tell I need to enter my password, hit enter, and then fingerprint works...? Not sure what's going on there.

yajo commented 2 months ago

I found a workaround: use an unauthorized finger. This way, fingerprint auth fails and you can quickly fall back to password. It's nice for initial login, where otherwise you hit https://github.com/NixOS/nixpkgs/issues/136286#issuecomment-923881841. For the rest of fingerprint usages (sudo, go back after GNOME gets locked while you were away for some minutes), I can keep using the authorized finger.

fzakaria commented 2 months ago

I blindly copied @arbv pam config and surprised how well it works.

I also have this module to turn off fprintd when laptop lid is closed and docked to a monitor. https://github.com/fzakaria/nix-home/blob/framework-laptop/modules/nixos/fprint-laptop-lid.nix

I was tired of sudo asking for fingerprint permissions.

@arbv is there a more "correct" way to do that?

arbv commented 2 months ago

I blindly copied @arbv pam config and surprised how well it works.

I also have this module to turn off fprintd when laptop lid is closed and docked to a monitor. https://github.com/fzakaria/nix-home/blob/framework-laptop/modules/nixos/fprint-laptop-lid.nix

I was tired of sudo asking for fingerprint permissions.

@arbv is there a more "correct" way to do that?

I have no idea, TBH. What I did is recreated the configuration from arch while I still had it on my machine.