From cd2b2443c5ba2f4885e3d85f98332b2fa8b30432 Mon Sep 17 00:00:00 2001 From: Sergey Orlov Date: Thu, 30 May 2019 15:20:58 +0200 Subject: [PATCH] ipatests: allow to relax security of LDAP connection from controller to IPA host The Host.ldap_connect() method uses LDAPClient from ipapython package. In a3934a21 we started to use secure connection from tests controller to ipa server. And also 5be9341f changed the LDAPClient.simple_bind method to forbid password based authentiction over insecure connection. This makes it imposible to establish ldap connection in some test configurations where hostnames known to ipa server do not match ones known to tests controller (i.e. when host.hostname != host.external_hostname) because TLS certificate is issued for host.hostname and test controller tries to verify it against host.external_hostname. A sublass of LDAPClient is provided which allows to skip certificate check. Fixes: https://pagure.io/freeipa/issue/7960 Reviewed-By: Florence Blanc-Renaud --- ipatests/pytest_ipa/integration/host.py | 36 ++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 4 deletions(-) diff --git a/ipatests/pytest_ipa/integration/host.py b/ipatests/pytest_ipa/integration/host.py index e6a3853e5..8f6800c44 100644 --- a/ipatests/pytest_ipa/integration/host.py +++ b/ipatests/pytest_ipa/integration/host.py @@ -21,12 +21,40 @@ import subprocess import tempfile +import ldap import pytest_multihost.host from ipaplatform.paths import paths from ipapython import ipaldap +class LDAPClientWithoutCertCheck(ipaldap.LDAPClient): + """Adds an option to disable certificate check for TLS connection + + To disable certificate validity check create client with added option + no_certificate_check: + client = LDAPClientWithoutCertCheck(..., no_certificate_check=True) + """ + def __init__(self, *args, **kwargs): + self._no_certificate_check = kwargs.pop( + 'no_certificate_check', False) + super(LDAPClientWithoutCertCheck, self).__init__(*args, **kwargs) + + def _connect(self): + if (self._start_tls and self.protocol == 'ldap' and + self._no_certificate_check): + with self.error_handler(): + conn = ipaldap.ldap_initialize( + self.ldap_uri, cacertfile=self._cacert) + conn.set_option(ldap.OPT_X_TLS_REQUIRE_CERT, + ldap.OPT_X_TLS_NEVER) + conn.set_option(ldap.OPT_X_TLS_NEWCTX, 0) + conn.start_tls_s() + return conn + else: + return super(LDAPClientWithoutCertCheck, self)._connect() + + class Host(pytest_multihost.host.Host): """Representation of a remote IPA host""" @@ -53,11 +81,11 @@ class Host(pytest_multihost.host.Host): f.write(cacert) f.flush() - conn = ipaldap.LDAPClient.from_hostname_secure( + hostnames_mismatch = self.hostname != self.external_hostname + conn = LDAPClientWithoutCertCheck.from_hostname_secure( self.external_hostname, - cacert=f.name - ) - + cacert=f.name, + no_certificate_check=hostnames_mismatch) binddn = self.config.dirman_dn self.log.info('LDAP bind as %s', binddn) conn.simple_bind(binddn, self.config.dirman_password)