Add password prompt
authorDavid Bartley <dtbartle@csclub.uwaterloo.ca>
Sun, 16 Dec 2007 23:06:09 +0000 (18:06 -0500)
committerDavid Bartley <dtbartle@csclub.uwaterloo.ca>
Sun, 16 Dec 2007 23:06:09 +0000 (18:06 -0500)
ceo/ldapi.py
ceo/members.py
ceo/urwid/main.py

index 1b881ad..85acccd 100644 (file)
@@ -4,16 +4,17 @@ LDAP Utilities
 This module makes use of python-ldap, a Python module with bindings
 to libldap, OpenLDAP's native C client library.
 """
-import ldap.modlist
+import ldap.modlist, os, pwd
+from subprocess import Popen, PIPE
 
 
-def connect_sasl(uri, mech, realm):
+def connect_sasl(uri, mech, realm, password):
 
     # open the connection
     ld = ldap.initialize(uri)
 
     # authenticate
-    sasl = Sasl(mech, realm)
+    sasl = Sasl(mech, realm, password)
     ld.sasl_interactive_bind_s('', sasl)
 
     return ld
@@ -124,9 +125,17 @@ def format_ldaperror(ex):
 
 class Sasl:
 
-    def __init__(self, mech, realm):
+    def __init__(self, mech, realm, password):
         self.mech = mech
         self.realm = realm
 
+        if mech == 'GSSAPI' and password is not None:
+            userid = pwd.getpwuid(os.getuid()).pw_name
+            kinit = '/usr/bin/kinit'
+            kinit_args = [ kinit, '%s@%s' % (userid, realm) ]
+            kinit = Popen(kinit_args, stdin=PIPE, stdout=PIPE, stderr=PIPE)
+            kinit.stdin.write('%s\n' % password)
+            kinit.wait()
+
     def callback(self, id, challenge, prompt, defresult):
         return ''
index 13a0a58..71fbf7e 100644 (file)
@@ -83,14 +83,21 @@ class ChildFailed(MemberException):
 # global directory connection
 ld = None
 
-def connect():
+def connect(auth_callback):
     """Connect to LDAP."""
 
     configure()
 
     global ld
-    ld = ldapi.connect_sasl(cfg['server_url'],
-            cfg['sasl_mech'], cfg['sasl_realm'])
+    password = None
+    while ld is None:
+        try:
+            ld = ldapi.connect_sasl(cfg['server_url'], cfg['sasl_mech'],
+                cfg['sasl_realm'], password)
+        except ldap.LOCAL_ERROR, e:
+            password = auth_callback.callback(e)
+            if password == None:
+                raise e
 
 
 def disconnect():
index 8cfe506..b0c0331 100644 (file)
@@ -1,4 +1,4 @@
-import sys, random, ldap, urwid.curses_display
+import sys, random, ldap, urwid.curses_display, getpass
 from ceo import members, ldapi
 from ceo.urwid.widgets import *
 from ceo.urwid.window import *
@@ -148,9 +148,9 @@ def run():
 
 def start():
     try:
-        print "Connecting...",
+        print "Connecting...\n",
         sys.stdout.flush()
-        members.connect()
+        members.connect(AuthCallback())
         print "done."
 
         ui.run_wrapper( run )
@@ -162,5 +162,13 @@ def start():
         print "You probably aren't permitted to do whatever you just tried."
         print "Admittedly, ceo probably shouldn't have crashed either."
 
+class AuthCallback:
+    def callback(self, error):
+        try:
+            return getpass.getpass("Password: ")
+        except KeyboardInterrupt:
+            print ""
+            sys.exit(1)
+
 if __name__ == '__main__':
     start()