summaryrefslogtreecommitdiffstats
path: root/plugins
diff options
context:
space:
mode:
Diffstat (limited to 'plugins')
-rw-r--r--plugins/check_http.c182
1 files changed, 100 insertions, 82 deletions
diff --git a/plugins/check_http.c b/plugins/check_http.c
index eba8ac27..e2047edd 100644
--- a/plugins/check_http.c
+++ b/plugins/check_http.c
@@ -40,22 +40,22 @@ enum {
40#include <ssl.h> 40#include <ssl.h>
41#include <err.h> 41#include <err.h>
42#include <rand.h> 42#include <rand.h>
43#endif 43#else
44 44# ifdef HAVE_OPENSSL_SSL_H
45#ifdef HAVE_OPENSSL_SSL_H 45# include <openssl/rsa.h>
46#include <openssl/rsa.h> 46# include <openssl/crypto.h>
47#include <openssl/crypto.h> 47# include <openssl/x509.h>
48#include <openssl/x509.h> 48# include <openssl/pem.h>
49#include <openssl/pem.h> 49# include <openssl/ssl.h>
50#include <openssl/ssl.h> 50# include <openssl/err.h>
51#include <openssl/err.h> 51# include <openssl/rand.h>
52#include <openssl/rand.h> 52# endif
53#endif 53#endif
54 54
55#ifdef HAVE_SSL 55#ifdef HAVE_SSL
56int check_cert = FALSE; 56int check_cert = FALSE;
57int days_till_exp; 57int days_till_exp;
58char *randbuff = ""; 58char *randbuff;
59SSL_CTX *ctx; 59SSL_CTX *ctx;
60SSL *ssl; 60SSL *ssl;
61X509 *server_cert; 61X509 *server_cert;
@@ -84,14 +84,6 @@ struct timeval tv;
84 84
85#define server_port_check(use_ssl) (use_ssl ? HTTPS_PORT : HTTP_PORT) 85#define server_port_check(use_ssl) (use_ssl ? HTTPS_PORT : HTTP_PORT)
86 86
87/* per RFC 2396 */
88
89#define HDR_LOCATION "%*[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]: "
90#define URI_HTTP "%[HTPShtps]://"
91#define URI_HOST "%[-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]"
92#define URI_PORT ":%[0123456789]"
93#define URI_PATH "%[-_.!~*'();/?:@&=+$,%#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]"
94
95#define HTTP_URL "/" 87#define HTTP_URL "/"
96#define CRLF "\r\n" 88#define CRLF "\r\n"
97 89
@@ -100,9 +92,9 @@ int specify_port = FALSE;
100int server_port = HTTP_PORT; 92int server_port = HTTP_PORT;
101char server_port_text[6] = ""; 93char server_port_text[6] = "";
102char server_type[6] = "http"; 94char server_type[6] = "http";
103char *server_address = ""; 95char *server_address;
104char *host_name = ""; 96char *host_name;
105char *server_url = ""; 97char *server_url;
106int server_url_length; 98int server_url_length;
107int server_expect_yn = 0; 99int server_expect_yn = 0;
108char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; 100char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT;
@@ -118,8 +110,8 @@ int use_ssl = FALSE;
118int verbose = FALSE; 110int verbose = FALSE;
119int sd; 111int sd;
120int min_page_len = 0; 112int min_page_len = 0;
121char *http_method = "GET"; 113char *http_method;
122char *http_post_data = ""; 114char *http_post_data;
123char buffer[MAX_INPUT_BUFFER]; 115char buffer[MAX_INPUT_BUFFER];
124 116
125int process_arguments (int, char **); 117int process_arguments (int, char **);
@@ -136,7 +128,7 @@ main (int argc, char **argv)
136 int result = STATE_UNKNOWN; 128 int result = STATE_UNKNOWN;
137 129
138 /* Set default URL. Must be malloced for subsequent realloc if --onredirect=follow */ 130 /* Set default URL. Must be malloced for subsequent realloc if --onredirect=follow */
139 asprintf (&server_url, "%s", HTTP_URL); 131 server_url = strdup(HTTP_URL);
140 server_url_length = strlen(server_url); 132 server_url_length = strlen(server_url);
141 133
142 if (process_arguments (argc, argv) == ERROR) 134 if (process_arguments (argc, argv) == ERROR)
@@ -161,8 +153,7 @@ main (int argc, char **argv)
161#ifdef HAVE_SSL 153#ifdef HAVE_SSL
162 if (use_ssl && check_cert == TRUE) { 154 if (use_ssl && check_cert == TRUE) {
163 if (connect_SSL () != OK) 155 if (connect_SSL () != OK)
164 die (STATE_CRITICAL, 156 die (STATE_CRITICAL, _("HTTP CRITICAL - Could not make SSL connection\n"));
165 _("HTTP CRITICAL - Could not make SSL connection\n"));
166 if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { 157 if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) {
167 result = check_certificate (&server_cert); 158 result = check_certificate (&server_cert);
168 X509_free (server_cert); 159 X509_free (server_cert);
@@ -313,16 +304,16 @@ process_arguments (int argc, char **argv)
313 break; 304 break;
314 /* Note: H, I, and u must be malloc'd or will fail on redirects */ 305 /* Note: H, I, and u must be malloc'd or will fail on redirects */
315 case 'H': /* Host Name (virtual host) */ 306 case 'H': /* Host Name (virtual host) */
316 asprintf (&host_name, "%s", optarg); 307 host_name = strdup (optarg);
317 break; 308 break;
318 case 'I': /* Server IP-address */ 309 case 'I': /* Server IP-address */
319 asprintf (&server_address, "%s", optarg); 310 server_address = strdup(optarg);
320 break; 311 break;
321 case 'u': /* Host or server */ 312 case 'u': /* URL path */
322 asprintf (&server_url, "%s", optarg); 313 asprintf (&server_url, "%s", optarg);
323 server_url_length = strlen (server_url); 314 server_url_length = strlen (server_url);
324 break; 315 break;
325 case 'p': /* Host or server */ 316 case 'p': /* Server port */
326 if (!is_intnonneg (optarg)) 317 if (!is_intnonneg (optarg))
327 usage2 (_("invalid port number"), optarg); 318 usage2 (_("invalid port number"), optarg);
328 else { 319 else {
@@ -335,8 +326,9 @@ process_arguments (int argc, char **argv)
335 user_auth[MAX_INPUT_BUFFER - 1] = 0; 326 user_auth[MAX_INPUT_BUFFER - 1] = 0;
336 break; 327 break;
337 case 'P': /* HTTP POST data in URL encoded format */ 328 case 'P': /* HTTP POST data in URL encoded format */
338 asprintf (&http_method, "%s", "POST"); 329 if (http_method || http_post_data) break;
339 asprintf (&http_post_data, "%s", optarg); 330 http_method = strdup("POST");
331 http_post_data = strdup(optarg);
340 break; 332 break;
341 case 's': /* string or substring */ 333 case 's': /* string or substring */
342 strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); 334 strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1);
@@ -391,22 +383,25 @@ process_arguments (int argc, char **argv)
391 383
392 c = optind; 384 c = optind;
393 385
394 if (strcmp (server_address, "") == 0 && c < argc) 386 if (server_address == NULL && c < argc)
395 asprintf (&server_address, "%s", argv[c++]); 387 server_address = strdup (argv[c++]);
396 388
397 if (strcmp (host_name, "") == 0 && c < argc) 389 if (host_name == NULL && c < argc)
398 asprintf (&host_name, "%s", argv[c++]); 390 asprintf (&host_name, "%s", argv[c++]);
399 391
400 if (strcmp (server_address ,"") == 0) { 392 if (server_address == NULL) {
401 if (strcmp (host_name, "") == 0) 393 if (host_name == NULL)
402 usage (_("check_http: you must specify a server address or host name\n")); 394 usage (_("check_http: you must specify a server address or host name\n"));
403 else 395 else
404 asprintf (&server_address, "%s", host_name); 396 server_address = strdup (host_name);
405 } 397 }
406 398
407 if (check_critical_time && critical_time>(double)socket_timeout) 399 if (check_critical_time && critical_time>(double)socket_timeout)
408 socket_timeout = (int)critical_time + 1; 400 socket_timeout = (int)critical_time + 1;
409 401
402 if (http_method == NULL)
403 http_method = strdup ("GET");
404
410 return TRUE; 405 return TRUE;
411} 406}
412 407
@@ -455,21 +450,34 @@ base64 (char *bin, size_t len)
455 450
456 451
457 452
453/* per RFC 2396 */
454#define HDR_LOCATION "%*[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]: "
455#define URI_HTTP "%[HTPShtps]://"
456#define URI_HOST "%[-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]"
457#define URI_PORT ":%[0123456789]"
458#define URI_PATH "%[-_.!~*'();/?:@&=+$,%#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]"
459#define HD1 HDR_LOCATION URI_HTTP URI_HOST URI_PORT URI_PATH
460#define HD2 HDR_LOCATION URI_HTTP URI_HOST URI_PATH
461#define HD3 HDR_LOCATION URI_HTTP URI_HOST URI_PORT
462#define HD4 HDR_LOCATION URI_HTTP URI_HOST
463#define HD5 HDR_LOCATION URI_PATH
464
458int 465int
459check_http (void) 466check_http (void)
460{ 467{
461 char *msg = NULL; 468 char *msg;
462 char *status_line = ""; 469 char *status_line;
463 char *header = NULL; 470 char *header;
464 char *page = ""; 471 char *page;
465 char *auth = NULL; 472 char *auth;
466 int i = 0; 473 int i = 0;
467 size_t pagesize = 0; 474 size_t pagesize = 0;
468 char *full_page = ""; 475 char *full_page;
469 char *buf = NULL; 476 char *buf;
470 char *pos = ""; 477 char *pos;
471 char *x = NULL; 478 char *x;
472 char *orig_url = NULL; 479 char *orig_url;
480 long microsec;
473 double elapsed_time; 481 double elapsed_time;
474 int page_len = 0; 482 int page_len = 0;
475#ifdef HAVE_SSL 483#ifdef HAVE_SSL
@@ -504,7 +512,7 @@ check_http (void)
504 asprintf (&buf, "%s %s HTTP/1.0\r\n", http_method, server_url); 512 asprintf (&buf, "%s %s HTTP/1.0\r\n", http_method, server_url);
505 513
506 /* optionally send the host header info (not clear if it's usable) */ 514 /* optionally send the host header info (not clear if it's usable) */
507 if (strcmp (host_name, "")) 515 if (host_name)
508 asprintf (&buf, "%sHost: %s\r\n", buf, host_name); 516 asprintf (&buf, "%sHost: %s\r\n", buf, host_name);
509 517
510 /* send user agent */ 518 /* send user agent */
@@ -512,13 +520,13 @@ check_http (void)
512 buf, clean_revstring (revision), VERSION); 520 buf, clean_revstring (revision), VERSION);
513 521
514 /* optionally send the authentication info */ 522 /* optionally send the authentication info */
515 if (strcmp (user_auth, "")) { 523 if (strlen(user_auth)) {
516 auth = base64 (user_auth, strlen (user_auth)); 524 auth = base64 (user_auth, strlen (user_auth));
517 asprintf (&buf, "%sAuthorization: Basic %s\r\n", buf, auth); 525 asprintf (&buf, "%sAuthorization: Basic %s\r\n", buf, auth);
518 } 526 }
519 527
520 /* either send http POST data */ 528 /* either send http POST data */
521 if (strlen (http_post_data)) { 529 if (http_post_data) {
522 asprintf (&buf, "%sContent-Type: application/x-www-form-urlencoded\r\n", buf); 530 asprintf (&buf, "%sContent-Type: application/x-www-form-urlencoded\r\n", buf);
523 asprintf (&buf, "%sContent-Length: %i\r\n\r\n", buf, strlen (http_post_data)); 531 asprintf (&buf, "%sContent-Length: %i\r\n\r\n", buf, strlen (http_post_data));
524 asprintf (&buf, "%s%s%s", buf, http_post_data, CRLF); 532 asprintf (&buf, "%s%s%s", buf, http_post_data, CRLF);
@@ -543,6 +551,7 @@ check_http (void)
543#endif 551#endif
544 552
545 /* fetch the page */ 553 /* fetch the page */
554 full_page = strdup("");
546 while ((i = my_recv ()) > 0) { 555 while ((i = my_recv ()) > 0) {
547 buffer[i] = '\0'; 556 buffer[i] = '\0';
548 asprintf (&full_page, "%s%s", full_page, buffer); 557 asprintf (&full_page, "%s%s", full_page, buffer);
@@ -663,42 +672,49 @@ check_http (void)
663 while (pos) { 672 while (pos) {
664 server_address = realloc (server_address, MAX_IPV4_HOSTLENGTH + 1); 673 server_address = realloc (server_address, MAX_IPV4_HOSTLENGTH + 1);
665 if (server_address == NULL) 674 if (server_address == NULL)
666 die (STATE_UNKNOWN, 675 die (STATE_UNKNOWN,_("ERROR: could not allocate server_address"));
667 _("HTTP UNKNOWN: could not allocate server_address"));
668 if (strcspn (pos, "\r\n") > (size_t)server_url_length) { 676 if (strcspn (pos, "\r\n") > (size_t)server_url_length) {
669 server_url = realloc (server_url, strcspn (pos, "\r\n")); 677 server_url = realloc (server_url, strcspn (pos, "\r\n"));
670 if (server_url == NULL) 678 if (server_url == NULL)
671 die (STATE_UNKNOWN, 679 die (STATE_UNKNOWN, _("ERROR: could not allocate server_url"));
672 _("HTTP UNKNOWN: could not allocate server_url"));
673 server_url_length = strcspn (pos, "\r\n"); 680 server_url_length = strcspn (pos, "\r\n");
674 } 681 }
675 if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST URI_PORT URI_PATH, server_type, server_address, server_port_text, server_url) == 4) { 682 /* HDR_LOCATION, URI_HTTP, URI_HOST, URI_PORT, URI_PATH */
676 asprintf (&host_name, "%s", server_address); 683 if (sscanf (pos, HD1, server_type, server_address, server_port_text, server_url) == 4) {
684 if (host_name != NULL) free(host_name);
685 host_name = strdup(server_address);
677 use_ssl = server_type_check (server_type); 686 use_ssl = server_type_check (server_type);
678 server_port = atoi (server_port_text); 687 server_port = atoi (server_port_text);
679 check_http (); 688 check_http ();
680 } 689 }
681 else if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST URI_PATH, server_type, server_address, server_url) == 3 ) { 690 /* HDR_LOCATION URI_HTTP URI_HOST URI_PATH */
682 asprintf (&host_name, "%s", server_address); 691 else if (sscanf (pos, HD2, server_type, server_address, server_url) == 3 ) {
692 if (host_name != NULL) free(host_name);
693 host_name = strdup(server_address);
683 use_ssl = server_type_check (server_type); 694 use_ssl = server_type_check (server_type);
684 server_port = server_port_check (use_ssl); 695 server_port = server_port_check (use_ssl);
685 check_http (); 696 check_http ();
686 } 697 }
687 else if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST URI_PORT, server_type, server_address, server_port_text) == 3) { 698 /* HDR_LOCATION URI_HTTP URI_HOST URI_PORT */
688 asprintf (&host_name, "%s", server_address); 699 else if(sscanf (pos, HD3, server_type, server_address, server_port_text) == 3) {
700 if (host_name != NULL) free(host_name);
701 host_name = strdup(server_address);
689 strcpy (server_url, "/"); 702 strcpy (server_url, "/");
690 use_ssl = server_type_check (server_type); 703 use_ssl = server_type_check (server_type);
691 server_port = atoi (server_port_text); 704 server_port = atoi (server_port_text);
692 check_http (); 705 check_http ();
693 } 706 }
694 else if (sscanf (pos, HDR_LOCATION URI_HTTP URI_HOST, server_type, server_address) == 2) { 707 /* HDR_LOCATION URI_HTTP URI_HOST */
695 asprintf (&host_name, "%s", server_address); 708 else if(sscanf (pos, HD4, server_type, server_address) == 2) {
709 if (host_name != NULL) free(host_name);
710 host_name = strdup(server_address);
696 strcpy (server_url, "/"); 711 strcpy (server_url, "/");
697 use_ssl = server_type_check (server_type); 712 use_ssl = server_type_check (server_type);
698 server_port = server_port_check (use_ssl); 713 server_port = server_port_check (use_ssl);
699 check_http (); 714 check_http ();
700 } 715 }
701 else if (sscanf (pos, HDR_LOCATION URI_PATH, server_url) == 1) { 716 /* HDR_LOCATION URI_PATH */
717 else if (sscanf (pos, HD5, server_url) == 1) {
702 if ((server_url[0] != '/') && (x = strrchr(orig_url, '/'))) { 718 if ((server_url[0] != '/') && (x = strrchr(orig_url, '/'))) {
703 *x = '\0'; 719 *x = '\0';
704 asprintf (&server_url, "%s/%s", orig_url, server_url); 720 asprintf (&server_url, "%s/%s", orig_url, server_url);
@@ -721,10 +737,11 @@ check_http (void)
721 printf (_("WARNING")); 737 printf (_("WARNING"));
722 else if (onredirect == STATE_CRITICAL) 738 else if (onredirect == STATE_CRITICAL)
723 printf (_("CRITICAL")); 739 printf (_("CRITICAL"));
724 elapsed_time = delta_time (tv); 740 microsec = deltime (tv);
725 asprintf (&msg, _(" - %s - %.3f second response time %s%s|time=%.3f\n"), 741 elapsed_time = (double)microsec / 1.0e6;
742 asprintf (&msg, _(" - %s - %.3f second response time %s%s|time=%ldus size=%dB\n"),
726 status_line, elapsed_time, timestamp, 743 status_line, elapsed_time, timestamp,
727 (display_html ? "</A>" : ""), elapsed_time); 744 (display_html ? "</A>" : ""), microsec, pagesize);
728 die (onredirect, "%s", msg); 745 die (onredirect, "%s", msg);
729 } /* end if (strstr (status_line, "30[0-4]") */ 746 } /* end if (strstr (status_line, "30[0-4]") */
730 747
@@ -733,10 +750,11 @@ check_http (void)
733 750
734 751
735 /* check elapsed time */ 752 /* check elapsed time */
736 elapsed_time = delta_time (tv); 753 microsec = deltime (tv);
737 asprintf (&msg, _("HTTP problem: %s - %.3f second response time %s%s|time=%.3f\n"), 754 elapsed_time = (double)microsec / 1.0e6;
755 asprintf (&msg, _("HTTP problem: %s - %.3f second response time %s%s|time=%ldus size=%dB\n"),
738 status_line, elapsed_time, timestamp, 756 status_line, elapsed_time, timestamp,
739 (display_html ? "</A>" : ""), elapsed_time); 757 (display_html ? "</A>" : ""), microsec, pagesize);
740 if (check_critical_time == TRUE && elapsed_time > critical_time) 758 if (check_critical_time == TRUE && elapsed_time > critical_time)
741 die (STATE_CRITICAL, "%s", msg); 759 die (STATE_CRITICAL, "%s", msg);
742 if (check_warning_time == TRUE && elapsed_time > warning_time) 760 if (check_warning_time == TRUE && elapsed_time > warning_time)
@@ -747,14 +765,14 @@ check_http (void)
747 765
748 if (strlen (string_expect)) { 766 if (strlen (string_expect)) {
749 if (strstr (page, string_expect)) { 767 if (strstr (page, string_expect)) {
750 printf (_("HTTP OK %s - %.3f second response time %s%s|time=%.3f\n"), 768 printf (_("HTTP OK %s - %.3f second response time %s%s|time=%ldus size=%dB\n"),
751 status_line, elapsed_time, 769 status_line, elapsed_time,
752 timestamp, (display_html ? "</A>" : ""), elapsed_time); 770 timestamp, (display_html ? "</A>" : ""), microsec, pagesize);
753 exit (STATE_OK); 771 exit (STATE_OK);
754 } 772 }
755 else { 773 else {
756 printf (_("CRITICAL - string not found%s|time=%.3f\n"), 774 printf (_("CRITICAL - string not found%s|time=%ldus\n size=%dB"),
757 (display_html ? "</A>" : ""), elapsed_time); 775 (display_html ? "</A>" : ""), microsec, pagesize);
758 exit (STATE_CRITICAL); 776 exit (STATE_CRITICAL);
759 } 777 }
760 } 778 }
@@ -762,15 +780,15 @@ check_http (void)
762 if (strlen (regexp)) { 780 if (strlen (regexp)) {
763 errcode = regexec (&preg, page, REGS, pmatch, 0); 781 errcode = regexec (&preg, page, REGS, pmatch, 0);
764 if (errcode == 0) { 782 if (errcode == 0) {
765 printf (_("HTTP OK %s - %.3f second response time %s%s|time=%.3f\n"), 783 printf (_("HTTP OK %s - %.3f second response time %s%s|time=%ldus size=%dB\n"),
766 status_line, elapsed_time, 784 status_line, elapsed_time,
767 timestamp, (display_html ? "</A>" : ""), elapsed_time); 785 timestamp, (display_html ? "</A>" : ""), microsec, pagesize);
768 exit (STATE_OK); 786 exit (STATE_OK);
769 } 787 }
770 else { 788 else {
771 if (errcode == REG_NOMATCH) { 789 if (errcode == REG_NOMATCH) {
772 printf (_("CRITICAL - pattern not found%s|time=%.3f\n"), 790 printf (_("CRITICAL - pattern not found%s|time=%ldus size=%dB\n"),
773 (display_html ? "</A>" : ""), elapsed_time); 791 (display_html ? "</A>" : ""), microsec, pagesize);
774 exit (STATE_CRITICAL); 792 exit (STATE_CRITICAL);
775 } 793 }
776 else { 794 else {
@@ -790,9 +808,9 @@ check_http (void)
790 exit (STATE_WARNING); 808 exit (STATE_WARNING);
791 } 809 }
792 /* We only get here if all tests have been passed */ 810 /* We only get here if all tests have been passed */
793 asprintf (&msg, _("HTTP OK %s - %.3f second response time %s%s|time=%.3f\n"), 811 asprintf (&msg, _("HTTP OK %s - %.3f second response time %s%s|time=%ldus size=%dB\n"),
794 status_line, (float)elapsed_time, 812 status_line, elapsed_time,
795 timestamp, (display_html ? "</A>" : ""), elapsed_time); 813 timestamp, (display_html ? "</A>" : ""), microsec, pagesize);
796 die (STATE_OK, "%s", msg); 814 die (STATE_OK, "%s", msg);
797 return STATE_UNKNOWN; 815 return STATE_UNKNOWN;
798} 816}