Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Arrange pytest to run with mod_ssl. Mostly skipping tests. #433

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 3 additions & 1 deletion test/modules/md/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,9 @@ def env(pytestconfig) -> MDTestEnv:
@pytest.fixture(autouse=True, scope="package")
def _md_package_scope(env):
env.httpd_error_log.add_ignored_lognos([
"AH10085" # There are no SSL certificates configured and no other module contributed any
"AH10085", # There are no SSL certificates configured and no other module contributed any
"AH10045", # No VirtualHost matches Managed Domain
"AH10105", # MDomain does not match any VirtualHost with 'SSLEngine on'
])


Expand Down
11 changes: 9 additions & 2 deletions test/modules/tls/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,10 @@ def __init__(self, env: HttpdTestEnv, extras: Dict[str, Any] = None):

def start_tls_vhost(self, domains: List[str], port=None, ssl_module=None):
if ssl_module is None:
ssl_module = 'mod_tls'
if not self.env.has_shared_module("tls"):
ssl_module = "mod_ssl"
else:
ssl_module = 'mod_tls'
super().start_vhost(domains=domains, port=port, doc_root=f"htdocs/{domains[0]}", ssl_module=ssl_module)

def end_tls_vhost(self):
Expand All @@ -39,8 +42,12 @@ def add_md_vhosts(self, domains: List[str], port = None):
f" MDCertificateKeyFile {pkey_file}",
])
self.add("</MDomain>")
if self.env.has_shared_module("tls"):
ssl_module= "mod_tls"
else:
ssl_module= "mod_ssl"
super().add_vhost(domains=[domain], port=port, doc_root=f"htdocs/{domain}",
with_ssl=True, with_certificates=False, ssl_module='mod_tls')
with_ssl=True, with_certificates=False, ssl_module=ssl_module)

def add_md_base(self, domain: str):
self.add([
Expand Down
5 changes: 4 additions & 1 deletion test/modules/tls/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -129,7 +129,10 @@ def __init__(self, pytestconfig=None):
]),
CertificateSpec(name="user1", client=True, single_file=True),
])
self.add_httpd_log_modules(['tls'])
if not HttpdTestEnv.has_shared_module("tls"):
self.add_httpd_log_modules(['ssl'])
else:
self.add_httpd_log_modules(['tls'])


def setup_httpd(self, setup: TlsTestSetup = None):
Expand Down
12 changes: 9 additions & 3 deletions test/modules/tls/test_02_conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -64,9 +64,15 @@ def test_tls_02_conf_cert_listen_wrong(self, env):
])
def test_tls_02_conf_cert_listen_valid(self, env, listen: str):
conf = TlsTestConf(env=env)
conf.add("TLSEngine {listen}".format(listen=listen))
conf.install()
assert env.apache_restart() == 0
if not env.has_shared_module("tls"):
# Without cert/key openssl will complain
conf.add("SSLEngine on");
conf.install()
assert env.apache_restart() == 1
else:
conf.add("TLSEngine {listen}".format(listen=listen))
conf.install()
assert env.apache_restart() == 0

def test_tls_02_conf_cert_listen_cert(self, env):
domain = env.domain_a
Expand Down
7 changes: 6 additions & 1 deletion test/modules/tls/test_06_ciphers.py
Original file line number Diff line number Diff line change
Expand Up @@ -181,7 +181,10 @@ def test_tls_06_ciphers_pref_unsupported(self, env):
})
conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
conf.install()
assert env.apache_restart() == 0
if not conf.env.has_shared_module("tls"):
assert env.apache_restart() != 0
else:
assert env.apache_restart() == 0
#
env.httpd_error_log.ignore_recent(
lognos = [
Expand All @@ -204,4 +207,6 @@ def test_tls_06_ciphers_supp_unsupported(self, env):
})
conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
conf.install()
if not conf.env.has_shared_module("tls"):
return
assert env.apache_restart() == 0
21 changes: 18 additions & 3 deletions test/modules/tls/test_08_vars.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,10 @@ def _class_scope(self, env):
def test_tls_08_vars_root(self, env):
# in domain_b root, the StdEnvVars is switch on
exp_proto = "TLSv1.2"
exp_cipher = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
if env.has_shared_module("tls"):
exp_cipher = "TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384"
else:
exp_cipher = "ECDHE-ECDSA-AES256-GCM-SHA384"
options = [ '--tls-max', '1.2']
r = env.tls_get(env.domain_b, "/vars.py", options=options)
assert r.exit_code == 0, r.stderr
Expand All @@ -47,7 +50,12 @@ def test_tls_08_vars_root(self, env):
def test_tls_08_vars_const(self, env, name: str, value: str):
r = env.tls_get(env.domain_b, f"/vars.py?name={name}")
assert r.exit_code == 0, r.stderr
assert r.json == {name: value}, r.stdout
if env.has_shared_module("tls"):
assert r.json == {name: value}, r.stdout
else:
if name == "SSL_SECURE_RENEG":
value = "true"
assert r.json == {name: value}, r.stdout

