You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by ic...@apache.org on 2021/11/30 16:30:26 UTC
svn commit: r1895433 [2/2] - in /httpd/httpd/trunk/test/modules/tls: ./ htdocs/ htdocs/a.mod-tls.test/ htdocs/b.mod-tls.test/ htdocs/b.mod-tls.test/dir1/
Added: httpd/httpd/trunk/test/modules/tls/test_10_session_id.py
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/test/modules/tls/test_10_session_id.py?rev=1895433&view=auto
==============================================================================
--- httpd/httpd/trunk/test/modules/tls/test_10_session_id.py (added)
+++ httpd/httpd/trunk/test/modules/tls/test_10_session_id.py Tue Nov 30 16:30:26 2021
@@ -0,0 +1,50 @@
+import re
+from typing import List
+
+import pytest
+
+from pyhttpd.result import ExecResult
+from .env import TlsTestEnv
+from .conf import TlsTestConf
+
+
+class TestSessionID:
+
+ @pytest.fixture(autouse=True, scope='class')
+ def _class_scope(self, env):
+ conf = TlsTestConf(env=env)
+ conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 0
+
+ def find_openssl_session_ids(self, r: ExecResult) -> List[str]:
+ ids = []
+ for line in r.stdout.splitlines():
+ m = re.match(r'^\s*Session-ID: (\S+)$', line)
+ if m:
+ ids.append(m.group(1))
+ return ids
+
+ def test_10_session_id_12(self, env):
+ r = env.openssl_client(env.domain_b, extra_args=[
+ "-reconnect", "-tls1_2"
+ ])
+ session_ids = self.find_openssl_session_ids(r)
+ assert 1 < len(session_ids), "expected several session-ids: {0}, stderr={1}".format(
+ session_ids, r.stderr
+ )
+ assert 1 == len(set(session_ids)), "sesion-ids should all be the same: {0}".format(session_ids)
+
+ @pytest.mark.skipif(True or not TlsTestEnv.openssl_supports_tls_1_3(),
+ reason="openssl TLSv1.3 session storage test incomplete")
+ def test_10_session_id_13(self, env):
+ r = env.openssl_client(env.domain_b, extra_args=[
+ "-reconnect", "-tls1_3"
+ ])
+ # openssl -reconnect closes connection immediately after the handhshake, so
+ # the Session data in TLSv1.3 is not seen and not found in its output.
+ # FIXME: how to check session data with TLSv1.3?
+ session_ids = self.find_openssl_session_ids(r)
+ assert 0 == len(session_ids), "expected no session-ids: {0}, stderr={1}".format(
+ session_ids, r.stdout
+ )
Added: httpd/httpd/trunk/test/modules/tls/test_11_md.py
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/test/modules/tls/test_11_md.py?rev=1895433&view=auto
==============================================================================
--- httpd/httpd/trunk/test/modules/tls/test_11_md.py (added)
+++ httpd/httpd/trunk/test/modules/tls/test_11_md.py Tue Nov 30 16:30:26 2021
@@ -0,0 +1,37 @@
+import time
+from datetime import timedelta
+
+import pytest
+
+from .conf import TlsTestConf
+
+
+class TestMD:
+
+ @pytest.fixture(autouse=True, scope='class')
+ def _class_scope(self, env):
+ conf = TlsTestConf(env=env, extras={
+ 'base': "LogLevel md:trace4"
+ })
+ conf.add_md_vhosts(domains=[env.domain_a, env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 0
+
+ def test_11_get_a(self, env):
+ # do we see the correct json for the domain_a?
+ data = env.tls_get_json(env.domain_a, "/index.json")
+ assert data == {'domain': env.domain_a}
+
+ def test_11_get_b(self, env):
+ # do we see the correct json for the domain_a?
+ data = env.tls_get_json(env.domain_b, "/index.json")
+ assert data == {'domain': env.domain_b}
+
+ def test_11_get_base(self, env):
+ # give the base server domain_a and lookup its index.json
+ conf = TlsTestConf(env=env)
+ conf.add_md_base(domain=env.domain_a)
+ conf.install()
+ assert env.apache_restart() == 0
+ data = env.tls_get_json(env.domain_a, "/index.json")
+ assert data == {'domain': 'localhost'}
Added: httpd/httpd/trunk/test/modules/tls/test_12_cauth.py
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/test/modules/tls/test_12_cauth.py?rev=1895433&view=auto
==============================================================================
--- httpd/httpd/trunk/test/modules/tls/test_12_cauth.py (added)
+++ httpd/httpd/trunk/test/modules/tls/test_12_cauth.py Tue Nov 30 16:30:26 2021
@@ -0,0 +1,235 @@
+import os
+from datetime import timedelta
+from typing import Optional
+
+import pytest
+
+from pyhttpd.certs import Credentials
+from .conf import TlsTestConf
+
+
+@pytest.fixture
+def clients_x(env):
+ return env.ca.get_first("clientsX")
+
+
+@pytest.fixture
+def clients_y(env):
+ return env.ca.get_first("clientsY")
+
+
+@pytest.fixture
+def cax_file(clients_x):
+ return os.path.join(os.path.dirname(clients_x.cert_file), "clientX-ca.pem")
+
+
+@pytest.mark.skip(reason="client certs disabled")
+class TestTLS:
+
+ @pytest.fixture(autouse=True, scope='class')
+ def _class_scope(self, env, clients_x, cax_file):
+ with open(cax_file, 'w') as fd:
+ fd.write("".join(open(clients_x.cert_file).readlines()))
+ fd.write("".join(open(env.ca.cert_file).readlines()))
+
+ @pytest.fixture(autouse=True, scope='function')
+ def _function_scope(self, env):
+ if env.is_live(timeout=timedelta(milliseconds=100)):
+ assert env.apache_stop() == 0
+
+ def get_ssl_var(self, env, domain: str, cert: Optional[Credentials], name: str):
+ r = env.tls_get(domain, f"/vars.py?name={name}", options=[
+ "--cert", cert.cert_file
+ ] if cert else [])
+ assert r.exit_code == 0, r.stderr
+ assert r.json, r.stderr + r.stdout
+ return r.json[name] if name in r.json else None
+
+ def test_12_set_ca_non_existing(self, env):
+ conf = TlsTestConf(env=env, extras={
+ env.domain_a: "TLSClientCA xxx"
+ })
+ conf.add_md_vhosts(domains=[env.domain_a, env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 1
+
+ def test_12_set_ca_existing(self, env, cax_file):
+ conf = TlsTestConf(env=env, extras={
+ env.domain_a: f"TLSClientCA {cax_file}"
+ })
+ conf.add_md_vhosts(domains=[env.domain_a, env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 0
+
+ def test_12_set_auth_no_ca(self, env):
+ conf = TlsTestConf(env=env, extras={
+ env.domain_a: "TLSClientCertificate required"
+ })
+ conf.add_md_vhosts(domains=[env.domain_a, env.domain_b])
+ conf.install()
+ # will fail bc lacking clien CA
+ assert env.apache_restart() == 1
+
+ def test_12_auth_option_std(self, env, cax_file, clients_x):
+ conf = TlsTestConf(env=env, extras={
+ env.domain_b: [
+ f"TLSClientCertificate required",
+ f"TLSClientCA {cax_file}",
+ "# TODO: TLSUserName SSL_CLIENT_S_DN_CN",
+ "TLSOptions +StdEnvVars",
+ ]
+ })
+ conf.add_md_vhosts(domains=[env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 0
+ # should be denied
+ r = env.tls_get(domain=env.domain_b, paths="/index.json")
+ assert r.exit_code != 0, r.stdout
+ # should work
+ ccert = clients_x.get_first("user1")
+ data = env.tls_get_json(env.domain_b, "/index.json", options=[
+ "--cert", ccert.cert_file
+ ])
+ assert data == {'domain': env.domain_b}
+ r = env.tls_get(env.domain_b, "/vars.py?name=SSL_CLIENT_S_DN_CN")
+ assert r.exit_code != 0, "should have been prevented"
+ val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_S_DN_CN")
+ assert val == 'Not Implemented'
+ # TODO
+ # val = self.get_ssl_var(env, env.domain_b, ccert, "REMOTE_USER")
+ # assert val == 'Not Implemented'
+ # not set on StdEnvVars, needs option ExportCertData
+ val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_CERT")
+ assert val == ""
+
+ def test_12_auth_option_cert(self, env, test_ca, cax_file, clients_x):
+ conf = TlsTestConf(env=env, extras={
+ env.domain_b: [
+ "TLSClientCertificate required",
+ f"TLSClientCA {cax_file}",
+ "TLSOptions Defaults +ExportCertData",
+ ]
+ })
+ conf.add_md_vhosts(domains=[env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 0
+ ccert = clients_x.get_first("user1")
+ val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_CERT")
+ assert val == ccert.cert_pem.decode()
+ # no chain should be present
+ val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_CHAIN_0")
+ assert val == ''
+ val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_SERVER_CERT")
+ assert val
+ server_certs = test_ca.get_credentials_for_name(env.domain_b)
+ assert val in [c.cert_pem.decode() for c in server_certs]
+
+ def test_12_auth_ssl_optional(self, env, cax_file, clients_x):
+ domain = env.domain_b
+ conf = TlsTestConf(env=env, extras={
+ domain: [
+ "SSLVerifyClient optional",
+ "SSLVerifyDepth 2",
+ "SSLOptions +StdEnvVars +ExportCertData",
+ f"SSLCACertificateFile {cax_file}",
+ "SSLUserName SSL_CLIENT_S_DN",
+ ]
+ })
+ conf.add_ssl_vhosts(domains=[domain])
+ conf.install()
+ assert env.apache_restart() == 0
+ # should work either way
+ data = env.tls_get_json(domain, "/index.json")
+ assert data == {'domain': domain}
+ # no client cert given, we expect the server variable to be empty
+ val = self.get_ssl_var(env, env.domain_b, None, "SSL_CLIENT_S_DN_CN")
+ assert val == ''
+ ccert = clients_x.get_first("user1")
+ data = env.tls_get_json(domain, "/index.json", options=[
+ "--cert", ccert.cert_file
+ ])
+ assert data == {'domain': domain}
+ val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_S_DN_CN")
+ assert val == 'user1'
+ val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_S_DN")
+ assert val == 'O=abetterinternet-mod_tls,OU=clientsX,CN=user1'
+ val = self.get_ssl_var(env, env.domain_b, ccert, "REMOTE_USER")
+ assert val == 'O=abetterinternet-mod_tls,OU=clientsX,CN=user1'
+ val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_I_DN")
+ assert val == 'O=abetterinternet-mod_tls,OU=clientsX'
+ val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_I_DN_CN")
+ assert val == ''
+ val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_I_DN_OU")
+ assert val == 'clientsX'
+ val = self.get_ssl_var(env, env.domain_b, ccert, "SSL_CLIENT_CERT")
+ assert val == ccert.cert_pem.decode()
+
+ def test_12_auth_optional(self, env, cax_file, clients_x):
+ domain = env.domain_b
+ conf = TlsTestConf(env=env, extras={
+ domain: [
+ "TLSClientCertificate optional",
+ f"TLSClientCA {cax_file}",
+ ]
+ })
+ conf.add_md_vhosts(domains=[domain])
+ conf.install()
+ assert env.apache_restart() == 0
+ # should work either way
+ data = env.tls_get_json(domain, "/index.json")
+ assert data == {'domain': domain}
+ # no client cert given, we expect the server variable to be empty
+ r = env.tls_get(domain, "/vars.py?name=SSL_CLIENT_S_DN_CN")
+ assert r.exit_code == 0, r.stderr
+ assert r.json == {
+ 'SSL_CLIENT_S_DN_CN': '',
+ }, r.stdout
+ data = env.tls_get_json(domain, "/index.json", options=[
+ "--cert", clients_x.get_first("user1").cert_file
+ ])
+ assert data == {'domain': domain}
+ r = env.tls_get(domain, "/vars.py?name=SSL_CLIENT_S_DN_CN", options=[
+ "--cert", clients_x.get_first("user1").cert_file
+ ])
+ # with client cert, we expect the server variable to show? Do we?
+ assert r.exit_code == 0, r.stderr
+ assert r.json == {
+ 'SSL_CLIENT_S_DN_CN': 'Not Implemented',
+ }, r.stdout
+
+ def test_12_auth_expired(self, env, cax_file, clients_x):
+ conf = TlsTestConf(env=env, extras={
+ env.domain_b: [
+ "TLSClientCertificate required",
+ f"TLSClientCA {cax_file}",
+ ]
+ })
+ conf.add_md_vhosts(domains=[env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 0
+ # should not work
+ r = env.tls_get(domain=env.domain_b, paths="/index.json", options=[
+ "--cert", clients_x.get_first("user_expired").cert_file
+ ])
+ assert r.exit_code != 0
+
+ def test_12_auth_other_ca(self, env, cax_file, clients_y):
+ conf = TlsTestConf(env=env, extras={
+ env.domain_b: [
+ "TLSClientCertificate required",
+ f"TLSClientCA {cax_file}",
+ ]
+ })
+ conf.add_md_vhosts(domains=[env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 0
+ # should not work
+ r = env.tls_get(domain=env.domain_b, paths="/index.json", options=[
+ "--cert", clients_y.get_first("user1").cert_file
+ ])
+ assert r.exit_code != 0
+ # This will work, as the CA root is present in the CA file
+ r = env.tls_get(domain=env.domain_b, paths="/index.json", options=[
+ "--cert", env.ca.get_first("user1").cert_file
+ ])
+ assert r.exit_code == 0
Added: httpd/httpd/trunk/test/modules/tls/test_13_proxy.py
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/test/modules/tls/test_13_proxy.py?rev=1895433&view=auto
==============================================================================
--- httpd/httpd/trunk/test/modules/tls/test_13_proxy.py (added)
+++ httpd/httpd/trunk/test/modules/tls/test_13_proxy.py Tue Nov 30 16:30:26 2021
@@ -0,0 +1,40 @@
+from datetime import timedelta
+
+import pytest
+
+from .conf import TlsTestConf
+
+
+class TestProxy:
+
+ @pytest.fixture(autouse=True, scope='class')
+ def _class_scope(self, env):
+ conf = TlsTestConf(env=env, extras={
+ 'base': "LogLevel proxy:trace1 proxy_http:trace1 ssl:trace1",
+ env.domain_b: [
+ "ProxyPreserveHost on",
+ f'ProxyPass "/proxy/" "http://127.0.0.1:{env.http_port}/"',
+ f'ProxyPassReverse "/proxy/" "http://{env.domain_b}:{env.http_port}"',
+ ]
+ })
+ # add vhosts a+b and a ssl proxy from a to b
+ conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 0
+
+ def test_13_proxy_http_get(self, env):
+ data = env.tls_get_json(env.domain_b, "/proxy/index.json")
+ assert data == {'domain': env.domain_b}
+
+ @pytest.mark.parametrize("name, value", [
+ ("SERVER_NAME", "b.mod-tls.test"),
+ ("SSL_SESSION_RESUMED", ""),
+ ("SSL_SECURE_RENEG", ""),
+ ("SSL_COMPRESS_METHOD", ""),
+ ("SSL_CIPHER_EXPORT", ""),
+ ("SSL_CLIENT_VERIFY", ""),
+ ])
+ def test_13_proxy_http_vars(self, env, name: str, value: str):
+ r = env.tls_get(env.domain_b, f"/proxy/vars.py?name={name}")
+ assert r.exit_code == 0, r.stderr
+ assert r.json == {name: value}, r.stdout
Added: httpd/httpd/trunk/test/modules/tls/test_14_proxy_ssl.py
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/test/modules/tls/test_14_proxy_ssl.py?rev=1895433&view=auto
==============================================================================
--- httpd/httpd/trunk/test/modules/tls/test_14_proxy_ssl.py (added)
+++ httpd/httpd/trunk/test/modules/tls/test_14_proxy_ssl.py Tue Nov 30 16:30:26 2021
@@ -0,0 +1,78 @@
+import re
+import pytest
+
+from .conf import TlsTestConf
+
+
+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
+ conf = TlsTestConf(env=env, extras={
+ 'base': [
+ "LogLevel proxy:trace1 proxy_http:trace1 ssl:trace1 proxy_http2:trace1",
+ f"<Proxy https://127.0.0.1:{env.https_port}/>",
+ " SSLProxyEngine on",
+ " SSLProxyVerify require",
+ f" SSLProxyCACertificateFile {env.ca.cert_file}",
+ " ProxyPreserveHost on",
+ "</Proxy>",
+ f"<Proxy https://localhost:{env.https_port}/>",
+ " ProxyPreserveHost on",
+ "</Proxy>",
+ f"<Proxy h2://127.0.0.1:{env.https_port}/>",
+ " SSLProxyEngine on",
+ " SSLProxyVerify require",
+ f" SSLProxyCACertificateFile {env.ca.cert_file}",
+ " ProxyPreserveHost on",
+ "</Proxy>",
+ ],
+ env.domain_b: [
+ "Protocols h2 http/1.1",
+ 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",
+ ],
+ })
+ conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 0
+
+ def test_14_proxy_ssl_get(self, env):
+ data = env.tls_get_json(env.domain_b, "/proxy-ssl/index.json")
+ assert data == {'domain': env.domain_b}
+
+ def test_14_proxy_ssl_get_local(self, env):
+ # does not work, since SSLProxy* not configured
+ data = env.tls_get_json(env.domain_b, "/proxy-local/index.json")
+ assert data is None
+
+ def test_14_proxy_ssl_h2_get(self, env):
+ r = env.tls_get(env.domain_b, "/proxy-h2-ssl/index.json")
+ assert r.exit_code == 0
+ assert r.json == {'domain': env.domain_b}
+
+ @pytest.mark.parametrize("name, value", [
+ ("SERVER_NAME", "b.mod-tls.test"),
+ ("SSL_SESSION_RESUMED", "Initial"),
+ ("SSL_SECURE_RENEG", "false"),
+ ("SSL_COMPRESS_METHOD", "NULL"),
+ ("SSL_CIPHER_EXPORT", "false"),
+ ("SSL_CLIENT_VERIFY", "NONE"),
+ ])
+ def test_14_proxy_ssl_vars_const(self, env, name: str, value: str):
+ 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, pattern", [
+ ("SSL_VERSION_INTERFACE", r'mod_tls/\d+\.\d+\.\d+'),
+ ("SSL_VERSION_LIBRARY", r'rustls-ffi/\d+\.\d+\.\d+/rustls/\d+\.\d+\.\d+'),
+ ])
+ def test_14_proxy_ssl_vars_match(self, env, name: str, pattern: str):
+ 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
Added: httpd/httpd/trunk/test/modules/tls/test_15_proxy_tls.py
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/test/modules/tls/test_15_proxy_tls.py?rev=1895433&view=auto
==============================================================================
--- httpd/httpd/trunk/test/modules/tls/test_15_proxy_tls.py (added)
+++ httpd/httpd/trunk/test/modules/tls/test_15_proxy_tls.py Tue Nov 30 16:30:26 2021
@@ -0,0 +1,89 @@
+import re
+from datetime import timedelta
+
+import pytest
+
+from .conf import TlsTestConf
+
+
+class TestProxyTLS:
+
+ @pytest.fixture(autouse=True, scope='class')
+ def _class_scope(self, env):
+ # add vhosts a+b and a ssl proxy from a to b
+ conf = TlsTestConf(env=env, extras={
+ 'base': [
+ "LogLevel proxy:trace1 proxy_http:trace1 proxy_http2:trace2 http2:trace2 cgid:trace4",
+ "TLSProxyProtocol TLSv1.3+",
+ f"<Proxy https://127.0.0.1:{env.https_port}/>",
+ " TLSProxyEngine on",
+ f" TLSProxyCA {env.ca.cert_file}",
+ " TLSProxyProtocol TLSv1.2+",
+ " TLSProxyCiphersPrefer TLS13_AES_256_GCM_SHA384",
+ " TLSProxyCiphersSuppress TLS13_AES_128_GCM_SHA256",
+ " ProxyPreserveHost on",
+ "</Proxy>",
+ f"<Proxy https://localhost:{env.https_port}/>",
+ " ProxyPreserveHost on",
+ "</Proxy>",
+ f"<Proxy h2://127.0.0.1:{env.https_port}/>",
+ " TLSProxyEngine on",
+ f" TLSProxyCA {env.ca.cert_file}",
+ " TLSProxyCiphersSuppress TLS_AES_256_GCM_SHA384:TLS_AES_128_GCM_SHA256",
+ " ProxyPreserveHost on",
+ "</Proxy>",
+ ],
+ env.domain_b: [
+ "Protocols h2 http/1.1",
+ f"ProxyPass /proxy-tls/ https://127.0.0.1:{env.https_port}/",
+ f"ProxyPass /proxy-local/ https://localhost:{env.https_port}/",
+ f"ProxyPass /proxy-h2-tls/ h2://127.0.0.1:{env.https_port}/",
+ "TLSOptions +StdEnvVars",
+ ],
+ })
+ conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 0
+
+ def test_15_proxy_tls_get(self, env):
+ data = env.tls_get_json(env.domain_b, "/proxy-tls/index.json")
+ assert data == {'domain': env.domain_b}
+
+ def test_15_proxy_tls_get_local(self, env):
+ # does not work, since SSLProxy* not configured
+ data = env.tls_get_json(env.domain_b, "/proxy-local/index.json")
+ assert data is None
+
+ def test_15_proxy_tls_h2_get(self, env):
+ r = env.tls_get(env.domain_b, "/proxy-h2-tls/index.json")
+ assert r.exit_code == 0
+ assert r.json == {'domain': env.domain_b}, f"{r.stdout}"
+
+ @pytest.mark.parametrize("name, value", [
+ ("SERVER_NAME", "b.mod-tls.test"),
+ ("SSL_PROTOCOL", "TLSv1.3"),
+ ("SSL_CIPHER", "TLS_AES_256_GCM_SHA384"),
+ ("SSL_SESSION_RESUMED", "Initial"),
+ ("SSL_SECURE_RENEG", "false"),
+ ("SSL_COMPRESS_METHOD", "NULL"),
+ ("SSL_CIPHER_EXPORT", "false"),
+ ("SSL_CLIENT_VERIFY", "NONE"),
+ ])
+ def test_15_proxy_tls_h1_vars(self, env, name: str, value: str):
+ r = env.tls_get(env.domain_b, f"/proxy-tls/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"),
+ ("SERVER_NAME", "b.mod-tls.test"),
+ ("SERVER_NAME", "b.mod-tls.test"),
+ ("SERVER_NAME", "b.mod-tls.test"),
+ ("SSL_PROTOCOL", "TLSv1.3"),
+ ("SSL_CIPHER", "TLS_CHACHA20_POLY1305_SHA256"),
+ ("SSL_SESSION_RESUMED", "Initial"),
+ ])
+ def test_15_proxy_tls_h2_vars(self, env, name: str, value: str):
+ r = env.tls_get(env.domain_b, f"/proxy-h2-tls/vars.py?name={name}")
+ assert r.exit_code == 0, r.stderr
+ assert r.json == {name: value}, r.stdout
Added: httpd/httpd/trunk/test/modules/tls/test_16_proxy_mixed.py
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/test/modules/tls/test_16_proxy_mixed.py?rev=1895433&view=auto
==============================================================================
--- httpd/httpd/trunk/test/modules/tls/test_16_proxy_mixed.py (added)
+++ httpd/httpd/trunk/test/modules/tls/test_16_proxy_mixed.py Tue Nov 30 16:30:26 2021
@@ -0,0 +1,43 @@
+import pytest
+
+from .conf import TlsTestConf
+
+
+class TestProxyMixed:
+
+ @pytest.fixture(autouse=True, scope='class')
+ def _class_scope(self, env):
+ conf = TlsTestConf(env=env, extras={
+ 'base': [
+ "LogLevel proxy:trace1 proxy_http:trace1 ssl:trace1 proxy_http2:trace1",
+ "ProxyPreserveHost on",
+ ],
+ env.domain_a: [
+ "Protocols h2 http/1.1",
+ "TLSProxyEngine on",
+ f"TLSProxyCA {env.ca.cert_file}",
+ "<Location /proxy-tls/>",
+ f" ProxyPass h2://127.0.0.1:{env.https_port}/",
+ "</Location>",
+ ],
+ env.domain_b: [
+ "SSLProxyEngine on",
+ "SSLProxyVerify require",
+ f"SSLProxyCACertificateFile {env.ca.cert_file}",
+ "<Location /proxy-ssl/>",
+ f" ProxyPass https://127.0.0.1:{env.https_port}/",
+ "</Location>",
+ ],
+ })
+ # add vhosts a+b and a ssl proxy from a to b
+ conf.add_tls_vhosts(domains=[env.domain_a, env.domain_b])
+ conf.install()
+ assert env.apache_restart() == 0
+
+ def test_16_proxy_mixed_ssl_get(self, env):
+ data = env.tls_get_json(env.domain_b, "/proxy-ssl/index.json")
+ assert data == {'domain': env.domain_b}
+
+ def test_16_proxy_mixed_tls_get(self, env):
+ data = env.tls_get_json(env.domain_a, "/proxy-tls/index.json")
+ assert data == {'domain': env.domain_a}
Added: httpd/httpd/trunk/test/modules/tls/test_17_proxy_machine_cert.py
URL: http://svn.apache.org/viewvc/httpd/httpd/trunk/test/modules/tls/test_17_proxy_machine_cert.py?rev=1895433&view=auto
==============================================================================
--- httpd/httpd/trunk/test/modules/tls/test_17_proxy_machine_cert.py (added)
+++ httpd/httpd/trunk/test/modules/tls/test_17_proxy_machine_cert.py Tue Nov 30 16:30:26 2021
@@ -0,0 +1,69 @@
+import os
+
+import pytest
+
+from .conf import TlsTestConf
+
+
+class TestProxyMachineCert:
+
+ @pytest.fixture(autouse=True, scope='class')
+ def clients_x(cls, env):
+ return env.ca.get_first("clientsX")
+
+ @pytest.fixture(autouse=True, scope='class')
+ def clients_y(cls, env):
+ return env.ca.get_first("clientsY")
+
+ @pytest.fixture(autouse=True, scope='class')
+ def cax_file(cls, clients_x):
+ return os.path.join(os.path.dirname(clients_x.cert_file), "clientsX-ca.pem")
+
+ @pytest.fixture(autouse=True, scope='class')
+ def _class_scope(cls, env, cax_file, clients_x):
+ # add vhosts a(tls)+b(ssl, port2) and a ssl proxy from a to b with a machine cert
+ # host b requires a client certificate
+ conf = TlsTestConf(env=env, extras={
+ 'base': [
+ "LogLevel proxy:trace1 proxy_http:trace1 ssl:trace4 proxy_http2:trace1",
+ "ProxyPreserveHost on",
+ f"Listen {env.proxy_port}",
+ ],
+ })
+ conf.start_tls_vhost(domains=[env.domain_a], port=env.https_port)
+ conf.add([
+ "Protocols h2 http/1.1",
+ "TLSProxyEngine on",
+ f"TLSProxyCA {env.ca.cert_file}",
+ f"TLSProxyMachineCertificate {clients_x.get_first('user1').cert_file}",
+ "<Location /proxy-tls/>",
+ f" ProxyPass https://127.0.0.1:{env.proxy_port}/",
+ "</Location>",
+ ])
+ conf.end_tls_vhost()
+ conf.start_vhost(domains=[env.domain_a], port=env.proxy_port,
+ doc_root=f"htdocs/{env.domain_a}", with_ssl=True)
+ conf.add([
+ "SSLVerifyClient require",
+ "SSLVerifyDepth 2",
+ "SSLOptions +StdEnvVars +ExportCertData",
+ f"SSLCACertificateFile {cax_file}",
+ "SSLUserName SSL_CLIENT_S_DN_CN"
+ ])
+ conf.end_vhost()
+ conf.install()
+ assert env.apache_restart() == 0
+
+ def test_17_proxy_machine_cert_get_a(self, env):
+ data = env.tls_get_json(env.domain_a, "/proxy-tls/index.json")
+ assert data == {'domain': env.domain_a}
+
+ @pytest.mark.parametrize("name, value", [
+ ("SERVER_NAME", "a.mod-tls.test"),
+ ("SSL_CLIENT_VERIFY", "SUCCESS"),
+ ("REMOTE_USER", "user1"),
+ ])
+ def test_17_proxy_machine_cert_vars(self, env, name: str, value: str):
+ r = env.tls_get(env.domain_a, f"/proxy-tls/vars.py?name={name}")
+ assert r.exit_code == 0, r.stderr
+ assert r.json == {name: value}, r.stdout