Skip to content

Commit

Permalink
Skip some TLS tests when libldap used NSS
Browse files Browse the repository at this point in the history
Some TLS tests are broken or flaky when libldap is compiled with NSS as
TLS provider. It currently affects Fedora 27 and older releases.

Fedora issue: https://bugzilla.redhat.com/show_bug.cgi?id=1519167

https://github.com/python-ldap/python-ldap/issues/60

Signed-off-by: Christian Heimes <cheimes@redhat.com>
  • Loading branch information
Christian Heimes committed Nov 30, 2017
1 parent e716349 commit 47ce0df
Show file tree
Hide file tree
Showing 4 changed files with 60 additions and 21 deletions.
4 changes: 2 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -43,8 +43,8 @@ env:
# -Werror: turn all warnings into fatal errors
# -Werror=declaration-after-statement: strict ISO C90
- CFLAGS="-std=c90 -Wno-int-in-bool-context -Werror -Werror=declaration-after-statement"
# pass CFLAGS and WITH_GCOV to tox tasks
- TOX_TESTENV_PASSENV="CFLAGS WITH_GCOV"
# pass CFLAGS, CI (for Travis CI) and WITH_GCOV to tox tasks
- TOX_TESTENV_PASSENV="CFLAGS CI WITH_GCOV"

install:
- pip install "pip>=7.1.0"
Expand Down
39 changes: 39 additions & 0 deletions Lib/slapdtest.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,10 @@
from logging.handlers import SysLogHandler
import unittest

# Switch off processing .ldaprc or ldap.conf before importing _ldap
os.environ['LDAPNOINIT'] = '1'

import ldap
from ldap.compat import quote_plus

# a template string for generating simple slapd.conf file
Expand Down Expand Up @@ -52,6 +56,41 @@

LOCALHOST = '127.0.0.1'


def identity(test_item):
"""Identity decorator
"""
return test_item


def skip_unless_travis(reason):
"""Skip test unless test case is executed on CI like Travis CI
"""
if os.environ.get('CI', False):
return identity
else:
return unittest.skip(reason)


def requires_tls(skip_nss=False):
"""Decorator for TLS tests
Tests are not skipped on CI (e.g. Travis CI)
:param skip_nss: Skip test when libldap is compiled with NSS as TLS lib
"""
if not ldap.TLS_AVAIL:
return skip_unless_travis("test needs ldap.TLS_AVAIL")
elif skip_nss and ldap.get_option(ldap.OPT_X_TLS_PACKAGE) == 'MozNSS':
return skip_unless_travis(
"Test doesn't work correctly with Mozilla NSS, see "
"https://bugzilla.redhat.com/show_bug.cgi?id=1519167"
)
else:
return identity


def combined_logger(
log_name,
log_level=logging.WARN,
Expand Down
28 changes: 16 additions & 12 deletions Tests/t_cext.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@

import os
import unittest
from slapdtest import SlapdTestCase

from slapdtest import SlapdTestCase, requires_tls

# Switch off processing .ldaprc or ldap.conf before importing _ldap
os.environ['LDAPNOINIT'] = '1'
Expand Down Expand Up @@ -717,12 +718,6 @@ def test_sasl(self):
return
# TODO

def test_tls(self):
l = self._open_conn()
if not self._require_attr(l, 'start_tls_s'): # HAVE_TLS
return
# TODO

def test_cancel(self):
l = self._open_conn()
if not self._require_attr(l, 'cancel'): # FEATURE_CANCEL
Expand Down Expand Up @@ -807,7 +802,7 @@ def test_invalid_controls(self):
l.sasl_interactive_bind_s, 'who', 'SASLObject', post=(1,))
self.assertInvalidControls(l.unbind_ext)

@unittest.skipUnless(_ldap.TLS_AVAIL, "needs tls")
@requires_tls(skip_nss=True)
def test_tls_ext(self):
l = self._open_conn(bind=False)
# StartTLS needs LDAPv3
Expand All @@ -817,15 +812,17 @@ def test_tls_ext(self):
l.set_option(_ldap.OPT_X_TLS_NEWCTX, 0)
l.start_tls_s()

@unittest.skipUnless(_ldap.TLS_AVAIL, "needs tls")
@requires_tls(skip_nss=False)
def test_tls_ext_noca(self):
l = self._open_conn(bind=False)
l.set_option(_ldap.OPT_PROTOCOL_VERSION, _ldap.VERSION3)
l.set_option(_ldap.OPT_X_TLS_NEWCTX, 0)
with self.assertRaises(_ldap.CONNECT_ERROR):
with self.assertRaises(_ldap.CONNECT_ERROR) as e:
l.start_tls_s()
# some platforms return '(unknown error code)' as reason
if '(unknown error code)' not in str(e.exception):
self.assertIn('not trusted', str(e.exception))

@unittest.skipUnless(_ldap.TLS_AVAIL, "needs tls")
@requires_tls(skip_nss=True)
def test_tls_ext_clientcert(self):
l = self._open_conn(bind=False)
l.set_option(_ldap.OPT_PROTOCOL_VERSION, _ldap.VERSION3)
Expand All @@ -836,5 +833,12 @@ def test_tls_ext_clientcert(self):
l.set_option(_ldap.OPT_X_TLS_NEWCTX, 0)
l.start_tls_s()

@requires_tls(skip_nss=False)
def test_tls_packages(self):
# libldap has tls_g.c, tls_m.c, and tls_o.c with ldap_int_tls_impl
package = _ldap.get_option(_ldap.OPT_X_TLS_PACKAGE)
self.assertIn(package, {"GnuTLS", "MozNSS", "OpenSSL"})


if __name__ == '__main__':
unittest.main()
10 changes: 3 additions & 7 deletions Tests/t_ldap_sasl.py
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@

from ldap.ldapobject import SimpleLDAPObject
import ldap.sasl
from slapdtest import SlapdTestCase
from slapdtest import SlapdTestCase, requires_tls


LDIF = """
Expand Down Expand Up @@ -75,19 +75,15 @@ def test_external_ldapi(self):
"dn:{}".format(self.server.root_dn.lower())
)

@requires_tls(skip_nss=True)
def test_external_tlscert(self):
ldap_conn = self.ldap_object_class(self.server.ldap_uri)
ldap_conn.set_option(ldap.OPT_X_TLS_CACERTFILE, self.server.cafile)
ldap_conn.set_option(ldap.OPT_X_TLS_CERTFILE, self.server.clientcert)
ldap_conn.set_option(ldap.OPT_X_TLS_KEYFILE, self.server.clientkey)
ldap_conn.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, ldap.OPT_X_TLS_HARD)
ldap_conn.set_option(ldap.OPT_X_TLS_NEWCTX, 0)
try:
ldap_conn.start_tls_s()
except ldap.CONNECT_ERROR as e:
# TODO: On Fedora 27 OpenLDAP server refuses STARTTLS when test
# is executed with other tests,
raise unittest.SkipTest("buggy start_tls_s: {}".format(e))
ldap_conn.start_tls_s()

auth = ldap.sasl.external()
ldap_conn.sasl_interactive_bind_s("", auth)
Expand Down

0 comments on commit 47ce0df

Please sign in to comment.