Authenticate with PAM

I want to authenticate by PAM (so that i can use Google Authenticator) so i followed instructions on https://minecraft.codeemo.com/mineoswiki/index.php?title=Using_PAM

The instructions don’t mention what file to use in /etc/pam.d
I was guessing mineos but it doesn’t seem to work!?

Which file for the PAM instructions i have to use/change?

What do you mean by this?

As far as I’ve been able to tell, there aren’t any additional steps required above and beyond ensuring that pam-authenticate builds in NPM, which then is automatically used (first auth attempted).

I suppose it works, i have been revising the code in auth.js, but the benefit of PAM is that you can configure it by the files in /etc/pam.d/

Almost every service has its config file in there and if you put in the corresponding config file like:
auth requisite pam_google_authenticator.so forward_pass auth required pam_unix.so use_first_pass

then you will have two-factor authentication with Google authenticator. Its just the configurability of PAM.

I tried changing auth.js but it doesn’t seem to work either :frowning:
pam.authenticate(user, plaintext, function(err) { if (err) inner_callback(false); else inner_callback(user); }, {serviceName: 'mineos', remoteHost: 'localhost'});

Maybe the error isn’t in PAM but in the auth.js. With the above code i expect that PAM revokes me if i do not enter the 6-digit Google authenticator code and just enter my password.
But i guess the if then else construction then let’s me pass to the next step (shadow password):
pam(function(pam_passed) { //due to the stack of different auths, a false if auth failed is largely ig$ if (typeof pam_passed == 'string') callback(pam_passed); else etc_shadow(function(etc_passed) { if (typeof etc_passed == 'string') callback(etc_passed) else posix(function(posix_passed) { if (typeof posix_passed == 'string') callback(posix_passed) else callback(false); }) })

What do you think?

I tried changing auth.js something more, changing the if then else and now it works: two-factor PAM-authentication with Google authenticator!

pam(function(pam_passed) { //due to the stack of different auths, a false if auth failed is largely ig$ if (typeof pam_passed == 'string') callback(pam_passed); else // etc_shadow(function(etc_passed) { // if (typeof etc_passed == 'string') // callback(etc_passed) // else // posix(function(posix_passed) { // if (typeof posix_passed == 'string') // callback(posix_passed) // else callback(false); // }) // }) })

Hurray! So with above combination of changes you not only have real PAM-authentication but also two-factor!

Partially confused by the changes. According to your later change with everything commented out…weren’t those code paths already being fully ignored since you’re using PAM to start with?

No, apparently a PAM-fail went on with Shadow, which succeeds. By commenting out the else a PAM-fail will be a PAM-fail…

I will sum up the changes i made:

  1. extra parameter to pam.authenticate: {serviceName: 'mineos', remoteHost: 'localhost'}
    This looks for the mineos file in /etc/pam.d/ and uses its configuration. The localhost just points at the server itself; with PAM its possible to authenticate against a remote server. I think both extra parameters could be somewhere in the config file of Mineos.
  2. I commented out the else of pam_passed so that a PAM-fail gives a failed login (reloads the login screen).
  3. I installed the libpam-google-authenticator on the server and i configured the two lines in the /etc/pam.d/mineos file. There are many examples on the web how to use google-authenticator (or freeotp as you like).
1 Like

To resolve point 2, maybe you can add an parameter so that the type of authentication can be configured or maybe you can just add a flag inside pam.authenticate to know that it has passed through it, so that in the if then else you can check that flag.

I would be happy to test or review the changed code before committing it.