The first module I got sort-of working is this, which lets anyone log in with the password
import syslog def pam_sm_authenticate(pamh, flags, argv): syslog.syslog("start benc") at = pamh.authtok syslog.syslog("got password: "+at) if at == "poop53" : return pamh.PAM_SUCCESS else: return pamh.PAM_AUTH_ERR def pam_sm_setcred(pamh, flags, argv): return pamh.PAM_SUCCESS
Now this cheats a bit - it assumes that some other module has read in the password from the user - I used pam_unix to do that, configured as below, so that first a check against the unix password happens and then if that fails, check against
auth sufficient pam_unix.so auth sufficient pam_python.so /root/auth.py
The specific use I am thinking of, I don't want unix passwords to work. So in that case, I need to read in the password myself if it isn't already set.
Here's how I made that work:
def pam_sm_authenticate(pamh, flags, argv): syslog.syslog("start benc") pamh.authtok if pamh.authtok == None: syslog.syslog("got no password in authtok - trying through conversation") passmsg = pamh.Message(pamh.PAM_PROMPT_ECHO_OFF, "Monkeyballs?") rsp = pamh.conversation(passmsg) syslog.syslog("response is "+rsp.resp) pamh.authtok = rsp.resp # so we should at this point have the password either through the # prompt or from previous module syslog.syslog("got password: "+pamh.authtok) if pamh.authtok == "poop53" : return pamh.PAM_SUCCESS else: return pamh.PAM_AUTH_ERR def pam_sm_setcred(pamh, flags, argv): return pamh.PAM_SUCCESS
To use this with sshd, I need to enable sshd options
ChallengeResponseAuthentication, and now I get this:
$ ssh email@example.com Monkeyballs?poop53 Linux alcf3 2.6.35-28-generic #49-Ubuntu SMP Tue Mar 1 14:40:58 UTC 2011 i686 GNU/Linux #
So I'm happy that I can grab some string from the remote user now, and process it to get an authentication decision.
Thought its pretty weird to have a regular ssh client giving me a
Monkeyballs?prompt at auth time...
Modified: 2011-05-08: Later I used pam_python to write an out of band token module