Attachment '0002-PATCH-LDAPAuth-implement-SASL-bind.patch'
Download 1 From 829f13caed40bb7702d3653d76dc56a3c2bded19 Mon Sep 17 00:00:00 2001
2 From: Martin Wilck <martin.wilck@ts.fujitsu.com>
3 Date: Fri, 25 May 2012 16:06:38 +0200
4 Subject: [PATCH 2/2] PATCH: [LDAPAuth] implement SASL bind
5
6 This patch implements SASL binding for LDAP auth. This has several
7 advantages over simple LDAP binding: No bind DN is necessary, and
8 advanced authentication mechanisms are avaiable (e.g. avoiding
9 plain-text transmission of passwords).
10
11 DIGEST-MD5 tested (that's the only method my LDAP server supports),
12 but other methods should also work.
13 ---
14 auth/ldap_login.py | 40 ++++++++++++++++++++++++++++++++++++++--
15 1 files changed, 38 insertions(+), 2 deletions(-)
16
17 diff --git a/auth/ldap_login.py b/auth/ldap_login.py
18 index ba93098..5482e8a 100644
19 --- a/auth/ldap_login.py
20 +++ b/auth/ldap_login.py
21 @@ -26,6 +26,15 @@ except ImportError, err:
22 logging.error("You need to have python-ldap installed (%s)." % str(err))
23 raise
24
25 +try:
26 + import ldap.sasl as ldap_sasl
27 +except ImportError, err:
28 + logging.error("SASL module not found, SASL bind will not be possible (%s)." % str(err))
29 + ldap.sasl = None
30 +else:
31 + ldap.sasl = ldap_sasl
32 + del ldap_sasl
33 +
34 from MoinMoin import user
35 from MoinMoin.auth import BaseAuth, ContinueLogin
36
37 @@ -85,6 +94,7 @@ class LDAPAuth(BaseAuth):
38 autocreate=False, # set to True if you want to autocreate user profiles
39 name='ldap', # use e.g. 'ldap_pdc' and 'ldap_bdc' (or 'ldap1' and 'ldap2') if you auth against 2 ldap servers
40 report_invalid_credentials=True, # whether to emit "invalid username or password" msg at login time or not
41 + sasl_mech=None, # The SASL mechnism to use - this activates SASL
42 ):
43 self.server_uri = server_uri
44 self.bind_dn = bind_dn
45 @@ -117,6 +127,24 @@ class LDAPAuth(BaseAuth):
46
47 self.report_invalid_credentials = report_invalid_credentials
48
49 + if ldap.sasl is None:
50 + self.sasl_mech = None
51 + else:
52 + self.sasl_mech = sasl_mech.upper()
53 + self.bind_once = True # There's only 1 bind with SASL
54 +
55 + def sasl_bind(self, connection, authname, passwd):
56 + if self.sasl_mech in ("GSSAPI", "EXTERNAL"):
57 + authargs = {}
58 + else:
59 + authargs = {
60 + ldap.sasl.CB_AUTHNAME: authname.encode(self.coding),
61 + ldap.sasl.CB_PASS: passwd.encode(self.coding)
62 + }
63 + logging.debug("Attempting SASL/%s bind for %s" % (self.sasl_mech, authname))
64 + authtok = ldap.sasl.sasl(authargs, self.sasl_mech)
65 + connection.sasl_interactive_bind_s("", authtok)
66 +
67 def login(self, request, user_obj, **kw):
68 username = kw.get('username')
69 password = kw.get('password')
70 @@ -168,8 +196,11 @@ class LDAPAuth(BaseAuth):
71 # you can use %(username)s and %(password)s here to get the stuff entered in the form:
72 binddn = self.bind_dn % locals()
73 bindpw = self.bind_pw % locals()
74 - l.simple_bind_s(binddn.encode(coding), bindpw.encode(coding))
75 - logging.debug("Bound with binddn %r" % binddn)
76 + if self.sasl_mech is None:
77 + l.simple_bind_s(binddn.encode(coding), bindpw.encode(coding))
78 + logging.debug("Bound with binddn %r" % binddn)
79 + else:
80 + self.sasl_bind(l, binddn, bindpw)
81
82 # you can use %(username)s here to get the stuff entered in the form:
83 filterstr = self.search_filter % locals()
84 @@ -265,6 +296,11 @@ class LDAPAuth(BaseAuth):
85 "Trying to authenticate with next auth list entry." % (server, str(err)))
86 return ContinueLogin(user_obj, _("LDAP server %(server)s failed.") % {'server': server})
87
88 + except (ldap.STRONG_AUTH_NOT_SUPPORTED, ldap.STRONG_AUTH_REQUIRED, ldap.AUTH_UNKNOWN), err:
89 + logging.error("Authentication to LDAP server %s failed (%s)."
90 + "Trying to authenticate with next auth list entry." % (server, str(err)))
91 + return ContinueLogin(user_obj, _("LDAP server %(server)s failed.") % {'server': server})
92 +
93 except:
94 logging.exception("caught an exception, traceback follows...")
95 return ContinueLogin(user_obj)
96 --
97 1.7.7.6
Attached Files
To refer to attachments on a page, use attachment:filename, as shown below in the list of files. Do NOT use the URL of the [get] link, since this is subject to change and can break easily.You are not allowed to attach a file to this page.