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.
  • [get | view] (2012-05-25 14:33:00, 1.9 KB) [[attachment:0001-PATCH-LDAPAuth-allow-authentication-to-continue.patch]]
  • [get | view] (2012-05-25 14:33:28, 4.3 KB) [[attachment:0002-PATCH-LDAPAuth-implement-SASL-bind.patch]]
 All files | Selected Files: delete move to page copy to page

You are not allowed to attach a file to this page.