From: Stefan Eissing Date: Tue, 30 Nov 2021 15:58:30 +0000 (+0000) Subject: * test: allow more flexibility in the ssl modules used X-Git-Tag: 2.5.0-alpha2-ci-test-only~680 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=5144278ddb267e2fda2b0e4ad96a1be4ef0b5d25;p=thirdparty%2Fapache%2Fhttpd.git * test: allow more flexibility in the ssl modules used for a vhost. Adjust http2 and md test cases for working with modules other than mod_ssl. git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@1895429 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/test/modules/http2/env.py b/test/modules/http2/env.py index dae91657764..158646809c9 100644 --- a/test/modules/http2/env.py +++ b/test/modules/http2/env.py @@ -17,7 +17,7 @@ class H2TestSetup(HttpdTestSetup): def __init__(self, env: 'HttpdTestEnv'): super().__init__(env=env) self.add_source_dir(os.path.dirname(inspect.getfile(H2TestSetup))) - self.add_modules(["http2", "proxy_http2", "cgid", "autoindex"]) + self.add_modules(["http2", "proxy_http2", "cgid", "autoindex", "ssl"]) def make(self): super().make() @@ -90,6 +90,7 @@ class H2TestEnv(HttpdTestEnv): re.compile(r'.*malformed header from script \'hecho.py\': Bad header: x.*'), re.compile(r'.*:tls_post_process_client_hello:.*'), re.compile(r'.*:tls_process_client_certificate:.*'), + re.compile(r'.*have incompatible TLS configurations.'), ]) def setup_httpd(self, setup: HttpdTestSetup = None): @@ -106,8 +107,11 @@ class H2Conf(HttpdConf): ] })) - def start_vhost(self, domains, port=None, doc_root="htdocs", with_ssl=None): - super().start_vhost(domains=domains, port=port, doc_root=doc_root, with_ssl=with_ssl) + def start_vhost(self, domains, port=None, doc_root="htdocs", with_ssl=None, + ssl_module=None, with_certificates=None): + super().start_vhost(domains=domains, port=port, doc_root=doc_root, + with_ssl=with_ssl, ssl_module=ssl_module, + with_certificates=with_certificates) if f"noh2.{self.env.http_tld}" in domains: protos = ["http/1.1"] elif port == self.env.https_port or with_ssl is True: diff --git a/test/modules/http2/test_101_ssl_reneg.py b/test/modules/http2/test_101_ssl_reneg.py index 6d0b6ec70df..1ca23d4a5d4 100644 --- a/test/modules/http2/test_101_ssl_reneg.py +++ b/test/modules/http2/test_101_ssl_reneg.py @@ -1,9 +1,10 @@ import re import pytest -from .env import H2Conf +from .env import H2Conf, H2TestEnv +@pytest.mark.skipif(H2TestEnv.get_ssl_module() != "mod_ssl", reason="only for mod_ssl") class TestSslRenegotiation: @pytest.fixture(autouse=True, scope='class') diff --git a/test/modules/http2/test_700_load_get.py b/test/modules/http2/test_700_load_get.py index d181cd2882c..69430c33f69 100644 --- a/test/modules/http2/test_700_load_get.py +++ b/test/modules/http2/test_700_load_get.py @@ -31,7 +31,9 @@ class TestLoadGet: chunk = 32 for n in range(0, 5): args = [env.h2load, "-n", "%d" % chunk, "-c", "1", "-m", "10", - f"--base-uri={env.https_base_url}"] + f"--connect-to=localhost:{env.https_port}", + f"--base-uri={env.mkurl('https', 'cgi', '/')}", + ] for i in range(0, chunk): args.append(env.mkurl("https", "cgi", ("/mnot164.py?count=%d&text=%s" % (start+(n*chunk)+i, text)))) r = env.run(args) @@ -47,7 +49,9 @@ class TestLoadGet: chunk = 64 for n in range(0, 5): args = [env.h2load, "-n", "%d" % chunk, "-c", "%d" % conns, "-m", "10", - f"--base-uri={env.https_base_url}"] + f"--connect-to=localhost:{env.https_port}", + f"--base-uri={env.mkurl('https', 'cgi', '/')}", + ] for i in range(0, chunk): args.append(env.mkurl("https", "cgi", ("/mnot164.py?count=%d&text=%s" % (start+(n*chunk)+i, text)))) r = env.run(args) diff --git a/test/modules/md/test_702_auto.py b/test/modules/md/test_702_auto.py index ab96063268f..6864b0d2bce 100644 --- a/test/modules/md/test_702_auto.py +++ b/test/modules/md/test_702_auto.py @@ -548,7 +548,7 @@ class TestAutov2: # test case: 2.4.40 mod_ssl stumbles over a SSLCertificateChainFile when installing # a fallback certificate - @pytest.mark.skipif(HttpdTestEnv.get_ssl_module() != "ssl", reason="only for mod_ssl") + @pytest.mark.skipif(HttpdTestEnv.get_ssl_module() != "mod_ssl", reason="only for mod_ssl") def test_md_702_042(self, env): domain = self.test_domain dns_list = [domain] @@ -658,6 +658,9 @@ class TestAutov2: "", " SSLEngine on", "", + "", + f" TLSEngine {env.https_port}", + "", ]) conf.add_md([domain]) conf.install() diff --git a/test/modules/md/test_800_must_staple.py b/test/modules/md/test_800_must_staple.py index 2cc063c2d3f..06e881c2f1e 100644 --- a/test/modules/md/test_800_must_staple.py +++ b/test/modules/md/test_800_must_staple.py @@ -67,7 +67,7 @@ class TestMustStaple: # MD that must staple @pytest.mark.skipif(MDTestEnv.lacks_ocsp(), reason="no OCSP responder") - @pytest.mark.skipif(MDTestEnv.get_ssl_module() != "ssl", reason="only for mod_ssl") + @pytest.mark.skipif(MDTestEnv.get_ssl_module() != "mod_ssl", reason="only for mod_ssl") def test_md_800_004(self, env): # mod_ssl stapling is off, expect no stapling stat = env.get_ocsp_status(self.domain) diff --git a/test/modules/md/test_801_stapling.py b/test/modules/md/test_801_stapling.py index ba1aa49ad25..5c0360251b5 100644 --- a/test/modules/md/test_801_stapling.py +++ b/test/modules/md/test_801_stapling.py @@ -103,7 +103,7 @@ class TestStapling: assert env.apache_restart() == 0 stat = env.get_ocsp_status(md) assert stat['ocsp'] == "successful (0x0)" if \ - env.ssl_module == "ssl" else "no response sent" + env.ssl_module == "mod_ssl" else "no response sent" stat = env.get_md_status(md) assert not stat["stapling"] # @@ -124,7 +124,7 @@ class TestStapling: assert env.apache_restart() == 0 stat = env.get_ocsp_status(md) assert stat['ocsp'] == "successful (0x0)" if \ - env.ssl_module == "ssl" else "no response sent" + env.ssl_module == "mod_ssl" else "no response sent" stat = env.get_md_status(md) assert not stat["stapling"] @@ -187,7 +187,7 @@ class TestStapling: # mdB has no md stapling, but mod_ssl kicks in stat = env.get_ocsp_status(md_b) assert stat['ocsp'] == "successful (0x0)" if \ - env.ssl_module == "ssl" else "no response sent" + env.ssl_module == "mod_ssl" else "no response sent" stat = env.get_md_status(md_b) assert not stat["stapling"] diff --git a/test/modules/md/test_810_ec.py b/test/modules/md/test_810_ec.py index cd849b42ad8..f8480dd4ada 100644 --- a/test/modules/md/test_810_ec.py +++ b/test/modules/md/test_810_ec.py @@ -89,7 +89,7 @@ class TestAutov2: # use a curve unsupported by LE # only works with mod_ssl as rustls refuses to load such a weak key - @pytest.mark.skipif(MDTestEnv.get_ssl_module() != "ssl", reason="only for mod_ssl") + @pytest.mark.skipif(MDTestEnv.get_ssl_module() != "mod_ssl", reason="only for mod_ssl") @pytest.mark.skipif(MDTestEnv.get_acme_server() != 'boulder', reason="onyl boulder rejects this") def test_md_810_004(self, env): domain = self.test_domain @@ -111,7 +111,7 @@ class TestAutov2: domain = self.test_domain # behaviour differences, mod_ssl selects the strongest suitable, # mod_tls selects the first suitable - ec_key_len = 384 if env.ssl_module == "ssl" else 256 + ec_key_len = 384 if env.ssl_module == "mod_ssl" else 256 self.set_get_check_pkeys(env, domain, [ {'spec': "secp256r1", 'ciphers': "ECDSA", 'keylen': ec_key_len}, {'spec': "RSA 4096", 'ciphers': "ECDHE-RSA-CHACHA20-POLY1305", 'keylen': 4096}, diff --git a/test/pyhttpd/conf.py b/test/pyhttpd/conf.py index 3fefffaa8c0..a2eeab9bfea 100644 --- a/test/pyhttpd/conf.py +++ b/test/pyhttpd/conf.py @@ -17,6 +17,7 @@ class HttpdConf(object): self._extras = extras.copy() if extras else {} if 'base' in self._extras: self.add(self._extras['base']) + self._tls_engine_ports = set() def __repr__(self): s = '\n'.join(self._lines) @@ -36,29 +37,45 @@ class HttpdConf(object): self._lines.extend(line) return self - def add_certificate(self, cert_file, key_file): - if self.env.ssl_module == "ssl": + def add_certificate(self, cert_file, key_file, ssl_module=None): + if ssl_module is None: + ssl_module = self.env.ssl_module + if ssl_module == 'mod_ssl': self.add([ f"SSLCertificateFile {cert_file}", f"SSLCertificateKeyFile {key_file if key_file else cert_file}", ]) - elif self.env.ssl_module == "tls": - self.add(f""" - TLSCertificate {cert_file} {key_file} - """) + elif ssl_module == 'mod_tls': + self.add(f"TLSCertificate {cert_file} {key_file if key_file else ''}") + elif ssl_module == 'mod_gnutls': + self.add([ + f"GnuTLSCertificateFile {cert_file}", + f"GnuTLSKeyFile {key_file if key_file else cert_file}", + ]) + else: + raise Exception(f"unsupported ssl module: {ssl_module}") - def add_vhost(self, domains, port=None, doc_root="htdocs", with_ssl=None): - self.start_vhost(domains=domains, port=port, doc_root=doc_root, with_ssl=with_ssl) + def add_vhost(self, domains, port=None, doc_root="htdocs", with_ssl=None, + with_certificates=None, ssl_module=None): + self.start_vhost(domains=domains, port=port, doc_root=doc_root, + with_ssl=with_ssl, with_certificates=with_certificates, + ssl_module=ssl_module) self.end_vhost() return self - def start_vhost(self, domains, port=None, doc_root="htdocs", with_ssl=None): + def start_vhost(self, domains, port=None, doc_root="htdocs", with_ssl=None, + ssl_module=None, with_certificates=None): if not isinstance(domains, list): domains = [domains] if port is None: port = self.env.https_port + if ssl_module is None: + ssl_module = self.env.ssl_module if with_ssl is None: - with_ssl = (self.env.https_port == port) + with_ssl = self.env.https_port == port + if with_ssl and ssl_module == 'mod_tls' and port not in self._tls_engine_ports: + self.add(f"TLSEngine {port}") + self._tls_engine_ports.add(port) self.add("") self.add(f"") self._indents += 1 @@ -67,10 +84,13 @@ class HttpdConf(object): self.add(f"ServerAlias {alias}") self.add(f"DocumentRoot {doc_root}") if with_ssl: - if self.env.ssl_module == "ssl": + if ssl_module == 'mod_ssl': self.add("SSLEngine on") - for cred in self.env.get_credentials_for_name(domains[0]): - self.add_certificate(cred.cert_file, cred.pkey_file) + elif ssl_module == 'mod_gnutls': + self.add("GnuTLSEnable on") + if with_certificates is not False: + for cred in self.env.get_credentials_for_name(domains[0]): + self.add_certificate(cred.cert_file, cred.pkey_file, ssl_module=ssl_module) if domains[0] in self._extras: self.add(self._extras[domains[0]]) return self diff --git a/test/pyhttpd/env.py b/test/pyhttpd/env.py index 73044ae40b1..be28e997905 100644 --- a/test/pyhttpd/env.py +++ b/test/pyhttpd/env.py @@ -72,9 +72,7 @@ class HttpdTestSetup: self._source_dirs.append(source_dir) def add_modules(self, modules: List[str]): - for m in modules: - if m not in self._modules: - self._modules.append(m) + self._modules.extend(modules) def make(self): self._make_dirs() @@ -122,11 +120,17 @@ class HttpdTestSetup: fd.write(t.substitute(var_map)) def _make_modules_conf(self): + loaded = set() modules_conf = os.path.join(self.env.server_dir, 'conf/modules.conf') with open(modules_conf, 'w') as fd: # issue load directives for all modules we want that are shared missing_mods = list() for m in self._modules: + match = re.match(r'^mod_(.+)$', m) + if match: + m = match.group(1) + if m in loaded: + continue mod_path = os.path.join(self.env.libexec_dir, f"mod_{m}.so") if os.path.isfile(mod_path): fd.write(f"LoadModule {m}_module \"{mod_path}\"\n") @@ -134,6 +138,7 @@ class HttpdTestSetup: fd.write(f"#built static: LoadModule {m}_module \"{mod_path}\"\n") else: missing_mods.append(m) + loaded.add(m) if len(missing_mods) > 0: raise Exception(f"Unable to find modules: {missing_mods} " f"DSOs: {self.env.dso_modules}") @@ -162,7 +167,7 @@ class HttpdTestEnv: @classmethod def get_ssl_module(cls): - return os.environ['SSL'] if 'SSL' in os.environ else 'ssl' + return os.environ['SSL'] if 'SSL' in os.environ else 'mod_ssl' def __init__(self, pytestconfig=None): self._our_dir = os.path.dirname(inspect.getfile(Dummy))