noirello / bonsai

Simple Python 3 module for LDAP, using libldap2 and winldap C libraries.
MIT License
116 stars 32 forks source link

Raise specific Exceptions when LDAP-connections fail due to SSL-problems #75

Closed senfomat closed 1 year ago

senfomat commented 1 year ago

Issue: I recently ran multiple times into the problem, that LDAP-connection-attempts were unsuccessful, because the server-certificates could not got verified. This was due to a lack of the corresponding CA-Certificate in the central CA-system-store (in our case Ubuntu Linux).

When I was tracking down these connection-problems, I had to do trial&error to nail it down to this certificate-thing. Because bonsai just raises bonsai.errors.ConnectionError: Can't contact LDAP server. (unknown error code) (0xFFFF [-1]).

Is there a possibility to raise more specific exceptions on these SSL-related errors?

Setup:

Testscript:

#!/usr/bin/env python

import bonsai
from bonsai.errors import AuthenticationError, ConnectionError

bonsai.set_debug(True)

client = bonsai.LDAPClient("ldaps://ldap.domain.local")
client.set_credentials("SIMPLE", user="testuser", password="testpassword")

# client.set_cert_policy("allow")

try:
    returnValue = client.connect()
except ConnectionError as err:
    print(f"LDAP-Connection failed: {err}")
except AuthenticationError as err:
    print(f"LDAP-Authentication failed: {err}")
except Exception as e:
    print(f"Generic exception: {e}")

Output:

DBG: ldapconnection_new [self:0x7f7bcc9a35b0]
DBG: ldapconnection_init (self:0x7f7bcc9a35b0)
DBG: ldapconnection_open (self:0x7f7bcc9a35b0)
DBG: connecting (self:0x7f7bcc9a35b0)
DBG: create_conn_info (mech:SIMPLE, sock:-1, creds:0x7f7bcdf03f00)
DBG: ldapconnectiter_new [self:0x7f7bcc802740]
DBG: create_init_thread_data (client:0x7f7bcdc476d0, sock:-1)
DBG: create_init_thread (ld:0x24db110, info:0x24e7860, thread:0)
DBG: ldapconnection_result (self:0x7f7bcc9a35b0, args:0x7f7bcdd2ee80, kwds:(nil))[msgid:-1]
DBG: LDAPConnection_Result (self:0x7f7bcc9a35b0, msgid:-1, millisec:-1)
DBG: LDAPConnectIter_Next (self:0x7f7bcc802740, timeout:-1) [tls:0, state:0]
DBG: _ldap_finish_init_thread (async:0, thread:140169686472448, timeout:-1, misc:0x24db110)
DBG: _pthread_mutex_timedlock
DBG: ldap_init_thread_func (params:0x24db110)
DBG: set connecting async: 0
DBG: ldap_init_thread_func [retval:0]
DBG: LDAPConnectIter_Next (self:0x7f7bcc802740, timeout:-1) [tls:0, state:0]
DBG: _ldap_finish_init_thread (async:0, thread:140169686472448, timeout:-1, misc:0x24db110)
DBG: _pthread_mutex_timedlock
DBG: set_certificates (self:0x7f7bcc802740)
DBG: binding [state:3]
DBG: _ldap_bind (ld:0x7f7bc4000b60, info:0x24e7860, ppolicy:0, result:(nil), msgid:0)
DBG: ldapconnectiter_dealloc (self:0x7f7bcc802740)
DBG: dealloc_conn_info (info:0x24e7860)
LDAP-Connection failed: Can't contact LDAP server. (unknown error code) (0xFFFF [-1])
DBG: ldapconnection_dealloc (self:0x7f7bcc9a35b0)

(When I uncomment the line client.set_cert_policy("allow") in my code the connection gets successfully established.)

noirello commented 1 year ago

Unfortunately, If OpenLDAP doesn't set a specific return value or set a diagnostic message, then I don't think it's possible to raise a specific error.

The raised exception is based on the LDAP error code (returned by an LDAP function call or set to the LDAP structure's corresponding field), and if additional diagnostic message is provided, then it's concatenated to the exception's error message.

TLS related errors are usually only shown in libldap's trace logs. You can set trace level logging with bonsai.set_debug(True, -1).

senfomat commented 1 year ago

Ok, I agree, that this is an openldap-Libraryissue. So I'll close the issue.

But thanks for the hint to the trace-logs. There I can see the real error:

[...]
DBG: _ldap_bind (ld:0x7f3764000b60, info:0x1943560, ppolicy:0, result:(nil), msgid:0)
ldap_sasl_bind
ldap_send_initial_request
ldap_new_connection 1 1 0
ldap_int_open_connection
ldap_connect_to_host: TCP ldap.domain.local:636
ldap_new_socket: 3
ldap_prepare_socket: 3
ldap_connect_to_host: Trying 10.10.10.10:636
ldap_pvt_connect: fd: 3 tm: -1 async: 0
attempting to connect:
connect success
TLS: peer cert untrusted or revoked (0x42)
TLS: can't connect: (unknown error code).
ldap_msgfree
ldap_err2string
DBG: ldapconnectiter_dealloc (self:0x7f376a99a740)
[...]