From 47ce0dfb412e0874970412aa1758ed5d7bbf4aed Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Thu, 30 Nov 2017 15:39:55 +0100 Subject: [PATCH] Skip some TLS tests when libldap used NSS 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 --- .travis.yml | 4 ++-- Lib/slapdtest.py | 39 +++++++++++++++++++++++++++++++++++++++ Tests/t_cext.py | 28 ++++++++++++++++------------ Tests/t_ldap_sasl.py | 10 +++------- 4 files changed, 60 insertions(+), 21 deletions(-) diff --git a/.travis.yml b/.travis.yml index 8154a77..ad9cd96 100644 --- a/.travis.yml +++ b/.travis.yml @@ -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" diff --git a/Lib/slapdtest.py b/Lib/slapdtest.py index e0e57c7..ee1fbb2 100644 --- a/Lib/slapdtest.py +++ b/Lib/slapdtest.py @@ -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 @@ -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, diff --git a/Tests/t_cext.py b/Tests/t_cext.py index 22eb895..be858e9 100644 --- a/Tests/t_cext.py +++ b/Tests/t_cext.py @@ -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' @@ -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 @@ -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 @@ -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) @@ -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() diff --git a/Tests/t_ldap_sasl.py b/Tests/t_ldap_sasl.py index 24c7b20..9acd051 100644 --- a/Tests/t_ldap_sasl.py +++ b/Tests/t_ldap_sasl.py @@ -14,7 +14,7 @@ from ldap.ldapobject import SimpleLDAPObject import ldap.sasl -from slapdtest import SlapdTestCase +from slapdtest import SlapdTestCase, requires_tls LDIF = """ @@ -75,6 +75,7 @@ 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) @@ -82,12 +83,7 @@ def test_external_tlscert(self): 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)