summaryrefslogtreecommitdiffstats
path: root/plugins/check_http.c
diff options
context:
space:
mode:
Diffstat (limited to 'plugins/check_http.c')
-rw-r--r--plugins/check_http.c468
1 files changed, 348 insertions, 120 deletions
diff --git a/plugins/check_http.c b/plugins/check_http.c
index 2038f4a..718c8ee 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -31,13 +31,14 @@
31* 31*
32*****************************************************************************/ 32*****************************************************************************/
33 33
34/* splint -I. -I../../plugins -I../../lib/ -I/usr/kerberos/include/ ../../plugins/check_http.c */
35
36const char *progname = "check_http"; 34const char *progname = "check_http";
37const char *copyright = "1999-2013"; 35const char *copyright = "1999-2022";
38const char *email = "devel@monitoring-plugins.org"; 36const char *email = "devel@monitoring-plugins.org";
39 37
38// Do NOT sort those headers, it will break the build
39// TODO: Fix this
40#include "common.h" 40#include "common.h"
41#include "base64.h"
41#include "netutils.h" 42#include "netutils.h"
42#include "utils.h" 43#include "utils.h"
43#include "base64.h" 44#include "base64.h"
@@ -52,11 +53,13 @@ enum {
52 MAX_IPV4_HOSTLENGTH = 255, 53 MAX_IPV4_HOSTLENGTH = 255,
53 HTTP_PORT = 80, 54 HTTP_PORT = 80,
54 HTTPS_PORT = 443, 55 HTTPS_PORT = 443,
55 MAX_PORT = 65535 56 MAX_PORT = 65535,
57 DEFAULT_MAX_REDIRS = 15
56}; 58};
57 59
58#ifdef HAVE_SSL 60#ifdef HAVE_SSL
59int check_cert = FALSE; 61bool check_cert = false;
62bool continue_after_check_cert = false;
60int ssl_version = 0; 63int ssl_version = 0;
61int days_till_exp_warn, days_till_exp_crit; 64int days_till_exp_warn, days_till_exp_crit;
62char *randbuff; 65char *randbuff;
@@ -67,12 +70,12 @@ X509 *server_cert;
67# define my_recv(buf, len) read(sd, buf, len) 70# define my_recv(buf, len) read(sd, buf, len)
68# define my_send(buf, len) send(sd, buf, len, 0) 71# define my_send(buf, len) send(sd, buf, len, 0)
69#endif /* HAVE_SSL */ 72#endif /* HAVE_SSL */
70int no_body = FALSE; 73bool no_body = false;
71int maximum_age = -1; 74int maximum_age = -1;
72 75
73enum { 76enum {
74 REGS = 2, 77 REGS = 2,
75 MAX_RE_SIZE = 256 78 MAX_RE_SIZE = 1024
76}; 79};
77#include "regex.h" 80#include "regex.h"
78regex_t preg; 81regex_t preg;
@@ -89,12 +92,14 @@ struct timeval tv_temp;
89#define HTTP_URL "/" 92#define HTTP_URL "/"
90#define CRLF "\r\n" 93#define CRLF "\r\n"
91 94
92int specify_port = FALSE; 95bool specify_port = false;
93int server_port = HTTP_PORT; 96int server_port = HTTP_PORT;
97int virtual_port = 0;
94char server_port_text[6] = ""; 98char server_port_text[6] = "";
95char server_type[6] = "http"; 99char server_type[6] = "http";
96char *server_address; 100char *server_address;
97char *host_name; 101char *host_name;
102int host_name_length;
98char *server_url; 103char *server_url;
99char *user_agent; 104char *user_agent;
100int server_url_length; 105int server_url_length;
@@ -102,38 +107,39 @@ int server_expect_yn = 0;
102char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; 107char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT;
103char header_expect[MAX_INPUT_BUFFER] = ""; 108char header_expect[MAX_INPUT_BUFFER] = "";
104char string_expect[MAX_INPUT_BUFFER] = ""; 109char string_expect[MAX_INPUT_BUFFER] = "";
105char output_header_search[30] = "";
106char output_string_search[30] = "";
107char *warning_thresholds = NULL; 110char *warning_thresholds = NULL;
108char *critical_thresholds = NULL; 111char *critical_thresholds = NULL;
109thresholds *thlds; 112thresholds *thlds;
110char user_auth[MAX_INPUT_BUFFER] = ""; 113char user_auth[MAX_INPUT_BUFFER] = "";
111char proxy_auth[MAX_INPUT_BUFFER] = ""; 114char proxy_auth[MAX_INPUT_BUFFER] = "";
112int display_html = FALSE; 115bool display_html = false;
113char **http_opt_headers; 116char **http_opt_headers;
114int http_opt_headers_count = 0; 117int http_opt_headers_count = 0;
115int onredirect = STATE_OK; 118int onredirect = STATE_OK;
116int followsticky = STICKY_NONE; 119int followsticky = STICKY_NONE;
117int use_ssl = FALSE; 120bool use_ssl = false;
118int use_sni = FALSE; 121bool use_sni = false;
119int verbose = FALSE; 122bool verbose = false;
120int show_extended_perfdata = FALSE; 123bool show_extended_perfdata = false;
124bool show_body = false;
121int sd; 125int sd;
122int min_page_len = 0; 126int min_page_len = 0;
123int max_page_len = 0; 127int max_page_len = 0;
124int redir_depth = 0; 128int redir_depth = 0;
125int max_depth = 15; 129int max_depth = DEFAULT_MAX_REDIRS;
126char *http_method; 130char *http_method;
131char *http_method_proxy;
127char *http_post_data; 132char *http_post_data;
128char *http_content_type; 133char *http_content_type;
129char buffer[MAX_INPUT_BUFFER]; 134char buffer[MAX_INPUT_BUFFER];
130char *client_cert = NULL; 135char *client_cert = NULL;
131char *client_privkey = NULL; 136char *client_privkey = NULL;
132 137
133int process_arguments (int, char **); 138// Forward function declarations
139bool process_arguments (int, char **);
134int check_http (void); 140int check_http (void);
135void redir (char *pos, char *status_line); 141void redir (char *pos, char *status_line);
136int server_type_check(const char *type); 142bool server_type_check(const char *type);
137int server_port_check(int ssl_flag); 143int server_port_check(int ssl_flag);
138char *perfd_time (double microsec); 144char *perfd_time (double microsec);
139char *perfd_time_connect (double microsec); 145char *perfd_time_connect (double microsec);
@@ -144,6 +150,7 @@ char *perfd_time_transfer (double microsec);
144char *perfd_size (int page_len); 150char *perfd_size (int page_len);
145void print_help (void); 151void print_help (void);
146void print_usage (void); 152void print_usage (void);
153char *unchunk_content(const char *content);
147 154
148int 155int
149main (int argc, char **argv) 156main (int argc, char **argv)
@@ -163,10 +170,10 @@ main (int argc, char **argv)
163 /* Parse extra opts if any */ 170 /* Parse extra opts if any */
164 argv=np_extra_opts (&argc, argv, progname); 171 argv=np_extra_opts (&argc, argv, progname);
165 172
166 if (process_arguments (argc, argv) == ERROR) 173 if (process_arguments (argc, argv) == false)
167 usage4 (_("Could not parse arguments")); 174 usage4 (_("Could not parse arguments"));
168 175
169 if (display_html == TRUE) 176 if (display_html == true)
170 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", 177 printf ("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">",
171 use_ssl ? "https" : "http", host_name ? host_name : server_address, 178 use_ssl ? "https" : "http", host_name ? host_name : server_address,
172 server_port, server_url); 179 server_port, server_url);
@@ -189,9 +196,11 @@ test_file (char *path)
189 usage2 (_("file does not exist or is not readable"), path); 196 usage2 (_("file does not exist or is not readable"), path);
190} 197}
191 198
192/* process command-line arguments */ 199/*
193int 200 * process command-line arguments
194process_arguments (int argc, char **argv) 201 * returns true on success, false otherwise
202 */
203bool process_arguments (int argc, char **argv)
195{ 204{
196 int c = 1; 205 int c = 1;
197 char *p; 206 char *p;
@@ -199,7 +208,9 @@ process_arguments (int argc, char **argv)
199 208
200 enum { 209 enum {
201 INVERT_REGEX = CHAR_MAX + 1, 210 INVERT_REGEX = CHAR_MAX + 1,
202 SNI_OPTION 211 SNI_OPTION,
212 MAX_REDIRS_OPTION,
213 CONTINUE_AFTER_CHECK_CERT
203 }; 214 };
204 215
205 int option = 0; 216 int option = 0;
@@ -227,6 +238,7 @@ process_arguments (int argc, char **argv)
227 {"certificate", required_argument, 0, 'C'}, 238 {"certificate", required_argument, 0, 'C'},
228 {"client-cert", required_argument, 0, 'J'}, 239 {"client-cert", required_argument, 0, 'J'},
229 {"private-key", required_argument, 0, 'K'}, 240 {"private-key", required_argument, 0, 'K'},
241 {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT},
230 {"useragent", required_argument, 0, 'A'}, 242 {"useragent", required_argument, 0, 'A'},
231 {"header", required_argument, 0, 'k'}, 243 {"header", required_argument, 0, 'k'},
232 {"no-body", no_argument, 0, 'N'}, 244 {"no-body", no_argument, 0, 'N'},
@@ -237,11 +249,13 @@ process_arguments (int argc, char **argv)
237 {"use-ipv4", no_argument, 0, '4'}, 249 {"use-ipv4", no_argument, 0, '4'},
238 {"use-ipv6", no_argument, 0, '6'}, 250 {"use-ipv6", no_argument, 0, '6'},
239 {"extended-perfdata", no_argument, 0, 'E'}, 251 {"extended-perfdata", no_argument, 0, 'E'},
252 {"show-body", no_argument, 0, 'B'},
253 {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION},
240 {0, 0, 0, 0} 254 {0, 0, 0, 0}
241 }; 255 };
242 256
243 if (argc < 2) 257 if (argc < 2)
244 return ERROR; 258 return false;
245 259
246 for (c = 1; c < argc; c++) { 260 for (c = 1; c < argc; c++) {
247 if (strcmp ("-to", argv[c]) == 0) 261 if (strcmp ("-to", argv[c]) == 0)
@@ -257,7 +271,7 @@ process_arguments (int argc, char **argv)
257 } 271 }
258 272
259 while (1) { 273 while (1) {
260 c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:nlLS::m:M:NE", longopts, &option); 274 c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:nlLS::m:M:NEB", longopts, &option);
261 if (c == -1 || c == EOF) 275 if (c == -1 || c == EOF)
262 break; 276 break;
263 277
@@ -297,10 +311,10 @@ process_arguments (int argc, char **argv)
297 /* xasprintf (&http_opt_headers, "%s", optarg); */ 311 /* xasprintf (&http_opt_headers, "%s", optarg); */
298 break; 312 break;
299 case 'L': /* show html link */ 313 case 'L': /* show html link */
300 display_html = TRUE; 314 display_html = true;
301 break; 315 break;
302 case 'n': /* do not show html link */ 316 case 'n': /* do not show html link */
303 display_html = FALSE; 317 display_html = false;
304 break; 318 break;
305 case 'C': /* Check SSL cert validity */ 319 case 'C': /* Check SSL cert validity */
306#ifdef HAVE_SSL 320#ifdef HAVE_SSL
@@ -321,9 +335,14 @@ process_arguments (int argc, char **argv)
321 usage2 (_("Invalid certificate expiration period"), optarg); 335 usage2 (_("Invalid certificate expiration period"), optarg);
322 days_till_exp_warn = atoi (optarg); 336 days_till_exp_warn = atoi (optarg);
323 } 337 }
324 check_cert = TRUE; 338 check_cert = true;
325 goto enable_ssl; 339 goto enable_ssl;
326#endif 340#endif
341 case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */
342#ifdef HAVE_SSL
343 continue_after_check_cert = true;
344 break;
345#endif
327 case 'J': /* use client certificate */ 346 case 'J': /* use client certificate */
328#ifdef HAVE_SSL 347#ifdef HAVE_SSL
329 test_file(optarg); 348 test_file(optarg);
@@ -341,7 +360,7 @@ process_arguments (int argc, char **argv)
341 enable_ssl: 360 enable_ssl:
342 /* ssl_version initialized to 0 as a default. Only set if it's non-zero. This helps when we include multiple 361 /* ssl_version initialized to 0 as a default. Only set if it's non-zero. This helps when we include multiple
343 parameters, like -S and -C combinations */ 362 parameters, like -S and -C combinations */
344 use_ssl = TRUE; 363 use_ssl = true;
345 if (c=='S' && optarg != NULL) { 364 if (c=='S' && optarg != NULL) {
346 int got_plus = strchr(optarg, '+') != NULL; 365 int got_plus = strchr(optarg, '+') != NULL;
347 366
@@ -358,7 +377,7 @@ process_arguments (int argc, char **argv)
358 else 377 else
359 usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)")); 378 usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)"));
360 } 379 }
361 if (specify_port == FALSE) 380 if (specify_port == false)
362 server_port = HTTPS_PORT; 381 server_port = HTTPS_PORT;
363#else 382#else
364 /* -C -J and -K fall through to here without SSL */ 383 /* -C -J and -K fall through to here without SSL */
@@ -366,8 +385,15 @@ process_arguments (int argc, char **argv)
366#endif 385#endif
367 break; 386 break;
368 case SNI_OPTION: 387 case SNI_OPTION:
369 use_sni = TRUE; 388 use_sni = true;
370 break; 389 break;
390 case MAX_REDIRS_OPTION:
391 if (!is_intnonneg (optarg))
392 usage2 (_("Invalid max_redirs count"), optarg);
393 else {
394 max_depth = atoi (optarg);
395 }
396 break;
371 case 'f': /* onredirect */ 397 case 'f': /* onredirect */
372 if (!strcmp (optarg, "stickyport")) 398 if (!strcmp (optarg, "stickyport"))
373 onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST|STICKY_PORT; 399 onredirect = STATE_DEPENDENT, followsticky = STICKY_HOST|STICKY_PORT;
@@ -391,11 +417,25 @@ process_arguments (int argc, char **argv)
391 case 'H': /* Host Name (virtual host) */ 417 case 'H': /* Host Name (virtual host) */
392 host_name = strdup (optarg); 418 host_name = strdup (optarg);
393 if (host_name[0] == '[') { 419 if (host_name[0] == '[') {
394 if ((p = strstr (host_name, "]:")) != NULL) /* [IPv6]:port */ 420 if ((p = strstr (host_name, "]:")) != NULL) { /* [IPv6]:port */
395 server_port = atoi (p + 2); 421 virtual_port = atoi (p + 2);
422 /* cut off the port */
423 host_name_length = strlen (host_name) - strlen (p) - 1;
424 free (host_name);
425 host_name = strndup (optarg, host_name_length);
426 if (specify_port == false)
427 server_port = virtual_port;
428 }
396 } else if ((p = strchr (host_name, ':')) != NULL 429 } else if ((p = strchr (host_name, ':')) != NULL
397 && strchr (++p, ':') == NULL) /* IPv4:port or host:port */ 430 && strchr (++p, ':') == NULL) { /* IPv4:port or host:port */
398 server_port = atoi (p); 431 virtual_port = atoi (p);
432 /* cut off the port */
433 host_name_length = strlen (host_name) - strlen (p) - 1;
434 free (host_name);
435 host_name = strndup (optarg, host_name_length);
436 if (specify_port == false)
437 server_port = virtual_port;
438 }
399 break; 439 break;
400 case 'I': /* Server IP-address */ 440 case 'I': /* Server IP-address */
401 server_address = strdup (optarg); 441 server_address = strdup (optarg);
@@ -409,7 +449,7 @@ process_arguments (int argc, char **argv)
409 usage2 (_("Invalid port number"), optarg); 449 usage2 (_("Invalid port number"), optarg);
410 else { 450 else {
411 server_port = atoi (optarg); 451 server_port = atoi (optarg);
412 specify_port = TRUE; 452 specify_port = true;
413 } 453 }
414 break; 454 break;
415 case 'a': /* authorization info */ 455 case 'a': /* authorization info */
@@ -430,6 +470,12 @@ process_arguments (int argc, char **argv)
430 if (http_method) 470 if (http_method)
431 free(http_method); 471 free(http_method);
432 http_method = strdup (optarg); 472 http_method = strdup (optarg);
473 char *tmp;
474 if ((tmp = strstr(http_method, ":")) > 0) {
475 tmp[0] = '\0';
476 http_method = http_method;
477 http_method_proxy = ++tmp;
478 }
433 break; 479 break;
434 case 'd': /* string or substring */ 480 case 'd': /* string or substring */
435 strncpy (header_expect, optarg, MAX_INPUT_BUFFER - 1); 481 strncpy (header_expect, optarg, MAX_INPUT_BUFFER - 1);
@@ -452,6 +498,7 @@ process_arguments (int argc, char **argv)
452 break; 498 break;
453 case 'R': /* regex */ 499 case 'R': /* regex */
454 cflags |= REG_ICASE; 500 cflags |= REG_ICASE;
501 // fall through
455 case 'r': /* regex */ 502 case 'r': /* regex */
456 strncpy (regexp, optarg, MAX_RE_SIZE - 1); 503 strncpy (regexp, optarg, MAX_RE_SIZE - 1);
457 regexp[MAX_RE_SIZE - 1] = 0; 504 regexp[MAX_RE_SIZE - 1] = 0;
@@ -459,7 +506,7 @@ process_arguments (int argc, char **argv)
459 if (errcode != 0) { 506 if (errcode != 0) {
460 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); 507 (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER);
461 printf (_("Could Not Compile Regular Expression: %s"), errbuf); 508 printf (_("Could Not Compile Regular Expression: %s"), errbuf);
462 return ERROR; 509 return false;
463 } 510 }
464 break; 511 break;
465 case INVERT_REGEX: 512 case INVERT_REGEX:
@@ -476,7 +523,7 @@ process_arguments (int argc, char **argv)
476#endif 523#endif
477 break; 524 break;
478 case 'v': /* verbose */ 525 case 'v': /* verbose */
479 verbose = TRUE; 526 verbose = true;
480 break; 527 break;
481 case 'm': /* min_page_length */ 528 case 'm': /* min_page_length */
482 { 529 {
@@ -501,7 +548,7 @@ process_arguments (int argc, char **argv)
501 break; 548 break;
502 } 549 }
503 case 'N': /* no-body */ 550 case 'N': /* no-body */
504 no_body = TRUE; 551 no_body = true;
505 break; 552 break;
506 case 'M': /* max-age */ 553 case 'M': /* max-age */
507 { 554 {
@@ -522,7 +569,10 @@ process_arguments (int argc, char **argv)
522 } 569 }
523 break; 570 break;
524 case 'E': /* show extended perfdata */ 571 case 'E': /* show extended perfdata */
525 show_extended_perfdata = TRUE; 572 show_extended_perfdata = true;
573 break;
574 case 'B': /* print body content after status line */
575 show_body = true;
526 break; 576 break;
527 } 577 }
528 } 578 }
@@ -550,10 +600,16 @@ process_arguments (int argc, char **argv)
550 if (http_method == NULL) 600 if (http_method == NULL)
551 http_method = strdup ("GET"); 601 http_method = strdup ("GET");
552 602
553 if (client_cert && !client_privkey) 603 if (http_method_proxy == NULL)
604 http_method_proxy = strdup ("GET");
605
606 if (client_cert && !client_privkey)
554 usage4 (_("If you use a client certificate you must also specify a private key file")); 607 usage4 (_("If you use a client certificate you must also specify a private key file"));
555 608
556 return TRUE; 609 if (virtual_port == 0)
610 virtual_port = server_port;
611
612 return true;
557} 613}
558 614
559 615
@@ -893,10 +949,25 @@ check_http (void)
893 /* @20100414, public[at]frank4dd.com, http://www.frank4dd.com/howto */ 949 /* @20100414, public[at]frank4dd.com, http://www.frank4dd.com/howto */
894 950
895 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0 951 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0
896 && host_name != NULL && use_ssl == TRUE) { 952 && host_name != NULL && use_ssl == true) {
897 953
898 if (verbose) printf ("Entering CONNECT tunnel mode with proxy %s:%d to dst %s:%d\n", server_address, server_port, host_name, HTTPS_PORT); 954 if (verbose) printf ("Entering CONNECT tunnel mode with proxy %s:%d to dst %s:%d\n", server_address, server_port, host_name, HTTPS_PORT);
899 asprintf (&buf, "%s %s:%d HTTP/1.1\r\n%s\r\n", http_method, host_name, HTTPS_PORT, user_agent); 955 asprintf (&buf, "%s %s:%d HTTP/1.1\r\n%s\r\n", http_method, host_name, HTTPS_PORT, user_agent);
956 if (strlen(proxy_auth)) {
957 base64_encode_alloc (proxy_auth, strlen (proxy_auth), &auth);
958 xasprintf (&buf, "%sProxy-Authorization: Basic %s\r\n", buf, auth);
959 }
960 /* optionally send any other header tag */
961 if (http_opt_headers_count) {
962 for (i = 0; i < http_opt_headers_count ; i++) {
963 if (force_host_header != http_opt_headers[i]) {
964 xasprintf (&buf, "%s%s\r\n", buf, http_opt_headers[i]);
965 }
966 }
967 /* This cannot be free'd here because a redirection will then try to access this and segfault */
968 /* Covered in a testcase in tests/check_http.t */
969 /* free(http_opt_headers); */
970 }
900 asprintf (&buf, "%sProxy-Connection: keep-alive\r\n", buf); 971 asprintf (&buf, "%sProxy-Connection: keep-alive\r\n", buf);
901 asprintf (&buf, "%sHost: %s\r\n", buf, host_name); 972 asprintf (&buf, "%sHost: %s\r\n", buf, host_name);
902 /* we finished our request, send empty line with CRLF */ 973 /* we finished our request, send empty line with CRLF */
@@ -912,7 +983,7 @@ check_http (void)
912 } 983 }
913#ifdef HAVE_SSL 984#ifdef HAVE_SSL
914 elapsed_time_connect = (double)microsec_connect / 1.0e6; 985 elapsed_time_connect = (double)microsec_connect / 1.0e6;
915 if (use_ssl == TRUE) { 986 if (use_ssl == true) {
916 gettimeofday (&tv_temp, NULL); 987 gettimeofday (&tv_temp, NULL);
917 result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey); 988 result = np_net_ssl_init_with_hostname_version_and_cert(sd, (use_sni ? host_name : NULL), ssl_version, client_cert, client_privkey);
918 if (verbose) printf ("SSL initialized\n"); 989 if (verbose) printf ("SSL initialized\n");
@@ -920,18 +991,20 @@ check_http (void)
920 die (STATE_CRITICAL, NULL); 991 die (STATE_CRITICAL, NULL);
921 microsec_ssl = deltime (tv_temp); 992 microsec_ssl = deltime (tv_temp);
922 elapsed_time_ssl = (double)microsec_ssl / 1.0e6; 993 elapsed_time_ssl = (double)microsec_ssl / 1.0e6;
923 if (check_cert == TRUE) { 994 if (check_cert == true) {
924 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit); 995 result = np_net_ssl_check_cert(days_till_exp_warn, days_till_exp_crit);
925 np_net_ssl_cleanup(); 996 if (continue_after_check_cert == false) {
926 if (sd) close(sd); 997 if (sd) close(sd);
927 return result; 998 np_net_ssl_cleanup();
999 return result;
1000 }
928 } 1001 }
929 } 1002 }
930#endif /* HAVE_SSL */ 1003#endif /* HAVE_SSL */
931 1004
932 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0 1005 if ( server_address != NULL && strcmp(http_method, "CONNECT") == 0
933 && host_name != NULL && use_ssl == TRUE) 1006 && host_name != NULL && use_ssl == true)
934 asprintf (&buf, "%s %s %s\r\n%s\r\n", "GET", server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent); 1007 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method_proxy, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent);
935 else 1008 else
936 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent); 1009 asprintf (&buf, "%s %s %s\r\n%s\r\n", http_method, server_url, host_name ? "HTTP/1.1" : "HTTP/1.0", user_agent);
937 1010
@@ -958,13 +1031,13 @@ check_http (void)
958 * 14.23). Some server applications/configurations cause trouble if the 1031 * 14.23). Some server applications/configurations cause trouble if the
959 * (default) port is explicitly specified in the "Host:" header line. 1032 * (default) port is explicitly specified in the "Host:" header line.
960 */ 1033 */
961 if ((use_ssl == FALSE && server_port == HTTP_PORT) || 1034 if ((use_ssl == false && virtual_port == HTTP_PORT) ||
962 (use_ssl == TRUE && server_port == HTTPS_PORT) || 1035 (use_ssl == true && virtual_port == HTTPS_PORT) ||
963 (server_address != NULL && strcmp(http_method, "CONNECT") == 0 1036 (server_address != NULL && strcmp(http_method, "CONNECT") == 0
964 && host_name != NULL && use_ssl == TRUE)) 1037 && host_name != NULL && use_ssl == true))
965 xasprintf (&buf, "%sHost: %s\r\n", buf, host_name); 1038 xasprintf (&buf, "%sHost: %s\r\n", buf, host_name);
966 else 1039 else
967 xasprintf (&buf, "%sHost: %s:%d\r\n", buf, host_name, server_port); 1040 xasprintf (&buf, "%sHost: %s:%d\r\n", buf, host_name, virtual_port);
968 } 1041 }
969 } 1042 }
970 1043
@@ -1001,9 +1074,8 @@ check_http (void)
1001 } 1074 }
1002 1075
1003 xasprintf (&buf, "%sContent-Length: %i\r\n\r\n", buf, (int)strlen (http_post_data)); 1076 xasprintf (&buf, "%sContent-Length: %i\r\n\r\n", buf, (int)strlen (http_post_data));
1004 xasprintf (&buf, "%s%s%s", buf, http_post_data, CRLF); 1077 xasprintf (&buf, "%s%s", buf, http_post_data);
1005 } 1078 } else {
1006 else {
1007 /* or just a newline so the server knows we're done with the request */ 1079 /* or just a newline so the server knows we're done with the request */
1008 xasprintf (&buf, "%s%s", buf, CRLF); 1080 xasprintf (&buf, "%s%s", buf, CRLF);
1009 } 1081 }
@@ -1022,10 +1094,19 @@ check_http (void)
1022 microsec_firstbyte = deltime (tv_temp); 1094 microsec_firstbyte = deltime (tv_temp);
1023 elapsed_time_firstbyte = (double)microsec_firstbyte / 1.0e6; 1095 elapsed_time_firstbyte = (double)microsec_firstbyte / 1.0e6;
1024 } 1096 }
1097 while (pos = memchr(buffer, '\0', i)) {
1098 /* replace nul character with a blank */
1099 *pos = ' ';
1100 }
1025 buffer[i] = '\0'; 1101 buffer[i] = '\0';
1026 xasprintf (&full_page_new, "%s%s", full_page, buffer); 1102
1027 free (full_page); 1103 if ((full_page_new = realloc(full_page, pagesize + i + 1)) == NULL)
1104 die (STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate memory for full_page\n"));
1105
1106 memmove(&full_page_new[pagesize], buffer, i + 1);
1107
1028 full_page = full_page_new; 1108 full_page = full_page_new;
1109
1029 pagesize += i; 1110 pagesize += i;
1030 1111
1031 if (no_body && document_headers_done (full_page)) { 1112 if (no_body && document_headers_done (full_page)) {
@@ -1037,25 +1118,7 @@ check_http (void)
1037 elapsed_time_transfer = (double)microsec_transfer / 1.0e6; 1118 elapsed_time_transfer = (double)microsec_transfer / 1.0e6;
1038 1119
1039 if (i < 0 && errno != ECONNRESET) { 1120 if (i < 0 && errno != ECONNRESET) {
1040#ifdef HAVE_SSL 1121 die(STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1041 /*
1042 if (use_ssl) {
1043 sslerr=SSL_get_error(ssl, i);
1044 if ( sslerr == SSL_ERROR_SSL ) {
1045 die (STATE_WARNING, _("HTTP WARNING - Client Certificate Required\n"));
1046 } else {
1047 die (STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1048 }
1049 }
1050 else {
1051 */
1052#endif
1053 die (STATE_CRITICAL, _("HTTP CRITICAL - Error on receive\n"));
1054#ifdef HAVE_SSL
1055 /* XXX
1056 }
1057 */
1058#endif
1059 } 1122 }
1060 1123
1061 /* return a CRITICAL status if we couldn't read any data */ 1124 /* return a CRITICAL status if we couldn't read any data */
@@ -1063,10 +1126,10 @@ check_http (void)
1063 die (STATE_CRITICAL, _("HTTP CRITICAL - No data received from host\n")); 1126 die (STATE_CRITICAL, _("HTTP CRITICAL - No data received from host\n"));
1064 1127
1065 /* close the connection */ 1128 /* close the connection */
1129 if (sd) close(sd);
1066#ifdef HAVE_SSL 1130#ifdef HAVE_SSL
1067 np_net_ssl_cleanup(); 1131 np_net_ssl_cleanup();
1068#endif 1132#endif
1069 if (sd) close(sd);
1070 1133
1071 /* Save check time */ 1134 /* Save check time */
1072 microsec = deltime (tv); 1135 microsec = deltime (tv);
@@ -1117,6 +1180,8 @@ check_http (void)
1117 xasprintf (&msg, 1180 xasprintf (&msg,
1118 _("Invalid HTTP response received from host on port %d: %s\n"), 1181 _("Invalid HTTP response received from host on port %d: %s\n"),
1119 server_port, status_line); 1182 server_port, status_line);
1183 if (show_body)
1184 xasprintf (&msg, _("%s\n%s"), msg, page);
1120 die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg); 1185 die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg);
1121 } 1186 }
1122 1187
@@ -1178,32 +1243,73 @@ check_http (void)
1178 } 1243 }
1179 1244
1180 /* Page and Header content checks go here */ 1245 /* Page and Header content checks go here */
1181 if (strlen (header_expect)) { 1246 if (strlen(header_expect) > 0) {
1182 if (!strstr (header, header_expect)) { 1247 if (strstr(header, header_expect) == NULL) {
1183 strncpy(&output_header_search[0],header_expect,sizeof(output_header_search)); 1248 // We did not find the header, the rest is for building the output and setting the state
1184 if(output_header_search[sizeof(output_header_search)-1]!='\0') { 1249 char output_header_search[30] = "";
1185 bcopy("...",&output_header_search[sizeof(output_header_search)-4],4); 1250
1251 strncpy(&output_header_search[0], header_expect,
1252 sizeof(output_header_search));
1253
1254 if (output_header_search[sizeof(output_header_search) - 1] != '\0') {
1255 bcopy("...",
1256 &output_header_search[sizeof(output_header_search) - 4],
1257 4);
1186 } 1258 }
1187 xasprintf (&msg, _("%sheader '%s' not found on '%s://%s:%d%s', "), msg, output_header_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); 1259
1260 xasprintf (&msg,
1261 _("%sheader '%s' not found on '%s://%s:%d%s', "),
1262 msg,
1263 output_header_search, use_ssl ? "https" : "http",
1264 host_name ? host_name : server_address, server_port,
1265 server_url);
1266
1188 result = STATE_CRITICAL; 1267 result = STATE_CRITICAL;
1189 } 1268 }
1190 } 1269 }
1191 1270
1271 // At this point we should test if the content is chunked and unchunk it, so
1272 // it can be searched (and possibly printed)
1273 const char *chunked_header_regex_string = "Transfer-Encoding: *chunked *";
1274 regex_t chunked_header_regex;
1275
1276 if (regcomp(&chunked_header_regex, chunked_header_regex_string, REG_ICASE)) {
1277 die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), "Failed to compile chunked_header_regex regex");
1278 }
1279
1280 regmatch_t chre_pmatch[1]; // We actually do not care about this, since we only want to know IF it was found
1281
1282 if (!no_body && regexec(&chunked_header_regex, header, 1, chre_pmatch, 0) == 0) {
1283 if (verbose) {
1284 printf("Found chunked content\n");
1285 }
1286 // We actually found the chunked header
1287 char *tmp = unchunk_content(page);
1288 if (tmp == NULL) {
1289 die(STATE_UNKNOWN, "HTTP %s: %s\n", state_text(STATE_UNKNOWN), "Failed to unchunk message body");
1290 }
1291 page = tmp;
1292 }
1192 1293
1193 if (strlen (string_expect)) { 1294 if (strlen(string_expect) > 0) {
1194 if (!strstr (page, string_expect)) { 1295 if (!strstr(page, string_expect)) {
1195 strncpy(&output_string_search[0],string_expect,sizeof(output_string_search)); 1296 // We found the string the body, the rest is for building the output
1196 if(output_string_search[sizeof(output_string_search)-1]!='\0') { 1297 char output_string_search[30] = "";
1197 bcopy("...",&output_string_search[sizeof(output_string_search)-4],4); 1298 strncpy(&output_string_search[0], string_expect,
1299 sizeof(output_string_search));
1300 if (output_string_search[sizeof(output_string_search) - 1] != '\0') {
1301 bcopy("...", &output_string_search[sizeof(output_string_search) - 4],
1302 4);
1198 } 1303 }
1199 xasprintf (&msg, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); 1304 xasprintf (&msg, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url);
1200 result = STATE_CRITICAL; 1305 result = STATE_CRITICAL;
1201 } 1306 }
1202 } 1307 }
1203 1308
1204 if (strlen (regexp)) { 1309 if (strlen(regexp) > 0) {
1205 errcode = regexec (&preg, page, REGS, pmatch, 0); 1310 errcode = regexec(&preg, page, REGS, pmatch, 0);
1206 if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { 1311 if ((errcode == 0 && invert_regex == 0) ||
1312 (errcode == REG_NOMATCH && invert_regex == 1)) {
1207 /* OK - No-op to avoid changing the logic around it */ 1313 /* OK - No-op to avoid changing the logic around it */
1208 result = max_state_alt(STATE_OK, result); 1314 result = max_state_alt(STATE_OK, result);
1209 } 1315 }
@@ -1255,7 +1361,7 @@ check_http (void)
1255 perfd_time (elapsed_time), 1361 perfd_time (elapsed_time),
1256 perfd_size (page_len), 1362 perfd_size (page_len),
1257 perfd_time_connect (elapsed_time_connect), 1363 perfd_time_connect (elapsed_time_connect),
1258 use_ssl == TRUE ? perfd_time_ssl (elapsed_time_ssl) : "", 1364 use_ssl == true ? perfd_time_ssl (elapsed_time_ssl) : "",
1259 perfd_time_headers (elapsed_time_headers), 1365 perfd_time_headers (elapsed_time_headers),
1260 perfd_time_firstbyte (elapsed_time_firstbyte), 1366 perfd_time_firstbyte (elapsed_time_firstbyte),
1261 perfd_time_transfer (elapsed_time_transfer)); 1367 perfd_time_transfer (elapsed_time_transfer));
@@ -1267,6 +1373,9 @@ check_http (void)
1267 perfd_time (elapsed_time), 1373 perfd_time (elapsed_time),
1268 perfd_size (page_len)); 1374 perfd_size (page_len));
1269 1375
1376 if (show_body)
1377 xasprintf (&msg, _("%s\n%s"), msg, page);
1378
1270 result = max_state_alt(get_status(elapsed_time, thlds), result); 1379 result = max_state_alt(get_status(elapsed_time, thlds), result);
1271 1380
1272 die (result, "HTTP %s: %s\n", state_text(result), msg); 1381 die (result, "HTTP %s: %s\n", state_text(result), msg);
@@ -1274,7 +1383,94 @@ check_http (void)
1274 return STATE_UNKNOWN; 1383 return STATE_UNKNOWN;
1275} 1384}
1276 1385
1386/* Receivces a pointer to the beginning of the body of a HTTP message
1387 * which is chunked and returns a pointer to a freshly allocated memory
1388 * region containing the unchunked body or NULL if something failed.
1389 * The result must be freed by the caller.
1390 */
1391char *unchunk_content(const char *content) {
1392 // https://en.wikipedia.org/wiki/Chunked_transfer_encoding
1393 // https://www.rfc-editor.org/rfc/rfc7230#section-4.1
1394 char *result = NULL;
1395 char *start_of_chunk;
1396 char* end_of_chunk;
1397 long size_of_chunk;
1398 const char *pointer = content;
1399 char *endptr;
1400 long length_of_chunk = 0;
1401 size_t overall_size = 0;
1402
1403 while (true) {
1404 size_of_chunk = strtol(pointer, &endptr, 16);
1405 if (size_of_chunk == LONG_MIN || size_of_chunk == LONG_MAX) {
1406 // Apparently underflow or overflow, should not happen
1407 if (verbose) {
1408 printf("Got an underflow or overflow from strtol at: %u\n", __LINE__);
1409 }
1410 return NULL;
1411 }
1412 if (endptr == pointer) {
1413 // Apparently this was not a number
1414 if (verbose) {
1415 printf("Chunked content did not start with a number at all (Line: %u)\n", __LINE__);
1416 }
1417 return NULL;
1418 }
1419
1420 // So, we got the length of the chunk
1421 if (*endptr == ';') {
1422 // Chunk extension starts here
1423 while (*endptr != '\r') {
1424 endptr++;
1425 }
1426 }
1427
1428 start_of_chunk = endptr + 2;
1429 end_of_chunk = start_of_chunk + size_of_chunk;
1430 length_of_chunk = (long)(end_of_chunk - start_of_chunk);
1431 pointer = end_of_chunk + 2; //Next number should be here
1432
1433 if (length_of_chunk == 0) {
1434 // Chunk length is 0, so this is the last one
1435 break;
1436 }
1437
1438 overall_size += length_of_chunk;
1439
1440 if (result == NULL) {
1441 // Size of the chunk plus the ending NULL byte
1442 result = (char *)malloc(length_of_chunk +1);
1443 if (result == NULL) {
1444 if (verbose) {
1445 printf("Failed to allocate memory for unchunked body\n");
1446 }
1447 return NULL;
1448 }
1449 } else {
1450 // Enlarge memory to the new size plus the ending NULL byte
1451 void *tmp = realloc(result, overall_size +1);
1452 if (tmp == NULL) {
1453 if (verbose) {
1454 printf("Failed to allocate memory for unchunked body\n");
1455 }
1456 return NULL;
1457 } else {
1458 result = tmp;
1459 }
1460 }
1461
1462 memcpy(result + (overall_size - size_of_chunk), start_of_chunk, size_of_chunk);
1463 }
1277 1464
1465 if (overall_size == 0 && result == NULL) {
1466 // We might just have received the end chunk without previous content, so result is never allocated
1467 result = calloc(1, sizeof(char));
1468 // No error handling here, we can only return NULL anyway
1469 } else {
1470 result[overall_size] = '\0';
1471 }
1472 return result;
1473}
1278 1474
1279/* per RFC 2396 */ 1475/* per RFC 2396 */
1280#define URI_HTTP "%5[HTPShtps]" 1476#define URI_HTTP "%5[HTPShtps]"
@@ -1285,7 +1481,9 @@ check_http (void)
1285#define HD2 URI_HTTP "://" URI_HOST "/" URI_PATH 1481#define HD2 URI_HTTP "://" URI_HOST "/" URI_PATH
1286#define HD3 URI_HTTP "://" URI_HOST ":" URI_PORT 1482#define HD3 URI_HTTP "://" URI_HOST ":" URI_PORT
1287#define HD4 URI_HTTP "://" URI_HOST 1483#define HD4 URI_HTTP "://" URI_HOST
1288#define HD5 URI_PATH 1484/* relative reference redirect like //www.site.org/test https://tools.ietf.org/html/rfc3986 */
1485#define HD5 "//" URI_HOST "/" URI_PATH
1486#define HD6 URI_PATH
1289 1487
1290void 1488void
1291redir (char *pos, char *status_line) 1489redir (char *pos, char *status_line)
@@ -1362,9 +1560,21 @@ redir (char *pos, char *status_line)
1362 use_ssl = server_type_check (type); 1560 use_ssl = server_type_check (type);
1363 i = server_port_check (use_ssl); 1561 i = server_port_check (use_ssl);
1364 } 1562 }
1563 /* URI_HTTP, URI_HOST, URI_PATH */
1564 else if (sscanf (pos, HD5, addr, url) == 2) {
1565 if(use_ssl){
1566 strcpy (type,"https");
1567 }
1568 else{
1569 strcpy (type, server_type);
1570 }
1571 xasprintf (&url, "/%s", url);
1572 use_ssl = server_type_check (type);
1573 i = server_port_check (use_ssl);
1574 }
1365 1575
1366 /* URI_PATH */ 1576 /* URI_PATH */
1367 else if (sscanf (pos, HD5, url) == 1) { 1577 else if (sscanf (pos, HD6, url) == 1) {
1368 /* relative url */ 1578 /* relative url */
1369 if ((url[0] != '/')) { 1579 if ((url[0] != '/')) {
1370 if ((x = strrchr(server_url, '/'))) 1580 if ((x = strrchr(server_url, '/')))
@@ -1395,8 +1605,8 @@ redir (char *pos, char *status_line)
1395 !strncmp(server_address, addr, MAX_IPV4_HOSTLENGTH) && 1605 !strncmp(server_address, addr, MAX_IPV4_HOSTLENGTH) &&
1396 (host_name && !strncmp(host_name, addr, MAX_IPV4_HOSTLENGTH)) && 1606 (host_name && !strncmp(host_name, addr, MAX_IPV4_HOSTLENGTH)) &&
1397 !strcmp(server_url, url)) 1607 !strcmp(server_url, url))
1398 die (STATE_WARNING, 1608 die (STATE_CRITICAL,
1399 _("HTTP WARNING - redirection creates an infinite loop - %s://%s:%d%s%s\n"), 1609 _("HTTP CRITICAL - redirection creates an infinite loop - %s://%s:%d%s%s\n"),
1400 type, addr, i, url, (display_html ? "</A>" : "")); 1610 type, addr, i, url, (display_html ? "</A>" : ""));
1401 1611
1402 strcpy (server_type, type); 1612 strcpy (server_type, type);
@@ -1421,6 +1631,9 @@ redir (char *pos, char *status_line)
1421 MAX_PORT, server_type, server_address, server_port, server_url, 1631 MAX_PORT, server_type, server_address, server_port, server_url,
1422 display_html ? "</A>" : ""); 1632 display_html ? "</A>" : "");
1423 1633
1634 /* reset virtual port */
1635 virtual_port = server_port;
1636
1424 if (verbose) 1637 if (verbose)
1425 printf (_("Redirection to %s://%s:%d%s\n"), server_type, 1638 printf (_("Redirection to %s://%s:%d%s\n"), server_type,
1426 host_name ? host_name : server_address, server_port, server_url); 1639 host_name ? host_name : server_address, server_port, server_url);
@@ -1430,13 +1643,13 @@ redir (char *pos, char *status_line)
1430} 1643}
1431 1644
1432 1645
1433int 1646bool
1434server_type_check (const char *type) 1647server_type_check (const char *type)
1435{ 1648{
1436 if (strcmp (type, "https")) 1649 if (strcmp (type, "https"))
1437 return FALSE; 1650 return false;
1438 else 1651 else
1439 return TRUE; 1652 return true;
1440} 1653}
1441 1654
1442int 1655int
@@ -1451,42 +1664,42 @@ server_port_check (int ssl_flag)
1451char *perfd_time (double elapsed_time) 1664char *perfd_time (double elapsed_time)
1452{ 1665{
1453 return fperfdata ("time", elapsed_time, "s", 1666 return fperfdata ("time", elapsed_time, "s",
1454 thlds->warning?TRUE:FALSE, thlds->warning?thlds->warning->end:0, 1667 thlds->warning?true:false, thlds->warning?thlds->warning->end:0,
1455 thlds->critical?TRUE:FALSE, thlds->critical?thlds->critical->end:0, 1668 thlds->critical?true:false, thlds->critical?thlds->critical->end:0,
1456 TRUE, 0, FALSE, 0); 1669 true, 0, true, socket_timeout);
1457} 1670}
1458 1671
1459char *perfd_time_connect (double elapsed_time_connect) 1672char *perfd_time_connect (double elapsed_time_connect)
1460{ 1673{
1461 return fperfdata ("time_connect", elapsed_time_connect, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0); 1674 return fperfdata ("time_connect", elapsed_time_connect, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1462} 1675}
1463 1676
1464char *perfd_time_ssl (double elapsed_time_ssl) 1677char *perfd_time_ssl (double elapsed_time_ssl)
1465{ 1678{
1466 return fperfdata ("time_ssl", elapsed_time_ssl, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0); 1679 return fperfdata ("time_ssl", elapsed_time_ssl, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1467} 1680}
1468 1681
1469char *perfd_time_headers (double elapsed_time_headers) 1682char *perfd_time_headers (double elapsed_time_headers)
1470{ 1683{
1471 return fperfdata ("time_headers", elapsed_time_headers, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0); 1684 return fperfdata ("time_headers", elapsed_time_headers, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1472} 1685}
1473 1686
1474char *perfd_time_firstbyte (double elapsed_time_firstbyte) 1687char *perfd_time_firstbyte (double elapsed_time_firstbyte)
1475{ 1688{
1476 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0); 1689 return fperfdata ("time_firstbyte", elapsed_time_firstbyte, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1477} 1690}
1478 1691
1479char *perfd_time_transfer (double elapsed_time_transfer) 1692char *perfd_time_transfer (double elapsed_time_transfer)
1480{ 1693{
1481 return fperfdata ("time_transfer", elapsed_time_transfer, "s", FALSE, 0, FALSE, 0, FALSE, 0, FALSE, 0); 1694 return fperfdata ("time_transfer", elapsed_time_transfer, "s", false, 0, false, 0, false, 0, true, socket_timeout);
1482} 1695}
1483 1696
1484char *perfd_size (int page_len) 1697char *perfd_size (int page_len)
1485{ 1698{
1486 return perfdata ("size", page_len, "B", 1699 return perfdata ("size", page_len, "B",
1487 (min_page_len>0?TRUE:FALSE), min_page_len, 1700 (min_page_len>0?true:false), min_page_len,
1488 (min_page_len>0?TRUE:FALSE), 0, 1701 (min_page_len>0?true:false), 0,
1489 TRUE, 0, FALSE, 0); 1702 true, 0, false, 0);
1490} 1703}
1491 1704
1492void 1705void
@@ -1506,6 +1719,10 @@ print_help (void)
1506 1719
1507 print_usage (); 1720 print_usage ();
1508 1721
1722#ifdef HAVE_SSL
1723 printf (_("In the first form, make an HTTP request."));
1724 printf (_("In the second form, connect to the server and check the TLS certificate."));
1725#endif
1509 printf (_("NOTE: One or both of -H and -I must be specified")); 1726 printf (_("NOTE: One or both of -H and -I must be specified"));
1510 1727
1511 printf ("\n"); 1728 printf ("\n");
@@ -1533,7 +1750,11 @@ print_help (void)
1533 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); 1750 printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)"));
1534 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); 1751 printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]");
1535 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); 1752 printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443"));
1536 printf (" %s\n", _("(when this option is used the URL is not checked.)")); 1753 printf (" %s\n", _("(when this option is used the URL is not checked by default. You can use"));
1754 printf (" %s\n", _(" --continue-after-certificate to override this behavior)"));
1755 printf (" %s\n", "--continue-after-certificate");
1756 printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check."));
1757 printf (" %s\n", _("Does nothing unless -C is used."));
1537 printf (" %s\n", "-J, --client-cert=FILE"); 1758 printf (" %s\n", "-J, --client-cert=FILE");
1538 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)")); 1759 printf (" %s\n", _("Name of file that contains the client certificate (PEM format)"));
1539 printf (" %s\n", _("to be used in establishing the SSL session")); 1760 printf (" %s\n", _("to be used in establishing the SSL session"));
@@ -1555,7 +1776,7 @@ print_help (void)
1555 printf (" %s\n", _("URL to GET or POST (default: /)")); 1776 printf (" %s\n", _("URL to GET or POST (default: /)"));
1556 printf (" %s\n", "-P, --post=STRING"); 1777 printf (" %s\n", "-P, --post=STRING");
1557 printf (" %s\n", _("URL encoded http POST data")); 1778 printf (" %s\n", _("URL encoded http POST data"));
1558 printf (" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)"); 1779 printf (" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT, CONNECT:POST)");
1559 printf (" %s\n", _("Set HTTP method.")); 1780 printf (" %s\n", _("Set HTTP method."));
1560 printf (" %s\n", "-N, --no-body"); 1781 printf (" %s\n", "-N, --no-body");
1561 printf (" %s\n", _("Don't wait for document body: stop reading after headers.")); 1782 printf (" %s\n", _("Don't wait for document body: stop reading after headers."));
@@ -1585,14 +1806,18 @@ print_help (void)
1585 printf (" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers")); 1806 printf (" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers"));
1586 printf (" %s\n", "-E, --extended-perfdata"); 1807 printf (" %s\n", "-E, --extended-perfdata");
1587 printf (" %s\n", _("Print additional performance data")); 1808 printf (" %s\n", _("Print additional performance data"));
1809 printf (" %s\n", "-B, --show-body");
1810 printf (" %s\n", _("Print body content below status line"));
1588 printf (" %s\n", "-L, --link"); 1811 printf (" %s\n", "-L, --link");
1589 printf (" %s\n", _("Wrap output in HTML link (obsoleted by urlize)")); 1812 printf (" %s\n", _("Wrap output in HTML link (obsoleted by urlize)"));
1590 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>"); 1813 printf (" %s\n", "-f, --onredirect=<ok|warning|critical|follow|sticky|stickyport>");
1591 printf (" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the")); 1814 printf (" %s\n", _("How to handle redirected pages. sticky is like follow but stick to the"));
1592 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same.")); 1815 printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same."));
1816 printf (" %s\n", "--max-redirs=INTEGER");
1817 printf (" %s", _("Maximal number of redirects (default: "));
1818 printf ("%d)\n", DEFAULT_MAX_REDIRS);
1593 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); 1819 printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>");
1594 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)")); 1820 printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)"));
1595
1596 printf (UT_WARN_CRIT); 1821 printf (UT_WARN_CRIT);
1597 1822
1598 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT); 1823 printf (UT_CONN_TIMEOUT, DEFAULT_SOCKET_TIMEOUT);
@@ -1603,7 +1828,7 @@ print_help (void)
1603 printf ("%s\n", _("Notes:")); 1828 printf ("%s\n", _("Notes:"));
1604 printf (" %s\n", _("This plugin will attempt to open an HTTP connection with the host.")); 1829 printf (" %s\n", _("This plugin will attempt to open an HTTP connection with the host."));
1605 printf (" %s\n", _("Successful connects return STATE_OK, refusals and timeouts return STATE_CRITICAL")); 1830 printf (" %s\n", _("Successful connects return STATE_OK, refusals and timeouts return STATE_CRITICAL"));
1606 printf (" %s\n", _("other errors return STATE_UNKNOWN. Successful connects, but incorrect reponse")); 1831 printf (" %s\n", _("other errors return STATE_UNKNOWN. Successful connects, but incorrect response"));
1607 printf (" %s\n", _("messages from the host result in STATE_WARNING return values. If you are")); 1832 printf (" %s\n", _("messages from the host result in STATE_WARNING return values. If you are"));
1608 printf (" %s\n", _("checking a virtual server that uses 'host headers' you must supply the FQDN")); 1833 printf (" %s\n", _("checking a virtual server that uses 'host headers' you must supply the FQDN"));
1609 printf (" %s\n", _("(fully qualified domain name) as the [host_name] argument.")); 1834 printf (" %s\n", _("(fully qualified domain name) as the [host_name] argument."));
@@ -1642,7 +1867,8 @@ print_help (void)
1642 printf (" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> -S(sl) -j CONNECT -H <webserver>")); 1867 printf (" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> -S(sl) -j CONNECT -H <webserver>"));
1643 printf (" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds")); 1868 printf (" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds"));
1644 printf (" %s\n", _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); 1869 printf (" %s\n", _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,"));
1645 printf (" %s\n", _("a STATE_CRITICAL will be returned.")); 1870 printf (" %s\n", _("a STATE_CRITICAL will be returned. By adding a colon to the method you can set the method used"));
1871 printf (" %s\n", _("inside the proxied connection: -j CONNECT:POST"));
1646 1872
1647#endif 1873#endif
1648 1874
@@ -1659,9 +1885,11 @@ print_usage (void)
1659 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); 1885 printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname);
1660 printf (" [-J <client certificate file>] [-K <private key>]\n"); 1886 printf (" [-J <client certificate file>] [-K <private key>]\n");
1661 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); 1887 printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n");
1662 printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport>]\n"); 1888 printf (" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport>]\n");
1663 printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); 1889 printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n");
1664 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); 1890 printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n");
1665 printf (" [-A string] [-k string] [-S <version>] [--sni] [-C <warn_age>[,<crit_age>]]\n"); 1891 printf (" [-A string] [-k string] [-S <version>] [--sni]\n");
1666 printf (" [-T <content-type>] [-j method]\n"); 1892 printf (" [-T <content-type>] [-j method]\n");
1893 printf (" %s -H <vhost> | -I <IP-address> -C <warn_age>[,<crit_age>]\n",progname);
1894 printf (" [-p <port>] [-t <timeout>] [-4|-6] [--sni]\n");
1667} 1895}