[python-ldap] Issue with TLS contexts...

Mark E. Haase mehaase at gmail.com
Tue Apr 29 05:50:00 CEST 2014


I'm having an issue with TLS in python-ldap. I can get a few basic use
cases working, but it appears that it's not possible to change some TLS
context parameters at runtime after they have initially been set. Here's a
test case i've reproduced:

 1 import ldap
 2 import os
 3
 4 url = "ldaps://***********************:636/"
 5 username = "cn=admin,dc=****************,dc=net"
 6 password = "*************"
 7
 8 # ldap.set_option( ldap.OPT_DEBUG_LEVEL, 255 )
 9
10 base_path = os.path.dirname(os.path.realpath(__file__))
11 ldap_handle = ldap.initialize(url)
12
13 # ldap.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
14 ldap.set_option(ldap.OPT_X_TLS, ldap.OPT_X_TLS_DEMAND)
15 ldap.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_DEMAND)
16 ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, os.path.join(base_path,
"badca"))
17
18 print("OPT_X_TLS", ldap.get_option(ldap.OPT_X_TLS))
19 print("OPT_X_TLS_REQUIRE_CERT",
ldap.get_option(ldap.OPT_X_TLS_REQUIRE_CERT))
20 print("OPT_X_TLS_CACERTFILE", ldap.get_option(ldap.OPT_X_TLS_CACERTFILE))
21
22 try:
23     print("#" * 20) + "SIMPLE BIND #1" + ("#" * 20)
24     ldap_handle.simple_bind_s(username, password)
25     print("Success!")
26 except ldap.SERVER_DOWN:
27     print("Caught 'server down' during bind #1.")
28
29 ldap_handle2 = ldap.initialize(url)
30 ldap.set_option(ldap.OPT_X_TLS_CACERTFILE, os.path.join(base_path,
"goodca"))
31
32 print("OPT_X_TLS", ldap.get_option(ldap.OPT_X_TLS))
33 print("OPT_X_TLS_REQUIRE_CERT",
ldap.get_option(ldap.OPT_X_TLS_REQUIRE_CERT))
34 print("OPT_X_TLS_CACERTFILE", ldap.get_option(ldap.OPT_X_TLS_CACERTFILE))
35
36 try:
37     print("#" * 20) + "SIMPLE BIND #2" + ("#" * 20)
38     ldap_handle2.simple_bind_s(username, password)
39     print("Success!")
40 except ldap.SERVER_DOWN:
41     print("Caught 'server down' during bind #2.")

Note that I have two CA certificate files (lines 16 and 30). One is
"goodca" and it contains the server's actual CA certificate. The other is
called "badca" and it contains some other random CA certificate. If I try
to create 2 instances and the first one uses the bad ca, then the second
one also uses the bad ca and they both fail! If I transpose lines 16 and
30, then they both use the good ca and both connections succeed! In short,
it appears that once CACERTFILE has been set, it's not possible to change
it.

The example above is highly contrived, because I'm trying to isolate the
issue. But my use case is a web application where an end user can provide a
CA certificate, so it's not ideal if the entire web server has to be
restarted every time the user provides a new CA certificate. (Also I'd like
to be able to support multiple LDAP servers in the same process.)

Is this intended behavior? Is it a bug? Should I be doing something
different?

Notice on line 13 I had experimented with creating a new TLS context, but
this parameter isn't document well in OpenLDAP or python-ldap, so I'm not
exactly sure what argument to pass to it. OpenLDAP has a function to
directly set a TLS context, but that doesn't appear to have been translated
into python-ldap.

I also tried setting options directly on the ldap_handle, but some options
(such as CACERTFILE) don't seem to apply to ldap_handle.

Any feedback would be greatly appreciated. I've been staring at python-ldap
for about 10 hours today :(
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://mail.python.org/pipermail/python-ldap/attachments/20140428/d2b12acd/attachment.html>


More information about the python-ldap mailing list