@pytest.mark.parametrize("name, pattern", [
("SSL_VERSION_INTERFACE", r'mod_tls/\d+\.\d+\.\d+'),
Expand All @@ -57,4 +65,11 @@ def test_tls_08_vars_match(self, env, name: str, pattern: str):
r = env.tls_get(env.domain_b, f"/vars.py?name={name}")
assert r.exit_code == 0, r.stderr
assert name in r.json
assert re.match(pattern, r.json[name]), r.json
if env.has_shared_module("tls"):
assert re.match(pattern, r.json[name]), r.json
else:
if name == "SSL_VERSION_INTERFACE":
pattern = r'mod_ssl/\d+\.\d+\.\d+'
else:
pattern = r'OpenSSL/\d+\.\d+\.\d+'
assert re.match(pattern, r.json[name]), r.json
42 changes: 40 additions & 2 deletions test/modules/tls/test_14_proxy_ssl.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,20 @@
import pytest

from .conf import TlsTestConf
from pyhttpd.env import HttpdTestEnv


class TestProxySSL:

@pytest.fixture(autouse=True, scope='class')
def _class_scope(self, env):
# add vhosts a+b and a ssl proxy from a to b
if not HttpdTestEnv.has_shared_module("tls"):
myoptions="SSLOptions +StdEnvVars"
myssl="mod_ssl"
else:
myoptions="TLSOptions +StdEnvVars"
myssl="mod_tls"
conf = TlsTestConf(env=env, extras={
'base': [
"LogLevel proxy:trace1 proxy_http:trace1 ssl:trace1 proxy_http2:trace1",
Expand All @@ -33,10 +40,10 @@ def _class_scope(self, env):
f'ProxyPass /proxy-ssl/ https://127.0.0.1:{env.https_port}/',
f'ProxyPass /proxy-local/ https://localhost:{env.https_port}/',
f'ProxyPass /proxy-h2-ssl/ h2://127.0.0.1:{env.https_port}/',
"TLSOptions +StdEnvVars",
myoptions,
],
})
conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b], ssl_module=myssl)
conf.install()
assert env.apache_restart() == 0

Expand Down Expand Up @@ -69,7 +76,24 @@ def test_tls_14_proxy_ssl_h2_get(self, env):
("SSL_CIPHER_EXPORT", "false"),
("SSL_CLIENT_VERIFY", "NONE"),
])
def test_tls_14_proxy_tsl_vars_const(self, env, name: str, value: str):
if not HttpdTestEnv.has_shared_module("tls"):
return
r = env.tls_get(env.domain_b, f"/proxy-ssl/vars.py?name={name}")
assert r.exit_code == 0, r.stderr
assert r.json == {name: value}, r.stdout

@pytest.mark.parametrize("name, value", [
("SERVER_NAME", "b.mod-tls.test"),
("SSL_SESSION_RESUMED", "Initial"),
("SSL_SECURE_RENEG", "true"),
("SSL_COMPRESS_METHOD", "NULL"),
("SSL_CIPHER_EXPORT", "false"),
("SSL_CLIENT_VERIFY", "NONE"),
])
def test_tls_14_proxy_ssl_vars_const(self, env, name: str, value: str):
if HttpdTestEnv.has_shared_module("tls"):
return
r = env.tls_get(env.domain_b, f"/proxy-ssl/vars.py?name={name}")
assert r.exit_code == 0, r.stderr
assert r.json == {name: value}, r.stdout
Expand All @@ -78,7 +102,21 @@ def test_tls_14_proxy_ssl_vars_const(self, env, name: str, value: str):
("SSL_VERSION_INTERFACE", r'mod_tls/\d+\.\d+\.\d+'),
("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+\.\d+'),
])
def test_tls_14_proxy_tsl_vars_match(self, env, name: str, pattern: str):
if not HttpdTestEnv.has_shared_module("tls"):
return
r = env.tls_get(env.domain_b, f"/proxy-ssl/vars.py?name={name}")
assert r.exit_code == 0, r.stderr
assert name in r.json
assert re.match(pattern, r.json[name]), r.json

@pytest.mark.parametrize("name, pattern", [
("SSL_VERSION_INTERFACE", r'mod_ssl/\d+\.\d+\.\d+'),
("SSL_VERSION_LIBRARY", r'OpenSSL/\d+\.\d+\.\d+'),
])
def test_tls_14_proxy_ssl_vars_match(self, env, name: str, pattern: str):
if HttpdTestEnv.has_shared_module("tls"):
return
r = env.tls_get(env.domain_b, f"/proxy-ssl/vars.py?name={name}")
assert r.exit_code == 0, r.stderr
assert name in r.json
Expand Down
2 changes: 2 additions & 0 deletions test/modules/tls/test_15_proxy_tls.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,9 @@
import pytest

