summaryrefslogtreecommitdiffstats
path: root/debian/perl-framework/t/ssl
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 15:01:31 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-07 15:01:31 +0000
commitc9cf025fadfe043f0f2f679e10d1207d8a158bb6 (patch)
tree3a94effe0bdc0a6814d8134f4ed840d7cc6b6f19 /debian/perl-framework/t/ssl
parentAdding upstream version 2.4.57. (diff)
downloadapache2-debian.tar.xz
apache2-debian.zip
Adding debian version 2.4.57-2.debian/2.4.57-2debian
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'debian/perl-framework/t/ssl')
-rw-r--r--debian/perl-framework/t/ssl/all.t12
-rw-r--r--debian/perl-framework/t/ssl/basicauth.t45
-rw-r--r--debian/perl-framework/t/ssl/env.t89
-rw-r--r--debian/perl-framework/t/ssl/extlookup.t32
-rw-r--r--debian/perl-framework/t/ssl/fakeauth.t35
-rw-r--r--debian/perl-framework/t/ssl/headers.t28
-rw-r--r--debian/perl-framework/t/ssl/http.t48
-rw-r--r--debian/perl-framework/t/ssl/ocsp.t64
-rw-r--r--debian/perl-framework/t/ssl/pha.t47
-rw-r--r--debian/perl-framework/t/ssl/pr12355.t70
-rw-r--r--debian/perl-framework/t/ssl/pr43738.t43
-rw-r--r--debian/perl-framework/t/ssl/proxy.t120
-rw-r--r--debian/perl-framework/t/ssl/require.t55
-rw-r--r--debian/perl-framework/t/ssl/v2.t28
-rw-r--r--debian/perl-framework/t/ssl/varlookup.t266
-rw-r--r--debian/perl-framework/t/ssl/verify.t39
16 files changed, 1021 insertions, 0 deletions
diff --git a/debian/perl-framework/t/ssl/all.t b/debian/perl-framework/t/ssl/all.t
new file mode 100644
index 0000000..d3965d8
--- /dev/null
+++ b/debian/perl-framework/t/ssl/all.t
@@ -0,0 +1,12 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+my $vars = Apache::Test::vars();
+
+#skip all tests in this directory unless ssl is enabled
+#and LWP has https support
+plan tests => 1, [$vars->{ssl_module_name}, qw(LWP::Protocol::https)];
+
+ok 1;
+
diff --git a/debian/perl-framework/t/ssl/basicauth.t b/debian/perl-framework/t/ssl/basicauth.t
new file mode 100644
index 0000000..dde2131
--- /dev/null
+++ b/debian/perl-framework/t/ssl/basicauth.t
@@ -0,0 +1,45 @@
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestConfig ();
+use Apache::TestUtil;
+
+#if keepalives are on, renegotiation not happen again once
+#a client cert is presented. so on test #3, the cert from #2
+#will be used. this test scenerio would never
+#happen in real-life, so just disable keepalives here.
+Apache::TestRequest::user_agent_keepalive(0);
+
+my $url = '/ssl-fakebasicauth/index.html';
+
+plan tests => 4, need need_auth, need_lwp;
+
+Apache::TestRequest::scheme('https');
+
+# With TLSv1.3 mod_ssl may return a better 403 error here, otherwise
+# expect a TLS alert which is represented as a 500 by LWP.
+ok t_cmp (GET_RC($url, cert => undef),
+ qr/^(500|403)$/,
+ "Getting $url with no cert"
+ );
+
+ok t_cmp (GET_RC($url, cert => 'client_snakeoil'),
+ 200,
+ "Getting $url with client_snakeoil cert"
+ );
+
+ok t_cmp (GET_RC($url, cert => 'client_ok'),
+ 401,
+ "Getting $url with client_ok cert"
+ );
+
+if (!have_min_apache_version("2.5.1")) {
+ skip "Colon in username test skipped.";
+}
+else {
+ ok t_cmp (GET_RC($url, cert => 'client_colon'),
+ 403,
+ "Getting $url with client_colon cert"
+ );
+}
diff --git a/debian/perl-framework/t/ssl/env.t b/debian/perl-framework/t/ssl/env.t
new file mode 100644
index 0000000..912a4dc
--- /dev/null
+++ b/debian/perl-framework/t/ssl/env.t
@@ -0,0 +1,89 @@
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+use Apache::TestUtil;
+use Apache::TestRequest;
+use Apache::TestConfig ();
+use Apache::TestSSLCA ();
+
+#if keepalives are on, renegotiation not happen again once
+#a client cert is presented.
+Apache::TestRequest::user_agent_keepalive(0);
+
+my $cert = 'client_snakeoil';
+
+my $server_expect =
+ Apache::TestSSLCA::dn_vars('ca', 'SERVER_I');
+
+my $client_expect =
+ Apache::TestSSLCA::dn_vars($cert, 'CLIENT_S');
+
+my $url = '/ssl-cgi/env.pl';
+
+my $tests = (keys(%$server_expect) + keys(%$client_expect) + 1) * 2;
+plan tests => $tests, need need_cgi, need_lwp;
+
+Apache::TestRequest::scheme('https');
+
+my $r = GET($url);
+
+ok t_cmp($r->code, 200, "response status OK");
+
+my $env = getenv($r->as_string);
+
+verify($env, $server_expect);
+verify($env, $client_expect, 1);
+
+$url = '/require-ssl-cgi/env.pl';
+
+$r = GET($url, cert => $cert);
+
+ok t_cmp($r->code, 200, "second response status OK");
+
+$env = getenv($r->as_string);
+
+verify($env, $server_expect);
+verify($env, $client_expect);
+
+sub verify {
+ my($env, $expect, $ne) = @_;
+
+ while (my($key, $val) = each %$expect) {
+ # the emailAddress attribute is still exported using the name
+ # _DN_Email by mod_ssl, even when using OpenSSL 0.9.7.
+ if ($key =~ /(.*)_emailAddress/) {
+ $key = $1 . "_Email";
+ }
+ if (Apache::TestConfig::WIN32) {
+ #perl uppercases all %ENV keys
+ #which causes SSL_*_DN_Email lookups to fail
+ $key = uc $key;
+ }
+ unless ($ne || $env->{$key}) {
+ print "#$key does not exist\n";
+ $env->{$key} = ""; #prevent use of unitialized value
+ }
+ if ($ne) {
+ print "#$key should not exist\n";
+ ok not exists $env->{$key};
+ }
+ else {
+ print "#$key: expect '$val', got '$env->{$key}'\n";
+ ok $env->{$key} eq $val;
+ }
+ }
+}
+
+sub getenv {
+ my $str = shift;
+
+ my %env;
+
+ for my $line (split /[\r\n]+/, $str) {
+ my($key, $val) = split /\s*=\s*/, $line, 2;
+ next unless $key and $val;
+ $env{$key} = $val;
+ }
+
+ \%env;
+}
diff --git a/debian/perl-framework/t/ssl/extlookup.t b/debian/perl-framework/t/ssl/extlookup.t
new file mode 100644
index 0000000..d40e76e
--- /dev/null
+++ b/debian/perl-framework/t/ssl/extlookup.t
@@ -0,0 +1,32 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+Apache::TestRequest::scheme("https");
+
+my %exts = (
+ "2.16.840.1.113730.1.13" => "This Is A Comment"
+);
+
+if (have_min_apache_version("2.4.0")) {
+ $exts{"1.3.6.1.4.1.18060.12.0"} = "Lemons",
+}
+
+plan tests => 2 * (keys %exts), need 'test_ssl', need_min_apache_version(2.1);
+
+my ($actual, $expected, $r, $c);
+
+foreach (sort keys %exts) {
+ $r = GET("/test_ssl_ext_lookup?$_", cert => 'client_ok');
+
+ ok t_cmp($r->code, 200, "ssl_ext_lookup works for $_");
+
+ $c = $r->content;
+ chomp $c;
+
+ ok t_cmp($c, $exts{$_}, "Extension value match for $_");
+}
+
diff --git a/debian/perl-framework/t/ssl/fakeauth.t b/debian/perl-framework/t/ssl/fakeauth.t
new file mode 100644
index 0000000..9009cf4
--- /dev/null
+++ b/debian/perl-framework/t/ssl/fakeauth.t
@@ -0,0 +1,35 @@
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestConfig ();
+use Apache::TestUtil;
+
+# check fake authentication using mod_auth_anon
+# no cert should fail but the presence of any cert
+# should pass. see also t/ssl/basicauth.t
+
+my $url = '/ssl-fakebasicauth2/index.html';
+
+plan tests => 3, need need_auth,
+ need_module('mod_authn_anon'),
+ need_min_apache_version(2.1);
+
+Apache::TestRequest::scheme('https');
+
+# With TLSv1.3 mod_ssl may return a better 403 error here, otherwise
+# expect a TLS alert which is represented as a 500 by LWP.
+ok t_cmp (GET_RC($url, cert => undef),
+ qr/^(500|403)$/,
+ "Getting $url with no cert"
+ );
+
+ok t_cmp (GET_RC($url, cert => 'client_snakeoil'),
+ 200,
+ "Getting $url with client_snakeoil cert"
+ );
+
+ok t_cmp (GET_RC($url, cert => 'client_ok'),
+ 200,
+ "Getting $url with client_ok cert"
+ );
diff --git a/debian/perl-framework/t/ssl/headers.t b/debian/perl-framework/t/ssl/headers.t
new file mode 100644
index 0000000..825d6a9
--- /dev/null
+++ b/debian/perl-framework/t/ssl/headers.t
@@ -0,0 +1,28 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+my $tests = 3;
+
+plan tests => $tests, need need_lwp, need_module('headers', 'ssl');
+
+Apache::TestRequest::scheme('https');
+
+my $h = HEAD_STR "/modules/headers/ssl/";
+
+# look for 500 when mod_headers doesn't grok the %s tag
+if ($h =~ /^HTTP\/1.1 500 Internal Server Error\n/) {
+ foreach (1..$tests) {
+ skip "Skipping because mod_headers doesn't grok %s\n";
+ }
+ exit 0;
+}
+
+$h =~ s/Client-Bad-Header-Line:.*$//g;
+
+ok t_cmp($h, qr/X-SSL-Flag: on/, "SSLFlag header set");
+ok t_cmp($h, qr/X-SSL-Cert:.*END CERTIFICATE-----/, "SSL certificate is unwrapped");
+ok t_cmp($h, qr/X-SSL-None: \(null\)\n/, "unknown SSL variable not given");
diff --git a/debian/perl-framework/t/ssl/http.t b/debian/perl-framework/t/ssl/http.t
new file mode 100644
index 0000000..e556224
--- /dev/null
+++ b/debian/perl-framework/t/ssl/http.t
@@ -0,0 +1,48 @@
+use strict;
+use warnings FATAL => 'all';
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+BEGIN {
+ # prevent TestRequest from croaking on an HTTP/0.9 response
+ $ENV{APACHE_TEST_HTTP_09_OK} = 1;
+}
+
+#verify we can send an non-ssl http request to the ssl port
+#without dumping core.
+
+my $url = '/index.html';
+
+my @todo;
+
+if (Apache::TestConfig::WIN32) {
+ print "\n#ap_core_translate() chokes on ':' here\n",
+ "#where r->uri = /mod_ssl:error:HTTP-request\n";
+ @todo = (todo => [2]);
+}
+
+plan tests => 2, @todo, need_lwp;
+
+my $config = Apache::Test::config();
+my $ssl_module = $config->{vars}->{ssl_module_name};
+my $hostport = $config->{vhosts}->{$ssl_module}->{hostport};
+my $rurl = "http://$hostport$url";
+
+my $res = GET($rurl);
+my $proto = $res->protocol;
+
+if ($proto and $proto eq "HTTP/0.9") {
+ skip "server gave HTTP/0.9 response";
+} else {
+ ok t_cmp($res->code,
+ 400,
+ "Expected bad request from 'GET $rurl'"
+ );
+}
+
+ok t_cmp($res->content,
+ qr{speaking plain HTTP to an SSL-enabled server port},
+ "that error document contains the proper hint"
+ );
+
diff --git a/debian/perl-framework/t/ssl/ocsp.t b/debian/perl-framework/t/ssl/ocsp.t
new file mode 100644
index 0000000..8ec8505
--- /dev/null
+++ b/debian/perl-framework/t/ssl/ocsp.t
@@ -0,0 +1,64 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestSSLCA;
+use Apache::TestRequest;
+use Apache::TestConfig ();
+
+#if keepalives are on, renegotiation not happen again once
+#a client cert is presented. so on test #3, the cert from #2
+#will be used. this test scenerio would never
+#happen in real-life, so just disable keepalives here.
+Apache::TestRequest::user_agent_keepalive(0);
+
+my $url = '/index.html';
+
+Apache::TestRequest::scheme('https');
+Apache::TestRequest::module('ssl_ocsp');
+
+my $openssl = Apache::TestSSLCA::openssl();
+if (!have_min_apache_version('2.4.26')
+ or `$openssl list -commands 2>&1` !~ /ocsp/) {
+ print "1..0 # skip: No OpenSSL or mod_ssl OCSP support";
+ exit 0;
+}
+
+plan tests => 3, need_lwp;
+
+my $r;
+
+sok {
+ $r = GET $url, cert => undef;
+ my $message = $r->content() || '';
+ my $warning = $r->header('Client-Warning') || '';
+ print "warning: $warning\n";
+ print "message: $message";
+ print "response:\n";
+ print $r->as_string;
+ $r->code == 500 && $warning =~ 'Internal response' &&
+ $message =~ /alert handshake failure|read failed|closed connection without sending any data/;
+};
+
+sok {
+ $r = GET $url, cert => 'client_ok';
+ my $warning = $r->header('Client-Warning') || '';
+ my $message = $r->content() || '';
+ print "warning: $warning\n";
+ print "message: $message";
+ print "response:\n";
+ print $r->as_string;
+ $r->code == 200;
+};
+
+sok {
+ $r = GET $url, cert => 'client_revoked';
+ my $message = $r->content() || '';
+ my $warning = $r->header('Client-Warning') || '';
+ print "warning: $warning\n";
+ print "message: $message";
+ print "response:\n";
+ print $r->as_string;
+ $r->code == 500 && $warning =~ 'Internal response' &&
+ $message =~ /alert certificate revoked|read failed|closed connection without sending any data/;
+};
diff --git a/debian/perl-framework/t/ssl/pha.t b/debian/perl-framework/t/ssl/pha.t
new file mode 100644
index 0000000..2e2a763
--- /dev/null
+++ b/debian/perl-framework/t/ssl/pha.t
@@ -0,0 +1,47 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+use IO::Socket::SSL;
+
+# This is the equivalent of pr12355.t for TLSv1.3.
+
+Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'});
+Apache::TestRequest::scheme('https');
+Apache::TestRequest::user_agent_keepalive(1);
+
+my $r = GET "/";
+
+if (!$r->is_success) {
+ print "1..0 # skip: TLSv1.3 not supported";
+ exit 0;
+}
+
+if (!defined &IO::Socket::SSL::can_pha || !IO::Socket::SSL::can_pha()) {
+ print "1..0 # skip: PHA not supported by IO::Socket::SSL < 2.061";
+ exit 0;
+}
+
+plan tests => 4, need_min_apache_version("2.4.47");
+
+$r = GET("/verify/", cert => undef);
+ok t_cmp($r->code, 403, "access must be denied without client certificate");
+
+# SSLRenegBufferSize 10 for this location which should mean a 413
+# error.
+$r = POST("/require/small/perl_echo.pl", content => 'y'x101,
+ cert => 'client_ok');
+ok t_cmp($r->code, 413, "PHA reneg body buffer size restriction works");
+
+# Reset to use a new connection.
+Apache::TestRequest::user_agent(reset => 1);
+Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'});
+Apache::TestRequest::scheme('https');
+
+$r = POST("/verify/modules/cgi/perl_echo.pl", content => 'x'x10000,
+ cert => 'client_ok');
+
+ok t_cmp($r->code, 200, "PHA works with POST body");
+ok t_cmp($r->content, $r->request->content, "request body matches response");
diff --git a/debian/perl-framework/t/ssl/pr12355.t b/debian/perl-framework/t/ssl/pr12355.t
new file mode 100644
index 0000000..8444b3f
--- /dev/null
+++ b/debian/perl-framework/t/ssl/pr12355.t
@@ -0,0 +1,70 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 10, need 'ssl', need_min_apache_version('2.0');
+
+my $r;
+
+Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'});
+Apache::TestRequest::scheme('https');
+
+$r = GET "/";
+my $tls13_works = $r->is_success;
+
+# Forget the above user agent settings, start fresh
+Apache::TestRequest::user_agent(reset => 1);
+
+# If TLS 1.3 worked, downgrade to TLS 1.2, otherwise use what works.
+if ($tls13_works) {
+ t_debug "Downgrading to TLSv12";
+ Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL', SSL_version => 'TLSv12'});
+} else {
+ Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL'});
+}
+Apache::TestRequest::user_agent_keepalive(1);
+Apache::TestRequest::scheme('https');
+
+# Send a series of POST requests with varying size request bodies.
+# Alternate between the location which requires a AES128-SHA ciphersuite
+# and one which requires AES256-SHA; mod_ssl will attempt to perform the
+# renegotiation between each request, and hence needs to perform the
+# buffering of request body data.
+
+$r = POST "/require-aes256-cgi/perl_echo.pl", content => "hello world";
+
+ok t_cmp($r->code, 200, "renegotiation on POST works");
+ok t_cmp($r->content, "hello world", "request body matches response");
+
+$r = POST "/require-aes128-cgi/perl_echo.pl", content => "hello world";
+
+ok t_cmp($r->code, 200, "renegotiation on POST works");
+ok t_cmp($r->content, "hello world", "request body matches response");
+
+$r = POST "/require-aes256-cgi/perl_echo.pl", content => 'x'x10000;
+
+ok t_cmp($r->code, 200, "renegotiation on POST works");
+ok t_cmp($r->content, $r->request->content, "request body matches response");
+
+$r = POST "/require-aes128-cgi/perl_echo.pl", content => 'x'x60000;
+
+ok t_cmp($r->code, 200, "renegotiation on POST works");
+ok t_cmp($r->content, $r->request->content, "request body matches response");
+
+# Test that content-level input filters are still run as expected by
+# using a request which triggers the mod_case_filter_in:
+
+my @filter = ('X-AddInputFilter' => 'CaseFilterIn'); #mod_client_add_filter
+
+if (have_module('case_filter_in')) {
+ $r = POST "/require-aes256-cgi/perl_echo.pl", @filter, content => "hello";
+
+ ok t_cmp($r->code, 200, "renegotiation on POST works");
+ ok t_cmp($r->content, "HELLO", "request body matches response");
+} else {
+ skip "mod_case_filter_in not available" foreach (1..2);
+}
+
diff --git a/debian/perl-framework/t/ssl/pr43738.t b/debian/perl-framework/t/ssl/pr43738.t
new file mode 100644
index 0000000..6bf9ccf
--- /dev/null
+++ b/debian/perl-framework/t/ssl/pr43738.t
@@ -0,0 +1,43 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+
+plan tests => 4,
+ need 'ssl', need_module('actions'),
+ need_min_apache_version('2.2.7');
+
+my $r;
+
+Apache::TestRequest::user_agent(ssl_opts => {SSL_version => 'TLSv13'});
+Apache::TestRequest::scheme('https');
+
+$r = GET "/";
+my $tls13_works = $r->is_success;
+
+# Forget the above user agent settings, start fresh
+Apache::TestRequest::user_agent(reset => 1);
+
+# If TLS 1.3 worked, downgrade to TLS 1.2, otherwise use what works.
+if ($tls13_works) {
+ t_debug "Downgrading to TLSv12";
+ Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL', SSL_version => 'TLSv12'});
+} else {
+ Apache::TestRequest::user_agent(ssl_opts => {SSL_cipher_list => 'ALL'});
+}
+Apache::TestRequest::user_agent_keepalive(1);
+Apache::TestRequest::scheme('https');
+
+# Variation of the PR 12355 test which breaks per PR 43738.
+
+$r = POST "/modules/ssl/aes128/empty.pfa", content => "hello world";
+
+ok t_cmp($r->code, 200, "renegotiation on POST works");
+ok t_cmp($r->content, "/modules/ssl/aes128/empty.pfa\nhello world", "request body matches response");
+
+$r = POST "/modules/ssl/aes256/empty.pfa", content => "hello world";
+
+ok t_cmp($r->code, 200, "renegotiation on POST works");
+ok t_cmp($r->content, "/modules/ssl/aes256/empty.pfa\nhello world", "request body matches response");
diff --git a/debian/perl-framework/t/ssl/proxy.t b/debian/perl-framework/t/ssl/proxy.t
new file mode 100644
index 0000000..bec84b4
--- /dev/null
+++ b/debian/perl-framework/t/ssl/proxy.t
@@ -0,0 +1,120 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+use Apache::TestCommon ();
+
+my %frontend = (
+ proxy_http_https => 'http',
+ proxy_https_https => 'https',
+ proxy_https_http => 'https',
+ proxy_http_https_proxy_section => 'http',
+ proxy_https_https_proxy_section => 'https',
+);
+my %backend = (
+ proxy_http_https => 'https',
+ proxy_https_https => 'https',
+ proxy_https_http => 'http',
+ proxy_http_https_proxy_section => 'https',
+ proxy_https_https_proxy_section => 'https',
+);
+
+my $num_modules = scalar keys %frontend;
+my $post_module = 'eat_post';
+
+my $post_tests = have_module($post_module) ?
+ Apache::TestCommon::run_post_test_sizes() : 0;
+
+my $num_http_backends = 0;
+for my $module (sort keys %backend) {
+ if ($backend{$module} eq "http") {
+ $num_http_backends++;
+ }
+}
+
+plan tests => (8 + $post_tests) * $num_modules - 5 * $num_http_backends,
+ need need_lwp, [qw(mod_proxy proxy_http.c)];
+
+for my $module (sort keys %frontend) {
+
+ my $scheme = $frontend{$module};
+ Apache::TestRequest::module($module);
+ Apache::TestRequest::scheme($scheme);
+
+ my $hostport = Apache::TestRequest::hostport();
+ my $res;
+ my %vars;
+
+ sok {
+ t_cmp(GET('/')->code,
+ 200,
+ "/ with $module ($scheme)");
+ };
+
+ sok {
+ t_cmp(GET('/modules/cgi/nph-foldhdr.pl')->code,
+ 200,
+ "CGI script with folded headers");
+ };
+
+ if ($backend{$module} eq "https") {
+ sok {
+ t_cmp(GET('/verify')->code,
+ 200,
+ "using valid proxyssl client cert");
+ };
+
+ sok {
+ t_cmp(GET('/require/snakeoil')->code,
+ 403,
+ "using invalid proxyssl client cert");
+ };
+
+ $res = GET('/require-ssl-cgi/env.pl');
+
+ sok {
+ t_cmp($res->code, 200, "protected cgi script");
+ };
+
+ my $body = $res->content || "";
+
+ for my $line (split /\s*\r?\n/, $body) {
+ my($key, $val) = split /\s*=\s*/, $line, 2;
+ next unless $key;
+ $vars{$key} = $val || "";
+ }
+
+ sok {
+ t_cmp($vars{HTTP_X_FORWARDED_HOST},
+ $hostport,
+ "X-Forwarded-Host header");
+ };
+
+ sok {
+ t_cmp($vars{SSL_CLIENT_S_DN_CN},
+ 'client_ok',
+ "client subject common name");
+ };
+ }
+
+ sok {
+ #test that ProxyPassReverse rewrote the Location header
+ #to use the frontend server rather than downstream server
+ my $uri = '/modules';
+ my $ruri = Apache::TestRequest::resolve_url($uri) . '/';
+
+ #tell lwp not to follow redirect so we can see the Location header
+ local $Apache::TestRequest::RedirectOK = 0;
+
+ $res = GET($uri);
+
+ my $location = $res->header('Location') || 'NONE';
+
+ t_cmp($location, $ruri, 'ProxyPassReverse Location rewrite');
+ };
+
+ Apache::TestCommon::run_post_test($post_module) if $post_tests;
+ Apache::TestRequest::user_agent(reset => 1);
+}
diff --git a/debian/perl-framework/t/ssl/require.t b/debian/perl-framework/t/ssl/require.t
new file mode 100644
index 0000000..2a218d4
--- /dev/null
+++ b/debian/perl-framework/t/ssl/require.t
@@ -0,0 +1,55 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+
+#if keepalives are on, renegotiation not happen again once
+#a client cert is presented. so on test #3, the cert from #2
+#will be used. this test scenerio would never
+#happen in real-life, so just disable keepalives here.
+Apache::TestRequest::user_agent_keepalive(0);
+
+my $sslrequire_oid_needed_version = '2.1.7';
+my $have_sslrequire_oid = have_min_apache_version($sslrequire_oid_needed_version);
+
+plan tests => 10, need_lwp;
+
+Apache::TestRequest::scheme('https');
+
+my $url = '/require/asf/index.html';
+
+ok GET_RC($url, cert => undef) != 200;
+
+ok GET_RC($url, cert => 'client_ok') == 200;
+
+ok GET_RC($url, cert => 'client_revoked') != 200;
+
+$url = '/require/snakeoil/index.html';
+
+ok GET_RC($url, cert => 'client_ok') != 200;
+
+ok GET_RC($url, cert => 'client_snakeoil') == 200;
+
+ok GET_RC('/require/strcmp/index.html', cert => undef) == 200;
+
+ok GET_RC('/require/intcmp/index.html', cert => undef) == 200;
+
+if ($have_sslrequire_oid) {
+
+ $url = '/require/certext/index.html';
+
+ ok GET_RC($url, cert => undef) != 200;
+
+ if (!have_min_apache_version("2.4.0")) {
+ skip "not backported, see 2.2.19 vote thread for analysis";
+ }
+ else {
+ ok GET_RC($url, cert => 'client_ok') == 200;
+ }
+
+ ok GET_RC($url, cert => 'client_snakeoil') != 200;
+
+} else {
+ skip "skipping certificate extension test (httpd < $sslrequire_oid_needed_version)" foreach (1..3);
+}
diff --git a/debian/perl-framework/t/ssl/v2.t b/debian/perl-framework/t/ssl/v2.t
new file mode 100644
index 0000000..643c9d7
--- /dev/null
+++ b/debian/perl-framework/t/ssl/v2.t
@@ -0,0 +1,28 @@
+BEGIN {
+ $ENV{HTTPS_VERSION} = 2; #use SSLv2 instead of SSLv3
+}
+
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+
+plan tests => 1, need need_lwp,
+ { "SSLv2 test(s) not applicable" =>
+ sub { !need_min_apache_version('2.4.0') } };
+
+Apache::TestRequest::scheme('https');
+
+#just make sure the basics work for SSLv2
+ok GET_OK('/');
+
+#per-dir renegotiation does not work with SSLv2,
+#same breakage with apache-1.3.22+mod_ssl-2.8.5
+my $url = '/require/asf/index.html';
+
+#ok GET_RC($url, cert => undef) != 200;
+
+#ok GET_RC($url, cert => 'client_ok') == 200;
+
+#ok GET_RC($url, cert => 'client_revoked') != 200;
diff --git a/debian/perl-framework/t/ssl/varlookup.t b/debian/perl-framework/t/ssl/varlookup.t
new file mode 100644
index 0000000..e00a143
--- /dev/null
+++ b/debian/perl-framework/t/ssl/varlookup.t
@@ -0,0 +1,266 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestUtil;
+use Apache::TestSSLCA qw(dn dn_oneline);
+
+unless (have_lwp) {
+ # bail out early, since the parser below relies on $LWP::VERSION
+ plan tests => 0, need_lwp;
+}
+
+use Time::localtime;
+
+my $config = Apache::Test::config();
+my $vars = Apache::Test::vars();
+my $server = $config->server;
+my $time = localtime();
+
+(my $mmn = $config->{httpd_info}->{MODULE_MAGIC_NUMBER}) =~ s/:\d+$//;
+
+#Apache::TestRequest::scheme('https');
+local $vars->{scheme} = 'https';
+my $port = $config->port;
+my $rfc2253 = have_min_apache_version('2.3.11');
+
+my $url = '/test_ssl_var_lookup';
+my(%lookup, @vars);
+
+my %client_dn = dn('client_ok');
+
+my $client_dn = dn_oneline(\%client_dn, $rfc2253);
+
+my %client_i_dn = dn('ca');
+
+my $client_i_dn = dn_oneline(\%client_i_dn, $rfc2253);
+
+my %server_dn = dn('server');
+
+my $dgst = Apache::TestSSLCA::dgst();
+
+my $email_field = Apache::TestSSLCA::email_field();
+
+my $san_email = "$client_dn{$email_field}";
+
+my $san_dns = "$server_dn{CN}";
+
+my $san_msupn = $san_email;
+
+my $san_dnssrv = "_https.$server_dn{CN}";
+
+if (not have_min_apache_version('2.4.13')) {
+ $san_email = $san_dns = "NULL";
+}
+
+if (not have_min_apache_version('2.4.17') or
+ Apache::Test::normalize_vstring(Apache::TestSSLCA::version()) <
+ Apache::Test::normalize_vstring("0.9.8")) {
+ $san_msupn = $san_dnssrv = "NULL";
+}
+
+# YYY will be turned into a pattern match: httpd-test/([-\w]+)
+# so we can test with different server keys/certs
+$server_dn{OU} = 'httpd-test/YYY';
+$server_dn{CN} = $vars->{servername};
+
+my $server_dn = dn_oneline(\%server_dn, $rfc2253);
+
+$server_dn =~ s{(httpd-test.*?)YYY}{$1([-\\w]+)};
+$server_dn{OU} =~ s{(httpd-test.*?)YYY}{$1([-\\w]+)};
+
+my %server_i_dn = %client_i_dn;
+my $server_i_dn = $client_i_dn;
+
+my $cert_datefmt = '^\w{3} {1,2}\d{1,2} \d{2}:\d{2}:\d{2} \d{4} GMT$';
+
+while (<DATA>) {
+ chomp;
+ s/^\s+//; s/\s+$//;
+ s/\#.*//;
+ next unless $_;
+ my($key, $val) = split /\s+/, $_, 2;
+ next unless $key and $val;
+
+ if ($val =~ /^\"/) {
+ $val = eval qq($val);
+ }
+ elsif ($val =~ /^\'([^\']+)\'$/) {
+ $val = $1;
+ }
+ else {
+ $val = eval $val;
+ }
+
+ die $@ if $@;
+
+ $lookup{$key} = $val;
+ push @vars, $key;
+}
+
+if (not have_min_apache_version('2.4.32')) {
+ @vars = grep(!/_RAW/, @vars);
+}
+
+if (not have_min_apache_version('2.5.1')) {
+ @vars = grep(!/_B64CERT/, @vars);
+}
+
+plan tests => scalar (@vars), need need_lwp, need_module('test_ssl');
+
+for my $key (@vars) {
+ sok { verify($key); };
+}
+
+sub verify {
+ my $key = shift;
+ my @headers;
+ if ($key eq 'HTTP_REFERER') {
+ push @headers, Referer => $0;
+ }
+ my $str = GET_BODY("$url?$key", cert => 'client_ok',
+ @headers);
+ t_cmp($str, $lookup{$key}, "$key");
+}
+
+__END__
+#http://www.modssl.org/docs/2.8/ssl_reference.html#ToC23
+HTTP_USER_AGENT "libwww-perl/$LWP::VERSION",
+HTTP:User-Agent "libwww-perl/$LWP::VERSION",
+HTTP_REFERER "$0"
+HTTP_COOKIE
+HTTP_FORWARDED
+HTTP_HOST Apache::TestRequest::hostport()
+HTTP_PROXY_CONNECTION
+HTTP_ACCEPT
+
+#standard CGI variables
+PATH_INFO
+AUTH_TYPE
+QUERY_STRING 'QUERY_STRING'
+SERVER_SOFTWARE qr(^$server->{version})
+SERVER_ADMIN $vars->{serveradmin}
+SERVER_PORT "$port"
+SERVER_NAME $vars->{servername}
+SERVER_PROTOCOL qr(^HTTP/1\.\d$)
+REMOTE_IDENT
+REMOTE_ADDR $vars->{remote_addr}
+REMOTE_HOST
+REMOTE_USER
+DOCUMENT_ROOT $vars->{documentroot}
+REQUEST_METHOD 'GET'
+REQUEST_URI $url
+
+#mod_ssl specific variables
+TIME_YEAR $time->year()+1900
+TIME_MON sprintf "%02d", $time->mon()+1
+TIME_DAY sprintf "%02d", $time->mday()
+TIME_WDAY $time->wday()
+TIME
+TIME_HOUR
+TIME_MIN
+TIME_SEC
+
+IS_SUBREQ 'false'
+API_VERSION "$mmn"
+THE_REQUEST qr(^GET $url\?THE_REQUEST HTTP/1\.\d$)
+REQUEST_SCHEME $vars->{scheme}
+REQUEST_FILENAME
+HTTPS 'on'
+ENV:THE_ARGS 'ENV:THE_ARGS'
+
+#XXX: should use Net::SSLeay to parse the certs
+#rather than just pattern match and hardcode
+
+SSL_CLIENT_M_VERSION qr(^\d+$)
+SSL_SERVER_M_VERSION qr(^\d+$)
+SSL_CLIENT_M_SERIAL qr(^[0-9A-F]+$)
+SSL_SERVER_M_SERIAL qr(^[0-9A-F]+$)
+SSL_PROTOCOL qr((TLS|SSL)v([1-3]|1\.[0-3])$)
+SSL_CLIENT_V_START qr($cert_datefmt);
+SSL_SERVER_V_START qr($cert_datefmt);
+SSL_SESSION_ID
+SSL_CLIENT_V_END qr($cert_datefmt);
+SSL_SERVER_V_END qr($cert_datefmt);
+SSL_CIPHER qr(^[A-Z0-9_-]+$)
+SSL_CIPHER_EXPORT 'false'
+SSL_CIPHER_ALGKEYSIZE qr(^\d+$)
+SSL_CIPHER_USEKEYSIZE qr(^\d+$)
+SSL_SECURE_RENEG qr(^(false|true)$)
+
+SSL_CLIENT_S_DN "$client_dn"
+SSL_SERVER_S_DN qr(^$server_dn$)
+SSL_CLIENT_S_DN_C "$client_dn{C}"
+SSL_SERVER_S_DN_C "$server_dn{C}"
+SSL_CLIENT_S_DN_ST "$client_dn{ST}"
+SSL_SERVER_S_DN_ST "$server_dn{ST}"
+SSL_CLIENT_S_DN_L "$client_dn{L}"
+SSL_SERVER_S_DN_L "$server_dn{L}"
+SSL_CLIENT_S_DN_O "$client_dn{O}"
+SSL_SERVER_S_DN_O "$server_dn{O}"
+SSL_CLIENT_S_DN_OU "$client_dn{OU}"
+SSL_SERVER_S_DN_OU qr(^$server_dn{OU})
+SSL_CLIENT_S_DN_CN "$client_dn{CN}"
+SSL_SERVER_S_DN_CN "$server_dn{CN}"
+SSL_CLIENT_S_DN_T
+SSL_SERVER_S_DN_T
+SSL_CLIENT_S_DN_I
+SSL_SERVER_S_DN_I
+SSL_CLIENT_S_DN_G
+SSL_SERVER_S_DN_G
+SSL_CLIENT_S_DN_S
+SSL_SERVER_S_DN_S
+SSL_CLIENT_S_DN_D
+SSL_SERVER_S_DN_D
+SSL_CLIENT_S_DN_UID
+SSL_SERVER_S_DN_UID
+SSL_CLIENT_S_DN_Email "$client_dn{$email_field}"
+SSL_SERVER_S_DN_Email "$server_dn{$email_field}"
+SSL_CLIENT_SAN_Email_0 "$san_email"
+SSL_SERVER_SAN_DNS_0 "$san_dns"
+SSL_CLIENT_SAN_OTHER_msUPN_0 "$san_msupn"
+SSL_SERVER_SAN_OTHER_dnsSRV_0 "$san_dnssrv"
+
+SSL_CLIENT_I_DN "$client_i_dn"
+SSL_SERVER_I_DN "$server_i_dn"
+SSL_CLIENT_I_DN_C "$client_i_dn{C}"
+SSL_SERVER_I_DN_C "$server_i_dn{C}"
+SSL_CLIENT_I_DN_ST "$client_i_dn{ST}"
+SSL_SERVER_I_DN_ST "$server_i_dn{ST}"
+SSL_CLIENT_I_DN_L "$client_i_dn{L}"
+SSL_SERVER_I_DN_L "$server_i_dn{L}"
+SSL_CLIENT_I_DN_O "$client_i_dn{O}"
+SSL_SERVER_I_DN_O "$server_i_dn{O}"
+SSL_CLIENT_I_DN_OU "$client_i_dn{OU}"
+SSL_SERVER_I_DN_OU "$server_i_dn{OU}"
+SSL_CLIENT_I_DN_CN "$client_i_dn{CN}"
+SSL_SERVER_I_DN_CN "$server_i_dn{CN}"
+SSL_SERVER_I_DN_CN_RAW "$server_i_dn{CN}"
+SSL_SERVER_I_DN_CN_0_RAW "$server_i_dn{CN}"
+SSL_CLIENT_I_DN_T
+SSL_SERVER_I_DN_T
+SSL_CLIENT_I_DN_I
+SSL_SERVER_I_DN_I
+SSL_CLIENT_I_DN_G
+SSL_SERVER_I_DN_G
+SSL_CLIENT_I_DN_S
+SSL_SERVER_I_DN_S
+SSL_CLIENT_I_DN_D
+SSL_SERVER_I_DN_D
+SSL_CLIENT_I_DN_UID
+SSL_SERVER_I_DN_UID
+SSL_CLIENT_I_DN_Email "$client_i_dn{$email_field}"
+SSL_SERVER_I_DN_Email "$server_i_dn{$email_field}"
+SSL_CLIENT_A_SIG "${dgst}WithRSAEncryption"
+SSL_SERVER_A_SIG "${dgst}WithRSAEncryption"
+SSL_CLIENT_A_KEY 'rsaEncryption'
+SSL_SERVER_A_KEY qr(^[rd]saEncryption$)
+SSL_CLIENT_CERT qr(^-----BEGIN CERTIFICATE-----)
+SSL_SERVER_CERT qr(^-----BEGIN CERTIFICATE-----)
+SSL_CLIENT_B64CERT qr(^[a-zA-Z0-9+/]{64,}={0,2}$)
+SSL_SERVER_B64CERT qr(^[a-zA-Z0-9+/]{64,}={0,2}$)
+SSL_CLIENT_VERIFY 'SUCCESS'
+SSL_VERSION_LIBRARY
+SSL_VERSION_INTERFACE
+
diff --git a/debian/perl-framework/t/ssl/verify.t b/debian/perl-framework/t/ssl/verify.t
new file mode 100644
index 0000000..7bca845
--- /dev/null
+++ b/debian/perl-framework/t/ssl/verify.t
@@ -0,0 +1,39 @@
+use strict;
+use warnings FATAL => 'all';
+
+use Apache::Test;
+use Apache::TestRequest;
+use Apache::TestConfig ();
+
+#if keepalives are on, renegotiation not happen again once
+#a client cert is presented. so on test #3, the cert from #2
+#will be used. this test scenerio would never
+#happen in real-life, so just disable keepalives here.
+Apache::TestRequest::user_agent_keepalive(0);
+
+my $url = '/verify/index.html';
+
+plan tests => 3, need_lwp;
+
+Apache::TestRequest::scheme('https');
+
+my $r;
+
+sok {
+ $r = GET $url, cert => undef;
+ print $r->as_string;
+ $r->code != 200;
+};
+
+sok {
+ $r = GET $url, cert => 'client_ok';
+ print $r->as_string;
+ $r->code == 200;
+};
+
+sok {
+ $r = GET $url, cert => 'client_revoked';
+ print $r->as_string;
+ $r->code != 200;
+};
+