google / google-authenticator-libpam

Apache License 2.0
1.77k stars 281 forks source link

does google-authenticator-libpam provides method to verify TOTP to handle error scenarios #253

Open raviteja-b opened 1 month ago

raviteja-b commented 1 month ago

I have configured google-authenticator-libpam pam module on system and it works. to handle error or wrong secret key setup scenarios, we wanted to verify TOTP token during google authenticator secret key setup.

In our use-case, secret key displayed on WebGUI for users to setup TOTP authenticator app mobile device to generate TOTP, in any case if user missed configuring TOTP authenticator app on mobile then this use gets locked out. so we wanted make sure user has setup TOTP authenticator app on mobile and ask user to provide first TOTP generated as input to validate secret key setup.

does google-authenticator-libpam pam module provides any API like "check_timebased_code()" which can be consumed by applications(WebGUI) to validate OTP ??

ThomasHabets commented 1 month ago

You provision GA libpam secrets via a web gui?

No, aside from the API PAM uses, this code doesn't expose any API. Probably there are "pam test" projects somewhere that lets you execute the auth stack outside of the actual auth flow.

raviteja-b commented 1 month ago

You provision GA libpam secrets via a web gui?

No, aside from the API PAM uses, this code doesn't expose any API. Probably there are "pam test" projects somewhere that lets you execute the auth stack outside of the actual auth flow.

yeah, secret key generated for each user on system and display secret key & QR code on Web GUI for user to setup TOTP authenticator

raviteja-b commented 1 month ago

You provision GA libpam secrets via a web gui? No, aside from the API PAM uses, this code doesn't expose any API. Probably there are "pam test" projects somewhere that lets you execute the auth stack outside of the actual auth flow.

yeah, generate secret for each user, display secret key and QR code on GUI page.

does google-authenticator pam module support an API which can support verify TOTP and return success or failure similar to https://www.man7.org/linux/man-pages/man3/pam_authenticate.3.html

ThomasHabets commented 1 month ago

GA PAM module already exports the standard PAM module API. You should be able to use that, just like the login flow does.

raviteja-b commented 1 month ago

GA PAM module already exports the standard PAM module API. You should be able to use that, just like the login flow does.

yeah, standard PAM module API expects both password + TOTP again, that's reason i was looking for google-authenticator specific TOTP verify method. can you please consider exposing any new API to verify TOTP, so that any app which use this library can consume this API

ThomasHabets commented 1 month ago

Not sure what you mean. GA PAM module doesn't check the regular password. It has no ability to. Why is it that you can't call pam_sm_authenticate? That way it'd work against replays, work with HOTP, and ensure that the secret file was written correctly.

raviteja-b commented 1 month ago

Not sure what you mean. GA PAM module doesn't check the regular password. It has no ability to. Why is it that you can't call pam_sm_authenticate? That way it'd work against replays, work with HOTP, and ensure that the secret file was written correctly.

User already logged in and have a web session on system by the time user configure google-authenticator and setup secret key. During user secret key setup, we wanted to verify TOTP token against secret key setup for the user, I am looking for a PAM method which can just take TOTP and secret key input and validate given TOTP.

During session creation, we call pam_sm_authenticate with totp and it works. pam_sm_authenticate expects both password and TOTP token both to pass authentication. if we need to call pam_sm_authenticate() method just to verify totp then user needs to enter password again from web GUI

ThomasHabets commented 1 month ago

pam_sm_authenticate expects both password and TOTP token both to pass authentication.

Only if you use the options try_first_pass / use_first_pass / forward_pass, right?

if we need to call pam_sm_authenticate() method just to verify totp then user needs to enter password again from web GUI

Why?

raviteja-b commented 1 month ago

pam_sm_authenticate expects both password and TOTP token both to pass authentication.

Only if you use the options try_first_pass / use_first_pass / forward_pass, right?

yes that's right

if we need to call pam_sm_authenticate() method just to verify totp then user needs to enter password again from web GUI

Why?

pam_sm_authenticate() generally expects password with TOTP appended, if any one of these two parameters are wrong then it returns error

ThomasHabets commented 1 month ago

So, don't use those parameters when you verify the OTP?

raviteja-b commented 1 month ago

So, don't use those parameters when you verify the OTP?

password usually is not stored unless user passed while login.. so don't want to use password parameter while verifying TOTP

akerl commented 1 month ago

@raviteja-b You're missing the point.

PAM is a pluggable system for composing authentication flows. Google-authenticator-libpam is a module for PAM that implements TOTP validation.

The flow you're describing, where a user logs in with a password and then TOTP, is how you have configured the auth flow for sshd or login or whatever specific thing you're having users do. But that's just one configuration, and it's a PAM system configuration.