from .conf import TlsTestConf
from pyhttpd.env import HttpdTestEnv

@pytest.mark.skipif(condition=not HttpdTestEnv.has_shared_module("tls"), reason="no mod_tls available")

class TestProxyTLS:

Expand Down
3 changes: 3 additions & 0 deletions test/modules/tls/test_16_proxy_mixed.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
import pytest

from .conf import TlsTestConf
from pyhttpd.env import HttpdTestEnv

@pytest.mark.skipif(condition=not HttpdTestEnv.has_shared_module("tls"), reason="no mod_tls available")


class TestProxyMixed:
Expand Down
3 changes: 2 additions & 1 deletion test/modules/tls/test_17_proxy_machine_cert.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,9 @@
import pytest

from .conf import TlsTestConf
from pyhttpd.env import HttpdTestEnv


@pytest.mark.skipif(condition=not HttpdTestEnv.has_shared_module("tls"), reason="no mod_tls available")
class TestProxyMachineCert:

@pytest.fixture(autouse=True, scope='class')
Expand Down
87 changes: 84 additions & 3 deletions test/pyhttpd/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,15 +26,96 @@ def __repr__(self):
def install(self):
self.env.install_test_conf(self._lines)

def replacetlsstr(self, line):
l = line.replace("TLS_", "")
l = l.replace("\n", " ")
l = l.replace("\\", " ")
l = " ".join(l.split())
l = l.replace(" ", ":")
l = l.replace("_", "-")
l = l.replace("-WITH", "")
l = l.replace("AES-", "AES")
l = l.replace("POLY1305-SHA256", "POLY1305")
return l

def replaceinstr(self, line):
if line.startswith("TLSCiphersPrefer"):
# the "TLS_" are changed into "".
l = self.replacetlsstr(line)
l = l.replace("TLSCiphersPrefer:", "SSLCipherSuite ")
elif line.startswith("TLSCiphersSuppress"):
# like SSLCipherSuite but with :!
l = self.replacetlsstr(line)
l = l.replace("TLSCiphersSuppress:", "SSLCipherSuite !")
l = l.replace(":", ":!")
elif line.startswith("TLSCertificate"):
l = line.replace("TLSCertificate", "SSLCertificateFile")
elif line.startswith("TLSProtocol"):
# mod_ssl is different (+ no supported and 0x code have to be translated)
l = line.replace("TLSProtocol", "SSLProtocol")
l = l.replace("+", "")
l = l.replace("default", "all")
l = l.replace("0x0303", "1.2") # need to check 1.3 and 1.1
elif line.startswith("SSLProtocol"):
l = line # we have that in test/modules/tls/test_05_proto.py
elif line.startswith("TLSHonorClientOrder"):
# mod_ssl has SSLHonorCipherOrder on = use server off = use client.
l = line.lower()
if "on" in l:
l = "SSLHonorCipherOrder off"
else:
l = "SSLHonorCipherOrder on"
elif line.startswith("TLSEngine"):
# In fact it should go in the corresponding VirtualHost... Not sure how to do that.
l = "SSLEngine On"
else:
if line != "":
l = line.replace("TLS", "SSL")
else:
l = line
return l

def add(self, line: Any):
# make we transform the TLS to SSL if we are using mod_ssl
if isinstance(line, str):
if not HttpdTestEnv.has_shared_module("tls"):
line = self.replaceinstr(line)
if self._indents > 0:
line = f"{' ' * self._indents}{line}"
self._lines.append(line)
else:
if self._indents > 0:
line = [f"{' ' * self._indents}{l}" for l in line]
self._lines.extend(line)
if not HttpdTestEnv.has_shared_module("tls"):
new = []
previous = ""
for l in line:
if previous.startswith("SSLCipherSuite"):
if l.startswith("TLSCiphersPrefer") or l.startswith("TLSCiphersSuppress"):
# we need to merge it
l = self.replaceinstr(l)
l = l.replace("SSLCipherSuite ", ":")
previous = previous + l
continue
else:
if self._indents > 0:
previous = f"{' ' * self._indents}{previous}"
new.append(previous)
previous = ""
l = self.replaceinstr(l)
if l.startswith("SSLCipherSuite"):
previous = l
continue
if self._indents > 0:
l = f"{' ' * self._indents}{l}"
new.append(l)
if previous != "":
if self._indents > 0:
previous = f"{' ' * self._indents}{previous}"
new.append(previous)
self._lines.extend(new)
else:
if self._indents > 0:
line = [f"{' ' * self._indents}{l}" for l in line]
self._lines.extend(line)
return self

def add_certificate(self, cert_file, key_file, ssl_module=None):
Expand Down