| OLD | NEW |
| (Empty) |
| 1 # Copyright (c) 2001-2008 Twisted Matrix Laboratories. | |
| 2 # See LICENSE for details. | |
| 3 | |
| 4 """ | |
| 5 Support for asynchronously authenticating using PAM. | |
| 6 """ | |
| 7 | |
| 8 | |
| 9 import PAM | |
| 10 | |
| 11 import getpass, threading, os | |
| 12 | |
| 13 from twisted.internet import threads, defer | |
| 14 | |
| 15 def pamAuthenticateThread(service, user, conv): | |
| 16 def _conv(items): | |
| 17 from twisted.internet import reactor | |
| 18 try: | |
| 19 d = conv(items) | |
| 20 except: | |
| 21 import traceback | |
| 22 traceback.print_exc() | |
| 23 return | |
| 24 ev = threading.Event() | |
| 25 def cb(r): | |
| 26 ev.r = (1, r) | |
| 27 ev.set() | |
| 28 def eb(e): | |
| 29 ev.r = (0, e) | |
| 30 ev.set() | |
| 31 reactor.callFromThread(d.addCallbacks, cb, eb) | |
| 32 ev.wait() | |
| 33 done = ev.r | |
| 34 if done[0]: | |
| 35 return done[1] | |
| 36 else: | |
| 37 raise done[1].type, done[1].value | |
| 38 | |
| 39 return callIntoPAM(service, user, _conv) | |
| 40 | |
| 41 def callIntoPAM(service, user, conv): | |
| 42 """A testing hook. | |
| 43 """ | |
| 44 pam = PAM.pam() | |
| 45 pam.start(service) | |
| 46 pam.set_item(PAM.PAM_USER, user) | |
| 47 pam.set_item(PAM.PAM_CONV, conv) | |
| 48 gid = os.getegid() | |
| 49 uid = os.geteuid() | |
| 50 os.setegid(0) | |
| 51 os.seteuid(0) | |
| 52 try: | |
| 53 pam.authenticate() # these will raise | |
| 54 pam.acct_mgmt() | |
| 55 return 1 | |
| 56 finally: | |
| 57 os.setegid(gid) | |
| 58 os.seteuid(uid) | |
| 59 | |
| 60 def defConv(items): | |
| 61 resp = [] | |
| 62 for i in range(len(items)): | |
| 63 message, kind = items[i] | |
| 64 if kind == 1: # password | |
| 65 p = getpass.getpass(message) | |
| 66 resp.append((p, 0)) | |
| 67 elif kind == 2: # text | |
| 68 p = raw_input(message) | |
| 69 resp.append((p, 0)) | |
| 70 elif kind in (3,4): | |
| 71 print message | |
| 72 resp.append(("", 0)) | |
| 73 else: | |
| 74 return defer.fail('foo') | |
| 75 d = defer.succeed(resp) | |
| 76 return d | |
| 77 | |
| 78 def pamAuthenticate(service, user, conv): | |
| 79 return threads.deferToThread(pamAuthenticateThread, service, user, conv) | |
| OLD | NEW |