summaryrefslogtreecommitdiffstats
path: root/plugins/tests/check_http.t
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/tests/check_http.t')
-rwxr-xr-xplugins/tests/check_http.t256
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
17use strict; 8use strict;
18use Test::More; 9use Test::More;
@@ -23,7 +14,7 @@ $ENV{'LC_TIME'} = "C";
23 14
24my $common_tests = 70; 15my $common_tests = 70;
25my $virtual_port_tests = 8; 16my $virtual_port_tests = 8;
26my $ssl_only_tests = 8; 17my $ssl_only_tests = 12;
27# Check that all dependent modules are available 18# Check that all dependent modules are available
28eval "use HTTP::Daemon 6.01;"; 19eval "use HTTP::Daemon 6.01;";
29plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@; 20plan skip_all => 'HTTP::Daemon >= 6.01 required' if $@;
@@ -59,61 +50,87 @@ $HTTP::Daemon::VERSION = "1.00";
59my $port_http = 50000 + int(rand(1000)); 50my $port_http = 50000 + int(rand(1000));
60my $port_https = $port_http + 1; 51my $port_https = $port_http + 1;
61my $port_https_expired = $port_http + 2; 52my $port_https_expired = $port_http + 2;
53my $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
64my @persist; 56my @persist;
65 57
66# Start up all servers 58# Start up all servers
67my @pids; 59my @pids;
68my $pid = fork(); 60# Fork a HTTP server
69if ($pid) { 61my $pid = fork;
70 # Parent 62defined $pid or die "Failed to fork";
71 push @pids, $pid; 63if (!$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}
73push @pids, $pid;
74
75if (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
123sub run_server { 140sub 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
224my $cmd; 262my $cmd;