Skip to content

Commit 1747677

Browse files
authored
Merge pull request #73 from metbosch/master
Improve TLS connections support
2 parents 7125c33 + 42962fd commit 1747677

File tree

5 files changed

+38
-15
lines changed

5 files changed

+38
-15
lines changed

Diff for: src/node/ext/ldap/base.py

+10
Original file line numberDiff line numberDiff line change
@@ -103,6 +103,9 @@ def __init__(self, props=None):
103103
self._start_tls = props.start_tls
104104
self._ignore_cert = props.ignore_cert
105105
self._tls_cacert_file = props.tls_cacertfile
106+
self._tls_cacert_dir = props.tls_cacertdir
107+
self._tls_clcert_file = props.tls_clcertfile
108+
self._tls_clkey_file = props.tls_clkeyfile
106109
self._retry_max = props.retry_max
107110
self._retry_delay = props.retry_delay
108111
# backward compatibility:
@@ -118,6 +121,13 @@ def bind(self):
118121
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
119122
elif self._tls_cacert_file: # pragma: no cover
120123
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self._tls_cacert_file)
124+
elif self._tls_cacert_dir: # pragma: no cover
125+
ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, self._tls_cacert_dir)
126+
if self._tls_clcert_file and self._tls_clkey_file: # pragma: no cover
127+
ldap.set_option(ldap.OPT_X_TLS_CERTFILE, self._tls_clcert_file)
128+
ldap.set_option(ldap.OPT_X_TLS_KEYFILE, self._tls_clkey_file)
129+
elif self._tls_clcert_file or self._tls_clkey_file: # pragma: no cover
130+
logger.exception("Only client certificate or key have been provided.")
121131
self._con = ldap.ldapobject.ReconnectLDAPObject(
122132
self._uri,
123133
bytes_mode=False,

Diff for: src/node/ext/ldap/interfaces.py

+3-6
Original file line numberDiff line numberDiff line change
@@ -39,14 +39,11 @@ class ILDAPProps(Interface):
3939

4040
tls_cacertfile = Attribute('Name of CA Cert file')
4141

42-
# XXX
43-
# tls_cacertdir = Attribute('Path to CA Cert directory')
42+
tls_cacertdir = Attribute('Path to CA Cert directory')
4443

45-
# XXX
46-
# tls_clcertfile = Attribute('Name of CL Cert file')
44+
tls_clcertfile = Attribute('Name of client Cert file')
4745

48-
# XXX
49-
# tls_clkeyfile = Attribute('Path to CL key file')
46+
tls_clkeyfile = Attribute('Path to client key file')
5047

5148
retry_max = Attribute('Retry count')
5249

Diff for: src/node/ext/ldap/properties.py

+11-9
Original file line numberDiff line numberDiff line change
@@ -48,9 +48,9 @@ def __init__(
4848
start_tls=0,
4949
ignore_cert=0,
5050
tls_cacertfile=None,
51-
# tls_cacertdir=None,
52-
# tls_clcertfile=None,
53-
# tls_clkeyfile=None,
51+
tls_cacertdir=None,
52+
tls_clcertfile=None,
53+
tls_clkeyfile=None,
5454
retry_max=1,
5555
retry_delay=10.0,
5656
multivalued_attributes=MULTIVALUED_DEFAULTS,
@@ -89,9 +89,11 @@ def __init__(
8989
needed if the CA is not in the default CA keyring (i.e. with
9090
self-signed certificates). Under Windows its possible that
9191
python-ldap lib does recognize the system keyring.
92-
:param tls_cacertdir: Not yet
93-
:param tls_clcertfile: Not yet
94-
:param tls_clkeyfile: Not yet
92+
:param tls_cacertdir: Provide a directory with CA Certificates.
93+
:param tls_clcertfile: Provide a specific client certificate file to be
94+
used for client authentication. Requires tls_clkeyfile to be set.
95+
:param tls_clkeyfile: Provide a specific client key file to be used for
96+
client authentication. Requires tls_clcertfile to be set.
9597
:param retry_max: Maximum count of reconnect trials. Value has to be >= 1
9698
:param retry_delay: Time span to wait between two reconnect trials.
9799
:param multivalued_attributes: Set of attributes names considered as
@@ -120,9 +122,9 @@ def __init__(
120122
self.start_tls = start_tls
121123
self.ignore_cert = ignore_cert
122124
self.tls_cacertfile = tls_cacertfile
123-
# self.tls_cacertdir = tls_cacertdir
124-
# self.tls_clcertfile = tls_clcertfile
125-
# self.tls_clkeyfile = tls_clkeyfile
125+
self.tls_cacertdir = tls_cacertdir
126+
self.tls_clcertfile = tls_clcertfile
127+
self.tls_clkeyfile = tls_clkeyfile
126128
self.retry_max = retry_max
127129
self.retry_delay = retry_delay
128130
self.multivalued_attributes = multivalued_attributes

Diff for: src/node/ext/ldap/session.py

+11
Original file line numberDiff line numberDiff line change
@@ -68,6 +68,15 @@ def authenticate(self, dn, pw):
6868
# Let's bypass connector/communicator until they are sorted out
6969
if self._props.ignore_cert: # pragma: no cover
7070
ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_NEVER)
71+
elif self._props.tls_cacertfile: # pragma: no cover
72+
ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, self._props.tls_cacertfile)
73+
elif self._props.tls_cacertdir: # pragma: no cover
74+
ldap.set_option(ldap.OPT_X_TLS_CACERTDIR, self._props.tls_cacertdir)
75+
if self._props.tls_clcertfile and self._props.tls_clkeyfile: # pragma: no cover
76+
ldap.set_option(ldap.OPT_X_TLS_CERTFILE, self._props.tls_clcertfile)
77+
ldap.set_option(ldap.OPT_X_TLS_KEYFILE, self._props.tls_clkeyfile)
78+
elif self._props.tls_clcertfile or self._props.tls_clkeyfile: # pragma: no cover
79+
logger.exception("Only client certificate or key have been provided.")
7180
con = ldap.initialize(
7281
self._props.uri,
7382
bytes_mode=False,
@@ -77,6 +86,8 @@ def authenticate(self, dn, pw):
7786
# Directory More info: https://www.python-ldap.org/faq.html#usage
7887
con.set_option(ldap.OPT_REFERRALS, 0)
7988
try:
89+
if self._props.start_tls:
90+
con.start_tls_s()
8091
con.simple_bind_s(dn, pw)
8192
except (ldap.INVALID_CREDENTIALS, ldap.UNWILLING_TO_PERFORM):
8293
# The UNWILLING_TO_PERFORM event might be thrown, if you query a

Diff for: src/node/ext/ldap/tests/test_properties.py

+3
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,9 @@ def test_LDAPProps(self):
4747
self.assertEqual(props.start_tls, 0)
4848
self.assertEqual(props.ignore_cert, 0)
4949
self.assertEqual(props.tls_cacertfile, None)
50+
self.assertEqual(props.tls_cacertdir, None)
51+
self.assertEqual(props.tls_clcertfile, None)
52+
self.assertEqual(props.tls_clkeyfile, None)
5053
self.assertEqual(props.retry_max, 1)
5154
self.assertEqual(props.retry_delay, 10.)
5255
self.assertEqual(props.multivalued_attributes, MULTIVALUED_DEFAULTS)

0 commit comments

Comments
 (0)