[python3-ldap] Trouble with STARTTLS

Richard Esplin richard-lists at esplins.org
Tue Apr 29 23:30:20 CEST 2014


It worked for me to establish an SSL connection on port 636 using python3-ldap 
version 0.9.1 and Python 3.3. My code is below. I download the cert in 
advance, and save the path in the configuration file. I also pull things like 
the bind dn from the config file.

I would get the error you report if my certificate was incorrect or I had an 
error in the path. It took me a few tries to get the CA cert as a PEM saved in 
the format the code needed at a path it could follow.

Good luck,

Richard

----
from .global_logging import logging
from .global_config import config, config_dir
import os
import ldap3 as ldap
import ssl


def check_auth(username, password):
    try:
        # TLS object for TLS related options. Cert checking is disabled by 
default.
        # Use the CA cert, stored in the config directory
        # * extracted from the server with
        #   openssl s_client -showcerts -connect <hostname>:636
        # * verify with
        #   openssl verify <filename>.crt 
        # * Cert should be a PEM
        cert_file = os.path.join(config_dir, config.get("LDAP", "cert_file"))
        tls_obj = ldap.Tls(ca_certs_file = cert_file,
                           validate = ssl.CERT_REQUIRED)
        ldap_server = ldap.Server(config.get("LDAP", "ldap_server"),
                                              port = 636, use_ssl = True, tls 
= tls_obj)
        basedn = "uid=%s,%s,%s" % (username,
                                   config.get("LDAP", "bind_organisation"),
                                   config.get("LDAP", "domain_components"))
        ldap_conn = ldap.Connection(ldap_server, auto_bind = True,
                                                    user = basedn, password = 
password,
                                                    read_only = True)
        # TODO: Use the connection timeout in the config file
        ldap_conn.unbind()
        return True
    except ldap.LDAPException as e:
        logging.warning("LDAP connection failed. Exception: %s" %e)
        return False


On Tuesday, April 29, 2014 00:04:07 Mark E. Haase wrote:
> I really like python3-ldap. Much cleaner than building on top of OpenLDAP :)
> 
> I can get TLS working on port 636, but I can't figure out how to get Start
> TLS on port 389. Here's what I have so far (Python 2.7):
> 
> 01 import ldap3
> 02 import os
> 03 import ssl
> 04
> 05 host = "ldap.*************.net"
> 06 port = 389
> 07 username = "cn=admin,dc=*************,dc=net"
> 08 password = "*************"
> 09 base_path = os.path.dirname(os.path.realpath(__file__))
> 10
> 11 tls = ldap3.Tls(validate=ssl.CERT_REQUIRED,
> ca_certs_file=os.path.join(base_path, "goodca"))
> 12 ldap_server = ldap3.Server(host, port=port, use_ssl=False, tls=tls)
> 13 ldap_handle = ldap3.Connection(ldap_server, user=username,
> password=password)
> 14 ldap_handle.open()
> 15 ldap_handle.start_tls()
> 16 ldap_handle.bind()
> 
> I'm ~100% sure that "goodca" is not the problem, because I've validated it
> with openssl s_client, gnutls-cli, ldapsearch, and python-ldap. It's PEM
> encoded. When I run this example, I get this exception:
> 
> mhaase at luci:~/luci/bin$ python test.py
> Traceback (most recent call last):
>   File "test.py", line 15, in <module>
>     ldap_handle.start_tls()
>   File "/usr/local/lib/python2.7/dist-packages/ldap3/core/connection.py",
> line 535, in start_tls
>     if self.server.tls.start_tls(self):
>   File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line
> 118, in start_tls
>     return self._start_tls(connection)
>   File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line
> 121, in _start_tls
>     connection.socket = self.wrap_socket(connection, False)
>   File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line 91,
> in wrap_socket
>     check_hostname(wrapped_socket, connection.server.host, self.valid_names)
> File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line 206,
> in check_hostname
>     match_hostname_backport(server_certificate, host_name)
>   File "/usr/local/lib/python2.7/dist-packages/ldap3/core/tls.py", line
> 168, in match_hostname_backport
>     raise ValueError("empty or no certificate")
> ValueError: empty or no certificate
> 
> Any ideas what I'm doing wrong? Any help would be greatly appreciated...
> I've been struggling with openldap/python-ldap/python3-for 12 hours today!!



More information about the python3-ldap mailing list