Changeset - 7ce3897bacd0
[Not reviewed]
default
0 3 0
Mads Kiilerich - 9 years ago 2016-11-15 22:53:41
madski@unity3d.com
auth: make ldap OPT_X_TLS_CACERTDIR configurable

A location was hardcoded. The location was wrong for many systems and prevented
actual TLS from working. Also, it should not be necessary with modern Pythons.

For some reason, instead of removing it, we now decide to expose it to the
user. Choice FTW!
3 files changed with 31 insertions and 9 deletions:
0 comments (0 inline, 0 general)
docs/setup.rst
Show inline comments
 
@@ -235,10 +235,8 @@ Connection Security : required
 
Certificate Checks : optional
 
    How SSL certificates verification is handled -- this is only useful when
 
    `Enable LDAPS`_ is enabled.  Only DEMAND or HARD offer full SSL security
 
    while the other options are susceptible to man-in-the-middle attacks.  SSL
 
    certificates can be installed to /etc/openldap/cacerts so that the
 
    DEMAND or HARD options can be used with self-signed certificates or
 
    certificates that do not have traceable certificates of authority.
 
    with mandatory certificate validation, while the other options are
 
    susceptible to man-in-the-middle attacks.
 

	
 
    NEVER
 
        A serve certificate will never be requested or checked.
 
@@ -260,6 +258,16 @@ Certificate Checks : optional
 
    HARD
 
        The same as DEMAND.
 

	
 
.. _Custom CA Certificates:
 

	
 
Custom CA Certificates : optional
 
    Directory used by OpenSSL to find CAs for validating the LDAP server certificate.
 
    Python 2.7.10 and later default to using the system certificate store, and
 
    this should thus not be necessary when using certificates signed by a CA
 
    trusted by the system.
 
    It can be set to something like `/etc/openldap/cacerts` on older systems or
 
    if using self-signed certificates.
 

	
 
.. _Base DN:
 

	
 
Base DN : required
kallithea/lib/auth_modules/auth_ldap.py
Show inline comments
 
@@ -49,7 +49,7 @@ except ImportError:
 
class AuthLdap(object):
 

	
 
    def __init__(self, server, base_dn, port=389, bind_dn='', bind_pass='',
 
                 tls_kind='PLAIN', tls_reqcert='DEMAND', ldap_version=3,
 
                 tls_kind='PLAIN', tls_reqcert='DEMAND', cacertdir=None, ldap_version=3,
 
                 ldap_filter='(&(objectClass=user)(!(objectClass=computer)))',
 
                 search_scope='SUBTREE', attr_login='uid'):
 
        if ldap is None:
 
@@ -67,6 +67,8 @@ class AuthLdap(object):
 
        OPT_X_TLS_DEMAND = 2
 
        self.TLS_REQCERT = getattr(ldap, 'OPT_X_TLS_%s' % tls_reqcert,
 
                                   OPT_X_TLS_DEMAND)
 
        self.cacertdir = cacertdir
 

	
 
        # split server into list
 
        self.LDAP_SERVER_ADDRESS = server.split(',')
 
        self.LDAP_SERVER_PORT = port
 
@@ -107,9 +109,11 @@ class AuthLdap(object):
 
        if "," in username:
 
            raise LdapUsernameError("invalid character in username: ,")
 
        try:
 
            if hasattr(ldap, 'OPT_X_TLS_CACERTDIR'):
 
                ldap.set_option(ldap.OPT_X_TLS_CACERTDIR,
 
                                '/etc/openldap/cacerts')
 
            if self.cacertdir:
 
                if hasattr(ldap, 'OPT_X_TLS_CACERTDIR'):
 
                    ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, self.cacertdir)
 
                else:
 
                    log.debug("OPT_X_TLS_CACERTDIR is not available - can't set %s", self.cacertdir)
 
            ldap.set_option(ldap.OPT_REFERRALS, ldap.OPT_OFF)
 
            ldap.set_option(ldap.OPT_RESTART, ldap.OPT_ON)
 
            ldap.set_option(ldap.OPT_TIMEOUT, 20)
 
@@ -168,7 +172,8 @@ class AuthLdap(object):
 
            log.debug("LDAP says no such user '%s' (%s)", uid, username)
 
            raise LdapUsernameError()
 
        except ldap.SERVER_DOWN:
 
            raise LdapConnectionError("LDAP can't access authentication server")
 
            # [0] might be {'info': "TLS error -8179:Peer's Certificate issuer is not recognized.", 'desc': "Can't contact LDAP server"}
 
            raise LdapConnectionError("LDAP can't connect to authentication server")
 

	
 

	
 
class KallitheaAuthPlugin(auth_modules.KallitheaExternalAuthPlugin):
 
@@ -231,6 +236,13 @@ class KallitheaAuthPlugin(auth_modules.K
 
                "formname": "Certificate Checks"
 
            },
 
            {
 
                "name": "cacertdir",
 
                "validator": self.validators.UnicodeString(strip=True),
 
                "type": "string",
 
                "description": "Optional: Custom CA certificate directory for validating LDAPS",
 
                "formname": "Custom CA Certificates"
 
            },
 
            {
 
                "name": "base_dn",
 
                "validator": self.validators.UnicodeString(strip=True),
 
                "type": "string",
 
@@ -314,6 +326,7 @@ class KallitheaAuthPlugin(auth_modules.K
 
            'bind_pass': settings.get('dn_pass'),
 
            'tls_kind': settings.get('tls_kind'),
 
            'tls_reqcert': settings.get('tls_reqcert'),
 
            'cacertdir': settings.get('cacertdir'),
 
            'ldap_filter': settings.get('filter'),
 
            'search_scope': settings.get('search_scope'),
 
            'attr_login': settings.get('attr_login'),
kallithea/tests/functional/test_admin_auth_settings.py
Show inline comments
 
@@ -30,6 +30,7 @@ class TestAuthSettingsController(TestCon
 
                       'auth_ldap_port': '999',
 
                       'auth_ldap_tls_kind': 'PLAIN',
 
                       'auth_ldap_tls_reqcert': 'NEVER',
 
                       'auth_ldap_cacertdir': '',
 
                       'auth_ldap_dn_user': 'test_user',
 
                       'auth_ldap_dn_pass': 'test_pass',
 
                       'auth_ldap_base_dn': 'test_base_dn',
0 comments (0 inline, 0 general)