Skip to content
Open
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
Empty file added test/modules/__init__.py
Empty file.
Empty file added test/modules/ssl/__init__.py
Empty file.
38 changes: 38 additions & 0 deletions test/modules/ssl/conftest.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import logging
import os
import pytest
import sys

from .env import SSLTestEnv
from pyhttpd.env import HttpdTestEnv

sys.path.append(os.path.join(os.path.dirname(__file__), '../..'))

def pytest_report_header(config, startdir):
env = SSLTestEnv()
return f"mod_ssl [apache: {env.get_httpd_version()}, mpm: {env.mpm_module}, {env.prefix}]"


@pytest.fixture(scope="package")
def env(pytestconfig) -> SSLTestEnv:
level = logging.INFO
console = logging.StreamHandler()
console.setLevel(level)
console.setFormatter(logging.Formatter('%(levelname)s: %(message)s'))
logging.getLogger('').addHandler(console)
logging.getLogger('').setLevel(level=level)
env = SSLTestEnv(pytestconfig=pytestconfig)
env.setup_httpd()
env.apache_access_log_clear()
env.httpd_error_log.clear_log()
return env

@pytest.fixture(autouse=True, scope="package")
def require_openssl(env):
if not env.has_tool("openssl"):
pytest.skip("openssl not installed")

@pytest.fixture(autouse=True, scope="package")
def _stop_package_scope(env):
yield
assert env.apache_stop() == 0
24 changes: 24 additions & 0 deletions test/modules/ssl/env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import inspect
import logging
import os

from pyhttpd.env import HttpdTestEnv, HttpdTestSetup

log = logging.getLogger(__name__)


class SSLTestSetup(HttpdTestSetup):

def __init__(self, env: 'HttpdTestEnv'):
super().__init__(env=env)
self.add_source_dir(os.path.dirname(inspect.getfile(SSLTestSetup)))
self.add_modules(["ssl"])

class SSLTestEnv(HttpdTestEnv):

def __init__(self, pytestconfig=None):
super().__init__(pytestconfig=pytestconfig)
self.add_httpd_log_modules(["http", "ssl", "core"])

def setup_httpd(self, setup: HttpdTestSetup = None):
super().setup_httpd(setup=SSLTestSetup(env=self))
36 changes: 36 additions & 0 deletions test/modules/ssl/test_001_sni.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
import os
import pytest

from pyhttpd.conf import HttpdConf

class TestSNI:
LOG_FILE = "test_sni.log"

@pytest.fixture(autouse=True, scope="class")
def _class_scope(self, env):
conf = HttpdConf(env, extras={
"base":
f'CustomLog logs/{self.LOG_FILE} "%{{SSL_TLS_SNI}}x"'
})
conf.add_vhost_test1()
conf.install()
assert env.apache_restart() == 0

# tests sni escaped characters
def test_ssl_001_01(self, env):
log_path = os.path.join(env.server_logs_dir, self.LOG_FILE)

open(log_path, 'wb').close()

env.run(args=[
'openssl', 's_client',
'-connect', f"localhost:{env.https_port}",
'-servername', "httpd\x01\x0a2024\".org",
'-crlf', '-ign_eof'
], intext="GET / HTTP/1.1\n\n")

with open(log_path, 'rb') as f:
log_content = f.read()

assert b'httpd\x01\n2024' not in log_content, \
f"found unescaped characters in {self.LOG_FILE}.log"
3 changes: 2 additions & 1 deletion test/pyhttpd/conf.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,8 @@ def replaceinstr(self, line):
# In fact it should go in the corresponding VirtualHost... Not sure how to do that.
l = "SSLEngine On"
else:
if line != "":
# conflict with the SSL_TLS_SNI
if line.lstrip().startswith("TLS"):
l = line.replace("TLS", "SSL")
else:
l = line
Expand Down
2 changes: 2 additions & 0 deletions test/pyhttpd/env.py
Original file line number Diff line number Diff line change
Expand Up @@ -921,3 +921,5 @@ def make_data_file(self, indir: str, fname: str, fsize: int) -> str:
fd.write(s[0:remain])
return fpath

def has_tool(self, name: str) -> bool:
return bool(shutil.which(name))