From 40cf5ec2f37ff2abfe1bf62d864ee5349d514fce Mon Sep 17 00:00:00 2001 From: David Bartley Date: Sun, 16 Dec 2007 18:06:09 -0500 Subject: [PATCH] Add password prompt --- ceo/ldapi.py | 17 +++++++++++++---- ceo/members.py | 13 ++++++++++--- ceo/urwid/main.py | 14 +++++++++++--- 3 files changed, 34 insertions(+), 10 deletions(-) diff --git a/ceo/ldapi.py b/ceo/ldapi.py index 1b881ad..85acccd 100644 --- a/ceo/ldapi.py +++ b/ceo/ldapi.py @@ -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 '' diff --git a/ceo/members.py b/ceo/members.py index 13a0a58..71fbf7e 100644 --- a/ceo/members.py +++ b/ceo/members.py @@ -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(): diff --git a/ceo/urwid/main.py b/ceo/urwid/main.py index 8cfe506..b0c0331 100644 --- a/ceo/urwid/main.py +++ b/ceo/urwid/main.py @@ -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()