[PATCH 03 of 11] Tests: added has_feature() tests for IO::Socket::SSL
Sergey Kandaurov
pluknet at nginx.com
Wed May 3 16:20:02 UTC 2023
> On 17 Apr 2023, at 07:31, Maxim Dounin <mdounin at mdounin.ru> wrote:
>
> # HG changeset patch
> # User Maxim Dounin <mdounin at mdounin.ru>
> # Date 1681702252 -10800
> # Mon Apr 17 06:30:52 2023 +0300
> # Node ID f704912ed09f3494a815709710c3744b0adca50b
> # Parent 6f0148ef1991d92a003c8529c8cce9a8dd49e706
> Tests: added has_feature() tests for IO::Socket::SSL.
>
> The following distinct features supported:
>
> - "socket_ssl", which requires IO::Socket::SSL and also implies
> existance of the IO::Socket::SSL::SSL_VERIFY_NONE() symbol.
> It is used by most of the tests.
>
SSL_VERIFY_NONE was added in IO::Socket::SSL 1.31 (2009.09.25).
The check was added primarily for then supported CentOS 5.
Now CentOS 5 is long obsolete, SSL_VERIFY_NONE can be dropped.
Most popular modern distributions have something of IO::Socket::SSL 2.0xx,
the oldest still supported CentOS 7 has IO::Socket::SSL 1.94.
> - "socket_ssl_sni", which requires IO::Socket::SSL with the can_client_sni()
> function (1.84), and SNI support available in Net::SSLeay and the OpenSSL
> library being used. Used by ssl_sni.t, ssl_sni_sessions.t,
> stream_ssl_preread.t. Additional Net::SSLeay testing is believed to be
> unneeded and was removed.
>
I agree that Net::SSLeay is believed to be redundant: properly implemented
IO::Socket::SSL should detect Net::SSLeay is too old and behave accordingly.
Note that you removed can_client_sni() from h2_ssl_verify_client.t.
In fact, it is replaced with "socket_ssl_alpn". ALPN support was added
to IO::Socket::SSL after SNI, so it should work in practice, although not
evident. Formally, the "socket_ssl_sni" prerequisite needs to be added.
On the other way, can_client_sni() was added in 1.83, while SNI support
factually was added noticeably earlier - in version 1.56, via SSL_hostname.
Using IO::Socket::SSL 1.82 allowed me to run the following tests
that would be otherwise skipped due to socket_ssl_sni:
ssl_sni.t - replacing with "socket_ssl" is enough
stream_ssl_preread.t - replacing with "socket_ssl" is enough
ssl_sni_sessions.t - also needs SSL_VERIFY_NONE in get_ssl_socket()
to stop whining on old IO::Socket::SSL that presumably doesn't get it
from $ctx. It won't run anyway though due to IO::Socket::SSL version
is too old to support TLSv1.3 sessions.
If we tend to drop anything older than 1.94 (CentOS 7), then we can freely
drop "socket_ssl_sni" from the patch. SSL_hostname is already there.
diff --git a/lib/Test/Nginx.pm b/lib/Test/Nginx.pm
--- a/lib/Test/Nginx.pm
+++ b/lib/Test/Nginx.pm
@@ -244,15 +244,9 @@ sub has_feature($) {
if ($feature =~ /^socket_ssl/) {
eval { require IO::Socket::SSL; };
return 0 if $@;
- eval { IO::Socket::SSL::SSL_VERIFY_NONE(); };
- return 0 if $@;
if ($feature eq 'socket_ssl') {
return 1;
}
- if ($feature eq 'socket_ssl_sni') {
- eval { IO::Socket::SSL->can_client_sni() or die; };
- return !$@;
- }
if ($feature eq 'socket_ssl_alpn') {
eval { IO::Socket::SSL->can_alpn() or die; };
return !$@;
diff --git a/ssl_sni.t b/ssl_sni.t
--- a/ssl_sni.t
+++ b/ssl_sni.t
@@ -22,7 +22,7 @@ use Test::Nginx;
select STDERR; $| = 1;
select STDOUT; $| = 1;
-my $t = Test::Nginx->new()->has(qw/http http_ssl sni rewrite socket_ssl_sni/)
+my $t = Test::Nginx->new()->has(qw/http http_ssl sni rewrite socket_ssl/)
->has_daemon('openssl')->plan(8)
->write_file_expand('nginx.conf', <<'EOF');
diff --git a/ssl_sni_sessions.t b/ssl_sni_sessions.t
--- a/ssl_sni_sessions.t
+++ b/ssl_sni_sessions.t
@@ -21,7 +21,7 @@ use Test::Nginx;
select STDERR; $| = 1;
select STDOUT; $| = 1;
-my $t = Test::Nginx->new()->has(qw/http http_ssl sni rewrite socket_ssl_sni/)
+my $t = Test::Nginx->new()->has(qw/http http_ssl sni rewrite socket_ssl/)
->has_daemon('openssl')
->write_file_expand('nginx.conf', <<'EOF');
@@ -177,6 +177,7 @@ sub get_ssl_socket {
PeerPort => $port,
SSL_hostname => $host,
SSL_reuse_ctx => $ctx,
+ SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE(),
SSL_error_trap => sub { die $_[1] }
);
alarm(0);
diff --git a/stream_ssl_preread.t b/stream_ssl_preread.t
--- a/stream_ssl_preread.t
+++ b/stream_ssl_preread.t
@@ -24,7 +24,7 @@ select STDERR; $| = 1;
select STDOUT; $| = 1;
my $t = Test::Nginx->new()->has(qw/stream stream_map stream_ssl_preread/)
- ->has(qw/stream_ssl stream_return socket_ssl_sni/)
+ ->has(qw/stream_ssl stream_return socket_ssl/)
->has_daemon('openssl')->plan(13)
->write_file_expand('nginx.conf', <<'EOF');
> - "socket_ssl_alpn", which requires IO::Socket::SSL with ALPN support (2.009),
> and ALPN support in Net::SSLeay and the OpenSSL library being used.
> Used by h2_ssl.t, h2_ssl_verify_client.t, stream_ssl_alpn.t,
> stream_ssl_preread_alpn.t.
>
> - "socket_ssl_sslversion", which requires IO::Socket::SSL with
> the get_sslversion() and get_sslversion_int() methods (1.964).
> Used by mail_imap_ssl.t.
I don't like that the whole mail_imap_ssl.t is skipped on < 1.964
(even though it is not quite new and most distributions have it now),
because of a minor optional feature that could not be tested.
In principle, we can rewrite the test similar to $ssl_protocol
to avoid dependency on 1.964:
diff --git a/mail_imap_ssl.t b/mail_imap_ssl.t
--- a/mail_imap_ssl.t
+++ b/mail_imap_ssl.t
@@ -29,7 +29,7 @@ select STDOUT; $| = 1;
local $SIG{PIPE} = 'IGNORE';
my $t = Test::Nginx->new()
- ->has(qw/mail mail_ssl imap http rewrite socket_ssl_sslversion/)
+ ->has(qw/mail mail_ssl imap http rewrite socket_ssl/)
->has_daemon('openssl')->plan(13)
->write_file_expand('nginx.conf', <<'EOF');
@@ -209,12 +209,9 @@ my $s = Test::Nginx::IMAP->new(PeerAddr
# Auth-SSL-Protocol and Auth-SSL-Cipher headers
-my ($cipher, $sslversion);
+$s = get_ssl_socket(8143);
-$s = get_ssl_socket(8143);
-$cipher = $s->get_cipher();
-$sslversion = $s->get_sslversion();
-$sslversion =~ s/_/./;
+my $cipher = $s->get_cipher();
undef $s;
@@ -237,7 +234,7 @@ TODO: {
local $TODO = 'not yet' unless $t->has_version('1.21.2');
$f = $t->read_file('auth2.log');
-like($f, qr|^$cipher:$sslversion$|m, 'log - cipher sslversion');
+like($f, qr/^$cipher:(TLS|SSL)v(\d|\.)+$/m, 'log - cipher sslversion');
}
>
> - "socket_ssl_reused", which requires IO::Socket::SSL with
> the get_session_reused() method (2.057). To be used in the following
> patches.
>
> This makes it possible to simplify and unify various SSL tests.
[..]
--
Sergey Kandaurov
More information about the nginx-devel
mailing list