blob: 3386b35ca175bad8de3702d89b649b0262d57581 [file] [log] [blame]
Sergey Kandaurov2028d512020-10-22 18:55:53 +01001#!/usr/bin/perl
2
3# (C) Sergey Kandaurov
4# (C) Nginx, Inc.
5
6# Tests for http ssl module, ssl_reject_handshake.
7
8###############################################################################
9
10use warnings;
11use strict;
12
13use Test::More;
14
15BEGIN { use FindBin; chdir($FindBin::Bin); }
16
17use lib 'lib';
18use Test::Nginx;
19
20###############################################################################
21
22select STDERR; $| = 1;
23select STDOUT; $| = 1;
24
25eval { require IO::Socket::SSL; };
26plan(skip_all => 'IO::Socket::SSL not installed') if $@;
Sergey Kandaurovcd7507e2020-10-23 01:07:27 +010027eval { IO::Socket::SSL->can_client_sni() or die; };
28plan(skip_all => 'IO::Socket::SSL with OpenSSL SNI support required') if $@;
Sergey Kandaurov2028d512020-10-22 18:55:53 +010029
Sergey Kandaurovcd7507e2020-10-23 01:07:27 +010030my $t = Test::Nginx->new()->has(qw/http http_ssl sni/)->has_daemon('openssl');
Sergey Kandaurov2028d512020-10-22 18:55:53 +010031
32$t->write_file_expand('nginx.conf', <<'EOF');
33
34%%TEST_GLOBALS%%
35
36daemon off;
37
38events {
39}
40
41http {
42 %%TEST_GLOBALS_HTTP%%
43
44 add_header X-Name $ssl_server_name;
45
46 server {
47 listen 127.0.0.1:8080 ssl;
48 server_name localhost;
49
50 ssl_reject_handshake on;
51 }
52
53 server {
54 listen 127.0.0.1:8081;
55 server_name ssl;
56
57 ssl on;
58 ssl_reject_handshake on;
59 }
60
61 server {
62 listen 127.0.0.1:8080 ssl;
63 listen 127.0.0.1:8081 ssl;
64 server_name virtual;
65
66 ssl_certificate localhost.crt;
67 ssl_certificate_key localhost.key;
68 }
69
70 server {
71 listen 127.0.0.1:8082 ssl;
72 server_name localhost;
73
74 ssl_certificate localhost.crt;
75 ssl_certificate_key localhost.key;
76 }
77
78 server {
79 listen 127.0.0.1:8082 ssl;
80 server_name virtual1;
81 }
82
83 server {
84 listen 127.0.0.1:8082 ssl;
85 server_name virtual2;
86
87 ssl_reject_handshake on;
88 }
89}
90
91EOF
92
93$t->write_file('openssl.conf', <<EOF);
94[ req ]
95default_bits = 2048
96encrypt_key = no
97distinguished_name = req_distinguished_name
98[ req_distinguished_name ]
99EOF
100
101my $d = $t->testdir();
102
103foreach my $name ('localhost') {
104 system('openssl req -x509 -new '
105 . "-config $d/openssl.conf -subj /CN=$name/ "
106 . "-out $d/$name.crt -keyout $d/$name.key "
107 . ">>$d/openssl.out 2>&1") == 0
108 or die "Can't create certificate for $name: $!\n";
109}
110
111$t->write_file('index.html', '');
Sergey Kandaurov3457b852021-06-01 16:40:18 +0300112
113# suppress deprecation warning
114
115open OLDERR, ">&", \*STDERR; close STDERR;
116$t->run()->plan(9);
117open STDERR, ">&", \*OLDERR;
Sergey Kandaurov2028d512020-10-22 18:55:53 +0100118
119###############################################################################
120
121# default virtual server rejected
122
123like(get('default', 8080), qr/unrecognized name/, 'default rejected');
124like(get(undef, 8080), qr/unrecognized name/, 'absent sni rejected');
125like(get('virtual', 8080), qr/virtual/, 'virtual accepted');
126
127# default virtual server rejected - ssl on
128
129like(get('default', 8081), qr/unrecognized name/, 'default rejected - ssl on');
130like(get('virtual', 8081), qr/virtual/, 'virtual accepted - ssl on');
131
132# non-default server "virtual2" rejected
133
134like(get('default', 8082), qr/default/, 'default accepted');
135like(get(undef, 8082), qr/200 OK(?!.*X-Name)/is, 'absent sni accepted');
136like(get('virtual1', 8082), qr/virtual1/, 'virtual 1 accepted');
137like(get('virtual2', 8082), qr/unrecognized name/, 'virtual 2 rejected');
138
139###############################################################################
140
141sub get {
142 my ($host, $port) = @_;
143 my $s = get_ssl_socket($host, $port) or return $@;
144 $host = 'localhost' if !defined $host;
145 my $r = http(<<EOF, socket => $s);
146GET / HTTP/1.0
147Host: $host
148
149EOF
150
151 $s->close();
152 return $r;
153}
154
155sub get_ssl_socket {
156 my ($host, $port) = @_;
157 my $s;
158
159 eval {
160 local $SIG{ALRM} = sub { die "timeout\n" };
161 local $SIG{PIPE} = sub { die "sigpipe\n" };
162 alarm(8);
163 $s = IO::Socket::SSL->new(
164 Proto => 'tcp',
165 PeerAddr => '127.0.0.1',
166 PeerPort => port($port),
167 SSL_hostname => $host,
168 SSL_verify_mode => IO::Socket::SSL::SSL_VERIFY_NONE(),
169 SSL_error_trap => sub { die $_[1] },
170 );
171 alarm(0);
172 };
173 alarm(0);
174
175 if ($@) {
176 log_in("died: $@");
177 return undef;
178 }
179
180 return $s;
181}
182
183###############################################################################