diff options
Diffstat (limited to 'plugins/tests/check_http.t')
-rwxr-xr-x | plugins/tests/check_http.t | 256 |
1 files changed, 147 insertions, 109 deletions
diff --git a/plugins/tests/check_http.t b/plugins/tests/check_http.t index 188f5e75..ea11b2ac 100755 --- a/plugins/tests/check_http.t +++ b/plugins/tests/check_http.t | |||
@@ -3,16 +3,7 @@ | |||
3 | # Test check_http by having an actual HTTP server running | 3 | # Test check_http by having an actual HTTP server running |
4 | # | 4 | # |
5 | # To create the https server certificate: | 5 | # To create the https server certificate: |
6 | # openssl req -new -x509 -keyout server-key.pem -out server-cert.pem -days 3650 -nodes | 6 | # ./certs/generate-certs.sh |
7 | # to create a new expired certificate: | ||
8 | # faketime '2008-01-01 12:00:00' openssl req -new -x509 -keyout expired-key.pem -out expired-cert.pem -days 1 -nodes | ||
9 | # Country Name (2 letter code) [AU]:DE | ||
10 | # State or Province Name (full name) [Some-State]:Bavaria | ||
11 | # Locality Name (eg, city) []:Munich | ||
12 | # Organization Name (eg, company) [Internet Widgits Pty Ltd]:Monitoring Plugins | ||
13 | # Organizational Unit Name (eg, section) []: | ||
14 | # Common Name (e.g. server FQDN or YOUR name) []:Monitoring Plugins | ||
15 | # Email Address []:devel@monitoring-plugins.org | ||
16 | 7 | ||
17 | use strict; | 8 | use strict; |
18 | use Test::More; | 9 | use Test::More; |
@@ -23,7 +14,7 @@ $ENV{'LC_TIME'} = "C"; | |||
23 | 14 | ||
24 | my $common_tests = 70; | 15 | my $common_tests = 70; |
25 | my $virtual_port_tests = 8; | 16 | my $virtual_port_tests = 8; |
26 | my $ssl_only_tests = 8; | 17 | my $ssl_only_tests = 12; |
27 | # Check that all dependent modules are available | 18 | # Check that all dependent modules are available |
28 | eval "use HTTP::Daemon 6.01;"; | 19 | eval "use HTTP::Daemon 6.01;"; |
29 | plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; | 20 | plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; |
@@ -59,61 +50,87 @@ $HTTP::Daemon::VERSION = "1.00"; | |||
59 | my $port_http = 50000 + int(rand(1000)); | 50 | my $port_http = 50000 + int(rand(1000)); |
60 | my $port_https = $port_http + 1; | 51 | my $port_https = $port_http + 1; |
61 | my $port_https_expired = $port_http + 2; | 52 | my $port_https_expired = $port_http + 2; |
53 | my $port_https_clientcert = $port_http + 3; | ||
62 | 54 | ||
63 | # This array keeps sockets around for implementing timeouts | 55 | # This array keeps sockets around for implementing timeouts |
64 | my @persist; | 56 | my @persist; |
65 | 57 | ||
66 | # Start up all servers | 58 | # Start up all servers |
67 | my @pids; | 59 | my @pids; |
68 | my $pid = fork(); | 60 | # Fork a HTTP server |
69 | if ($pid) { | 61 | my $pid = fork; |
70 | # Parent | 62 | defined $pid or die "Failed to fork"; |
71 | push @pids, $pid; | 63 | if (!$pid) { |
72 | if (exists $servers->{https}) { | 64 | undef @pids; |
73 | # Fork a normal HTTPS server | ||
74 | $pid = fork(); | ||
75 | if ($pid) { | ||
76 | # Parent | ||
77 | push @pids, $pid; | ||
78 | # Fork an expired cert server | ||
79 | $pid = fork(); | ||
80 | if ($pid) { | ||
81 | push @pids, $pid; | ||
82 | } else { | ||
83 | my $d = HTTP::Daemon::SSL->new( | ||
84 | LocalPort => $port_https_expired, | ||
85 | LocalAddr => "127.0.0.1", | ||
86 | SSL_cert_file => "$Bin/certs/expired-cert.pem", | ||
87 | SSL_key_file => "$Bin/certs/expired-key.pem", | ||
88 | ) || die; | ||
89 | print "Please contact https expired at: <URL:", $d->url, ">\n"; | ||
90 | run_server( $d ); | ||
91 | exit; | ||
92 | } | ||
93 | } else { | ||
94 | # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise | ||
95 | local $SIG{'PIPE'} = 'IGNORE'; | ||
96 | my $d = HTTP::Daemon::SSL->new( | ||
97 | LocalPort => $port_https, | ||
98 | LocalAddr => "127.0.0.1", | ||
99 | SSL_cert_file => "$Bin/certs/server-cert.pem", | ||
100 | SSL_key_file => "$Bin/certs/server-key.pem", | ||
101 | ) || die; | ||
102 | print "Please contact https at: <URL:", $d->url, ">\n"; | ||
103 | run_server( $d ); | ||
104 | exit; | ||
105 | } | ||
106 | } | ||
107 | } else { | ||
108 | # Child | ||
109 | #print "child\n"; | ||
110 | my $d = HTTP::Daemon->new( | 65 | my $d = HTTP::Daemon->new( |
111 | LocalPort => $port_http, | 66 | LocalPort => $port_http, |
112 | LocalAddr => "127.0.0.1", | 67 | LocalAddr => "127.0.0.1", |
113 | ) || die; | 68 | ) || die; |
114 | print "Please contact http at: <URL:", $d->url, ">\n"; | 69 | print "Please contact http at: <URL:", $d->url, ">\n"; |
115 | run_server( $d ); | 70 | run_server( $d ); |
116 | exit; | 71 | die "webserver stopped"; |
72 | } | ||
73 | push @pids, $pid; | ||
74 | |||
75 | if (exists $servers->{https}) { | ||
76 | # Fork a normal HTTPS server | ||
77 | $pid = fork; | ||
78 | defined $pid or die "Failed to fork"; | ||
79 | if (!$pid) { | ||
80 | undef @pids; | ||
81 | # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise | ||
82 | local $SIG{'PIPE'} = 'IGNORE'; | ||
83 | my $d = HTTP::Daemon::SSL->new( | ||
84 | LocalPort => $port_https, | ||
85 | LocalAddr => "127.0.0.1", | ||
86 | SSL_cert_file => "$Bin/certs/server-cert.pem", | ||
87 | SSL_key_file => "$Bin/certs/server-key.pem", | ||
88 | ) || die; | ||
89 | print "Please contact https at: <URL:", $d->url, ">\n"; | ||
90 | run_server( $d ); | ||
91 | die "webserver stopped"; | ||
92 | } | ||
93 | push @pids, $pid; | ||
94 | |||
95 | # Fork an expired cert server | ||
96 | $pid = fork; | ||
97 | defined $pid or die "Failed to fork"; | ||
98 | if (!$pid) { | ||
99 | undef @pids; | ||
100 | # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise | ||
101 | local $SIG{'PIPE'} = 'IGNORE'; | ||
102 | my $d = HTTP::Daemon::SSL->new( | ||
103 | LocalPort => $port_https_expired, | ||
104 | LocalAddr => "127.0.0.1", | ||
105 | SSL_cert_file => "$Bin/certs/expired-cert.pem", | ||
106 | SSL_key_file => "$Bin/certs/expired-key.pem", | ||
107 | ) || die; | ||
108 | print "Please contact https expired at: <URL:", $d->url, ">\n"; | ||
109 | run_server( $d ); | ||
110 | die "webserver stopped"; | ||
111 | } | ||
112 | push @pids, $pid; | ||
113 | |||
114 | # Fork an client cert expecting server | ||
115 | $pid = fork; | ||
116 | defined $pid or die "Failed to fork"; | ||
117 | if (!$pid) { | ||
118 | undef @pids; | ||
119 | # closing the connection after -C cert checks make the daemon exit with a sigpipe otherwise | ||
120 | local $SIG{'PIPE'} = 'IGNORE'; | ||
121 | my $d = HTTP::Daemon::SSL->new( | ||
122 | LocalPort => $port_https_clientcert, | ||
123 | LocalAddr => "127.0.0.1", | ||
124 | SSL_cert_file => "$Bin/certs/server-cert.pem", | ||
125 | SSL_key_file => "$Bin/certs/server-key.pem", | ||
126 | SSL_verify_mode => IO::Socket::SSL->SSL_VERIFY_PEER | IO::Socket::SSL->SSL_VERIFY_FAIL_IF_NO_PEER_CERT, | ||
127 | SSL_ca_file => "$Bin/certs/clientca-cert.pem", | ||
128 | ) || die; | ||
129 | print "Please contact https client cert at: <URL:", $d->url, ">\n"; | ||
130 | run_server( $d ); | ||
131 | die "webserver stopped"; | ||
132 | } | ||
133 | push @pids, $pid; | ||
117 | } | 134 | } |
118 | 135 | ||
119 | # give our webservers some time to startup | 136 | # give our webservers some time to startup |
@@ -122,60 +139,62 @@ sleep(3); | |||
122 | # Run the same server on http and https | 139 | # Run the same server on http and https |
123 | sub run_server { | 140 | sub run_server { |
124 | my $d = shift; | 141 | my $d = shift; |
125 | MAINLOOP: while (my $c = $d->accept ) { | 142 | while (1) { |
126 | while (my $r = $c->get_request) { | 143 | MAINLOOP: while (my $c = $d->accept) { |
127 | if ($r->method eq "GET" and $r->url->path =~ m^/statuscode/(\d+)^) { | 144 | while (my $r = $c->get_request) { |
128 | $c->send_basic_header($1); | 145 | if ($r->method eq "GET" and $r->url->path =~ m^/statuscode/(\d+)^) { |
129 | $c->send_crlf; | 146 | $c->send_basic_header($1); |
130 | } elsif ($r->method eq "GET" and $r->url->path =~ m^/file/(.*)^) { | 147 | $c->send_crlf; |
131 | $c->send_basic_header; | 148 | } elsif ($r->method eq "GET" and $r->url->path =~ m^/file/(.*)^) { |
132 | $c->send_crlf; | 149 | $c->send_basic_header; |
133 | $c->send_file_response("$Bin/var/$1"); | 150 | $c->send_crlf; |
134 | } elsif ($r->method eq "GET" and $r->url->path eq "/slow") { | 151 | $c->send_file_response("$Bin/var/$1"); |
135 | $c->send_basic_header; | 152 | } elsif ($r->method eq "GET" and $r->url->path eq "/slow") { |
136 | $c->send_crlf; | 153 | $c->send_basic_header; |
137 | sleep 1; | 154 | $c->send_crlf; |
138 | $c->send_response("slow"); | 155 | sleep 1; |
139 | } elsif ($r->url->path eq "/method") { | 156 | $c->send_response("slow"); |
140 | if ($r->method eq "DELETE") { | 157 | } elsif ($r->url->path eq "/method") { |
141 | $c->send_error(HTTP::Status->RC_METHOD_NOT_ALLOWED); | 158 | if ($r->method eq "DELETE") { |
142 | } elsif ($r->method eq "foo") { | 159 | $c->send_error(HTTP::Status->RC_METHOD_NOT_ALLOWED); |
143 | $c->send_error(HTTP::Status->RC_NOT_IMPLEMENTED); | 160 | } elsif ($r->method eq "foo") { |
161 | $c->send_error(HTTP::Status->RC_NOT_IMPLEMENTED); | ||
162 | } else { | ||
163 | $c->send_status_line(200, $r->method); | ||
164 | } | ||
165 | } elsif ($r->url->path eq "/postdata") { | ||
166 | $c->send_basic_header; | ||
167 | $c->send_crlf; | ||
168 | $c->send_response($r->method.":".$r->content); | ||
169 | } elsif ($r->url->path eq "/redirect") { | ||
170 | $c->send_redirect( "/redirect2" ); | ||
171 | } elsif ($r->url->path eq "/redir_external") { | ||
172 | $c->send_redirect(($d->isa('HTTP::Daemon::SSL') ? "https" : "http") . "://169.254.169.254/redirect2" ); | ||
173 | } elsif ($r->url->path eq "/redirect2") { | ||
174 | $c->send_basic_header; | ||
175 | $c->send_crlf; | ||
176 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' )); | ||
177 | } elsif ($r->url->path eq "/redir_timeout") { | ||
178 | $c->send_redirect( "/timeout" ); | ||
179 | } elsif ($r->url->path eq "/timeout") { | ||
180 | # Keep $c from being destroyed, but prevent severe leaks | ||
181 | unshift @persist, $c; | ||
182 | delete($persist[1000]); | ||
183 | next MAINLOOP; | ||
184 | } elsif ($r->url->path eq "/header_check") { | ||
185 | $c->send_basic_header; | ||
186 | $c->send_header('foo'); | ||
187 | $c->send_crlf; | ||
188 | } elsif ($r->url->path eq "/virtual_port") { | ||
189 | # return sent Host header | ||
190 | $c->send_basic_header; | ||
191 | $c->send_crlf; | ||
192 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host'))); | ||
144 | } else { | 193 | } else { |
145 | $c->send_status_line(200, $r->method); | 194 | $c->send_error(HTTP::Status->RC_FORBIDDEN); |
146 | } | 195 | } |
147 | } elsif ($r->url->path eq "/postdata") { | 196 | $c->close; |
148 | $c->send_basic_header; | ||
149 | $c->send_crlf; | ||
150 | $c->send_response($r->method.":".$r->content); | ||
151 | } elsif ($r->url->path eq "/redirect") { | ||
152 | $c->send_redirect( "/redirect2" ); | ||
153 | } elsif ($r->url->path eq "/redir_external") { | ||
154 | $c->send_redirect(($d->isa('HTTP::Daemon::SSL') ? "https" : "http") . "://169.254.169.254/redirect2" ); | ||
155 | } elsif ($r->url->path eq "/redirect2") { | ||
156 | $c->send_basic_header; | ||
157 | $c->send_crlf; | ||
158 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, 'redirected' )); | ||
159 | } elsif ($r->url->path eq "/redir_timeout") { | ||
160 | $c->send_redirect( "/timeout" ); | ||
161 | } elsif ($r->url->path eq "/timeout") { | ||
162 | # Keep $c from being destroyed, but prevent severe leaks | ||
163 | unshift @persist, $c; | ||
164 | delete($persist[1000]); | ||
165 | next MAINLOOP; | ||
166 | } elsif ($r->url->path eq "/header_check") { | ||
167 | $c->send_basic_header; | ||
168 | $c->send_header('foo'); | ||
169 | $c->send_crlf; | ||
170 | } elsif ($r->url->path eq "/virtual_port") { | ||
171 | # return sent Host header | ||
172 | $c->send_basic_header; | ||
173 | $c->send_crlf; | ||
174 | $c->send_response(HTTP::Response->new( 200, 'OK', undef, $r->header ('Host'))); | ||
175 | } else { | ||
176 | $c->send_error(HTTP::Status->RC_FORBIDDEN); | ||
177 | } | 197 | } |
178 | $c->close; | ||
179 | } | 198 | } |
180 | } | 199 | } |
181 | } | 200 | } |
@@ -200,25 +219,44 @@ SKIP: { | |||
200 | skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https}; | 219 | skip "HTTP::Daemon::SSL not installed", $common_tests + $ssl_only_tests if ! exists $servers->{https}; |
201 | run_common_tests( { command => "$command -p $port_https", ssl => 1 } ); | 220 | run_common_tests( { command => "$command -p $port_https", ssl => 1 } ); |
202 | 221 | ||
222 | my $expiry = "Thu Nov 28 21:02:11 2030 +0000"; | ||
223 | |||
203 | $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); | 224 | $result = NPTest->testCmd( "$command -p $port_https -S -C 14" ); |
204 | is( $result->return_code, 0, "$command -p $port_https -S -C 14" ); | 225 | is( $result->return_code, 0, "$command -p $port_https -S -C 14" ); |
205 | is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on Fri Feb 16 15:31:44 2029 +0000.", "output ok" ); | 226 | is( $result->output, "OK - Certificate 'Monitoring Plugins' will expire on $expiry.", "output ok" ); |
206 | 227 | ||
207 | $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); | 228 | $result = NPTest->testCmd( "$command -p $port_https -S -C 14000" ); |
208 | is( $result->return_code, 1, "$command -p $port_https -S -C 14000" ); | 229 | is( $result->return_code, 1, "$command -p $port_https -S -C 14000" ); |
209 | like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); | 230 | like( $result->output, '/WARNING - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" ); |
210 | 231 | ||
211 | # Expired cert tests | 232 | # Expired cert tests |
212 | $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); | 233 | $result = NPTest->testCmd( "$command -p $port_https -S -C 13960,14000" ); |
213 | is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" ); | 234 | is( $result->return_code, 2, "$command -p $port_https -S -C 13960,14000" ); |
214 | like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(Fri Feb 16 15:31:44 2029 \+0000\)./', "output ok" ); | 235 | like( $result->output, '/CRITICAL - Certificate \'Monitoring Plugins\' expires in \d+ day\(s\) \(' . quotemeta($expiry) . '\)./', "output ok" ); |
215 | 236 | ||
216 | $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); | 237 | $result = NPTest->testCmd( "$command -p $port_https_expired -S -C 7" ); |
217 | is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" ); | 238 | is( $result->return_code, 2, "$command -p $port_https_expired -S -C 7" ); |
218 | is( $result->output, | 239 | is( $result->output, |
219 | 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 11:00:26 2008 +0000.', | 240 | 'CRITICAL - Certificate \'Monitoring Plugins\' expired on Wed Jan 2 12:00:00 2008 +0000.', |
220 | "output ok" ); | 241 | "output ok" ); |
221 | 242 | ||
243 | # client cert tests | ||
244 | my $cmd; | ||
245 | $cmd = "$command -p $port_https_clientcert" | ||
246 | . " -J \"$Bin/certs/client-cert.pem\"" | ||
247 | . " -K \"$Bin/certs/client-key.pem\"" | ||
248 | . " -u /statuscode/200"; | ||
249 | $result = NPTest->testCmd($cmd); | ||
250 | is( $result->return_code, 0, $cmd); | ||
251 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | ||
252 | |||
253 | $cmd = "$command -p $port_https_clientcert" | ||
254 | . " -J \"$Bin/certs/clientchain-cert.pem\"" | ||
255 | . " -K \"$Bin/certs/clientchain-key.pem\"" | ||
256 | . " -u /statuscode/200"; | ||
257 | $result = NPTest->testCmd($cmd); | ||
258 | is( $result->return_code, 0, $cmd); | ||
259 | like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); | ||
222 | } | 260 | } |
223 | 261 | ||
224 | my $cmd; | 262 | my $cmd; |