Sorry for the repeat post...I'm not sure if my first post (on May 30th) went through or not.
I've been trying to write a PAM module using ctypes. In the conversation function (my_conv in the script below), you're passed in a pam_response** pointer. You're supposed to allocate an array of pam_response's and set the pointer's value to the new array. Then you fill in the array with appropriate data. I can't seem to get it working in python...The authenticate function always returns PAM_AUTHTOK_RECOVER_ERR (21), which I think means the response doesn't make any sense. I've tried saving the response array outside of my_conv to make sure it doesn't get garbage collected, but that doesn't seem to help. Any pointers would be appreciated! Cheers, Chris from ctypes import * libpam = CDLL("libpam.so") class pam_handle(Structure): _fields_ = [ ("handle", c_void_p) ] def __init__(self): self.handle = 0 class pam_message(Structure): _fields_ = [ ("msg_style", c_int), ("msg", c_char_p), ] def __repr__(self): return "<pam_message %i '%s'>" % (self.msg_style, self.msg) class pam_response(Structure): _fields_ = [ ("resp", c_char_p), ("resp_retcode", c_int), ] def __repr__(self): return "<pam_response %i '%s'>" % (self.resp_retcode, self.resp) conv_func = CFUNCTYPE(c_int, c_int, POINTER(POINTER(pam_message)), POINTER(POINTER(pam_response)), c_void_p) class pam_conv(Structure): _fields_ = [ ("conv", conv_func), ("appdata_ptr", c_void_p) ] pam_start = libpam.pam_start pam_start.restype = c_int pam_start.argtypes = [c_char_p, c_char_p, POINTER(pam_conv), POINTER(pam_handle)] pam_authenticate = libpam.pam_authenticate pam_authenticate.restype = c_int pam_authenticate.argtypes = [pam_handle, c_int] if __name__ == "__main__": import getpass, os, sys @conv_func def my_conv(nMessages, messages, pResponse, appData): # Create an array of nMessages response objects # Does r get GC'ed after we're all done? r = (pam_response * nMessages)() pResponse.contents = cast(r, POINTER(pam_response)) for i in range(nMessages): if messages[i].contents.msg == "Password: ": p = getpass.getpass() pResponse.contents[0].resp_retcode = 0 pResponse.contents[0].resp = p return 0 handle = pam_handle() c = pam_conv(my_conv, 0) retval = pam_start("login", os.getlogin(), pointer(c), pointer(handle)) if retval != 0: print "Couldn't start pam session" sys.exit(-1) retval = pam_authenticate(handle, 0) if retval == 21: print "Authentication information cannot be recovered" sys.exit(-1) print retval -- http://mail.python.org/mailman/listinfo/python-list