You can do a couple different things:

  1. Set up another PAM config that isn't sshd/login/etc, that uses TOTP but not password, and invoke that to validate TOTP
  2. Just call the function from this module directly, the same way that the PAM system flow does. This module only validates TOTP, not passwords, so you could just do that part.
  3. Write your own TOTP validation code. TOTP is a published standard, you can find or write a validator that takes a seed, a code, and the current timestamp. As @ThomasHabets as pointed out, if you wanted to be thorough, you'd need to somehow integrate that to make sure the validated code couldn't be replayed, which is something the module takes care of for you.
raviteja-b commented 1 month ago

@raviteja-b You're missing the point.

I understand your point, in our authentication flow also user passes both password and TOTP token while login, but before that during setup secret key we wanted to verify TOTP token to make sure user configured right secret key on their device..

PAM is a pluggable system for composing authentication flows. Google-authenticator-libpam is a module for PAM that implements TOTP validation.

The flow you're describing, where a user logs in with a password and then TOTP, is how you have configured the auth flow for sshd or login or whatever specific thing you're having users do. But that's just one configuration, and it's a PAM system configuration.

You can do a couple different things:

  1. Set up another PAM config that isn't sshd/login/etc, that uses TOTP but not password, and invoke that to validate TOTP
  2. Just call the function from this module directly, the same way that the PAM system flow does. This module only validates TOTP, not passwords, so you could just do that part.

which function you are referring here? looks like we can't use any method from google-authenticator pam module directly.

  1. Write your own TOTP validation code. TOTP is a published standard, you can find or write a validator that takes a seed, a code, and the current timestamp. As @ThomasHabets as pointed out, if you wanted to be thorough, you'd need to somehow integrate that to make sure the validated code couldn't be replayed, which is something the module takes care of for you.
ThomasHabets commented 1 month ago

I'm pretty sure calling pam_sm_authenticate() should work.

raviteja-b commented 1 month ago

I'm pretty sure calling pam_sm_authenticate() should work.

ok will try to use pam_sm_authenticate() thank you @ThomasHabets

raviteja-b commented 1 month ago

@ThomasHabets is there any google-authenticator pam module configuration option to bypass TOTP authentication for the specific user even though secret key setup done for that user ?? basically we wanted to support runtime TOTP authentication bypass user configuration. say there are multiple users configured with google TOTP authentication on the system, if specific user wants to disable TOTP authentication for that user, then what's recommended way to achieve this ?

ThomasHabets commented 1 month ago

@raviteja-b The closest thing is the nullok option. If the user deletes or renames their ~/.google_authenticator file, nullok means don't ask for OTP.

raviteja-b commented 1 month ago

@raviteja-b The closest thing is the nullok option. If the user deletes or renames their ~/.google_authenticator file, nullok means don't ask for OTP.

yes @ThomasHabets, I have configured auth required pam_google_authenticator.so forward_pass nullok When user's home directory has .google_authenticator file, it asks for OTP and when I remove google_authenticator file then it does not ask for OTP. I just wanted to understand if there is any other configuration option than removing or renaming file.

ThomasHabets commented 1 month ago

No other way, currently. Well written pull requests welcome. :-)

raviteja-b commented 1 month ago

I'm pretty sure calling pam_sm_authenticate() should work.

ok will try to use pam_sm_authenticate() thank you @ThomasHabets

@ThomasHabets pam_sm_authenticate() may work to validate just TOTP if I remove forward_pass auth required pam_google_authenticator.so forward_pass nullok but if I remove forward_pass, then all other users with TOTP secret key setup on that system will be able to login with TOTP even though user does not pass password right? we are enabling TOTP authentication to support two factor authentication for all users on the system

akerl commented 1 month ago

The fact that you're still talking about your system PAM config suggests you're still not understanding.

https://github.com/google/google-authenticator-libpam/blob/master/src/pam_google_authenticator.c#L2183 is the entrypoint in this codebase that the system PAM code calls. If you use that, or one of the underlying entrypoints, you can run all the code for TOTP checking, without ever interacting with passwords or system PAM configs.

raviteja-b commented 1 month ago

The fact that you're still talking about your system PAM config suggests you're still not understanding.

https://github.com/google/google-authenticator-libpam/blob/master/src/pam_google_authenticator.c#L2183 is the entrypoint in this codebase that the system PAM code calls. If you use that, or one of the underlying entrypoints, you can run all the code for TOTP checking, without ever interacting with passwords or system PAM configs.

ok, earlier I tried to use pam_authenticate() call which was working based on system PAM config. so I wanted to understand how does pam_sm_authenticate() works. Thank you @akerl