diff options
Diffstat (limited to 'plugins')
-rw-r--r-- | plugins/check_http.c | 255 |
1 files changed, 158 insertions, 97 deletions
diff --git a/plugins/check_http.c b/plugins/check_http.c index 6d521096..b9032d16 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c | |||
@@ -79,11 +79,6 @@ int errcode; | |||
79 | 79 | ||
80 | struct timeval tv; | 80 | struct timeval tv; |
81 | 81 | ||
82 | #define server_type_check(server_type) \ | ||
83 | (strcmp (server_type, "https") ? FALSE : TRUE) | ||
84 | |||
85 | #define server_port_check(use_ssl) (use_ssl ? HTTPS_PORT : HTTP_PORT) | ||
86 | |||
87 | #define HTTP_URL "/" | 82 | #define HTTP_URL "/" |
88 | #define CRLF "\r\n" | 83 | #define CRLF "\r\n" |
89 | 84 | ||
@@ -110,13 +105,18 @@ int use_ssl = FALSE; | |||
110 | int verbose = FALSE; | 105 | int verbose = FALSE; |
111 | int sd; | 106 | int sd; |
112 | int min_page_len = 0; | 107 | int min_page_len = 0; |
108 | int redir_depth = 0; | ||
109 | int max_depth = 15; | ||
113 | char *http_method; | 110 | char *http_method; |
114 | char *http_post_data; | 111 | char *http_post_data; |
115 | char buffer[MAX_INPUT_BUFFER]; | 112 | char buffer[MAX_INPUT_BUFFER]; |
116 | 113 | ||
117 | int process_arguments (int, char **); | 114 | int process_arguments (int, char **); |
118 | static char *base64 (char *bin, size_t len); | 115 | static char *base64 (const char *bin, size_t len); |
119 | int check_http (void); | 116 | int check_http (void); |
117 | int redir (char *pos, char *status_line); | ||
118 | int server_type_check(const char *type); | ||
119 | int server_port_check(int ssl_flag); | ||
120 | int my_recv (void); | 120 | int my_recv (void); |
121 | int my_close (void); | 121 | int my_close (void); |
122 | void print_help (void); | 122 | void print_help (void); |
@@ -409,7 +409,7 @@ process_arguments (int argc, char **argv) | |||
409 | 409 | ||
410 | /* written by lauri alanko */ | 410 | /* written by lauri alanko */ |
411 | static char * | 411 | static char * |
412 | base64 (char *bin, size_t len) | 412 | base64 (const char *bin, size_t len) |
413 | { | 413 | { |
414 | 414 | ||
415 | char *buf = (char *) malloc ((len + 2) / 3 * 4 + 1); | 415 | char *buf = (char *) malloc ((len + 2) / 3 * 4 + 1); |
@@ -450,17 +450,7 @@ base64 (char *bin, size_t len) | |||
450 | 450 | ||
451 | 451 | ||
452 | 452 | ||
453 | /* per RFC 2396 */ | 453 | |
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 URI_HTTP URI_HOST URI_PORT URI_PATH | ||
460 | #define HD2 URI_HTTP URI_HOST URI_PATH | ||
461 | #define HD3 URI_HTTP URI_HOST URI_PORT | ||
462 | #define HD4 URI_HTTP URI_HOST | ||
463 | #define HD5 URI_PATH | ||
464 | 454 | ||
465 | int | 455 | int |
466 | check_http (void) | 456 | check_http (void) |
@@ -475,9 +465,6 @@ check_http (void) | |||
475 | char *full_page; | 465 | char *full_page; |
476 | char *buf; | 466 | char *buf; |
477 | char *pos; | 467 | char *pos; |
478 | char *x; | ||
479 | char xx[2]; | ||
480 | char *orig_url; | ||
481 | long microsec; | 468 | long microsec; |
482 | double elapsed_time; | 469 | double elapsed_time; |
483 | int page_len = 0; | 470 | int page_len = 0; |
@@ -490,7 +477,7 @@ check_http (void) | |||
490 | if (use_ssl == TRUE) { | 477 | if (use_ssl == TRUE) { |
491 | 478 | ||
492 | if (connect_SSL () != OK) { | 479 | if (connect_SSL () != OK) { |
493 | die (STATE_CRITICAL, _("Unable to open TCP socket")); | 480 | die (STATE_CRITICAL, _("Unable to open TCP socket\n")); |
494 | } | 481 | } |
495 | 482 | ||
496 | if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { | 483 | if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { |
@@ -505,7 +492,7 @@ check_http (void) | |||
505 | else { | 492 | else { |
506 | #endif | 493 | #endif |
507 | if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) | 494 | if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) |
508 | die (STATE_CRITICAL, _("Unable to open TCP socket")); | 495 | die (STATE_CRITICAL, _("Unable to open TCP socket\n")); |
509 | #ifdef HAVE_SSL | 496 | #ifdef HAVE_SSL |
510 | } | 497 | } |
511 | #endif | 498 | #endif |
@@ -566,12 +553,12 @@ check_http (void) | |||
566 | if ( sslerr == SSL_ERROR_SSL ) { | 553 | if ( sslerr == SSL_ERROR_SSL ) { |
567 | die (STATE_WARNING, _("Client Certificate Required\n")); | 554 | die (STATE_WARNING, _("Client Certificate Required\n")); |
568 | } else { | 555 | } else { |
569 | die (STATE_CRITICAL, _("Error in recv()")); | 556 | die (STATE_CRITICAL, _("Error in recv()\n")); |
570 | } | 557 | } |
571 | } | 558 | } |
572 | else { | 559 | else { |
573 | #endif | 560 | #endif |
574 | die (STATE_CRITICAL, _("Error in recv()")); | 561 | die (STATE_CRITICAL, _("Error in recv()\n")); |
575 | #ifdef HAVE_SSL | 562 | #ifdef HAVE_SSL |
576 | } | 563 | } |
577 | #endif | 564 | #endif |
@@ -579,7 +566,7 @@ check_http (void) | |||
579 | 566 | ||
580 | /* return a CRITICAL status if we couldn't read any data */ | 567 | /* return a CRITICAL status if we couldn't read any data */ |
581 | if (pagesize == (size_t) 0) | 568 | if (pagesize == (size_t) 0) |
582 | die (STATE_CRITICAL, _("No data received %s"), timestamp); | 569 | die (STATE_CRITICAL, _("No data received %s\n"), timestamp); |
583 | 570 | ||
584 | /* close the connection */ | 571 | /* close the connection */ |
585 | my_close (); | 572 | my_close (); |
@@ -668,78 +655,9 @@ check_http (void) | |||
668 | strstr (status_line, "302") || strstr (status_line, "303") || | 655 | strstr (status_line, "302") || strstr (status_line, "303") || |
669 | strstr (status_line, "304") || strstr (status_line, "305") || | 656 | strstr (status_line, "304") || strstr (status_line, "305") || |
670 | strstr (status_line, "306")) { | 657 | strstr (status_line, "306")) { |
671 | if (onredirect == STATE_DEPENDENT) { | ||
672 | |||
673 | server_address = realloc (server_address, MAX_IPV4_HOSTLENGTH + 1); | ||
674 | if (server_address == NULL) | ||
675 | die (STATE_UNKNOWN,_("ERROR: could not allocate server_address")); | ||
676 | |||
677 | asprintf (&orig_url, "%s", server_url); | ||
678 | if (strcspn (pos, "\r\n") > (size_t)server_url_length) { | ||
679 | server_url = realloc (server_url, strcspn (pos, "\r\n")); | ||
680 | if (server_url == NULL) | ||
681 | die (STATE_UNKNOWN, _("ERROR: could not allocate server_url")); | ||
682 | server_url_length = strcspn (pos, "\r\n"); | ||
683 | } | ||
684 | 658 | ||
685 | pos = header; | 659 | if (onredirect == STATE_DEPENDENT) |
686 | while (pos) { | 660 | redir (header, status_line); |
687 | if (sscanf (pos, "%[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]:%n", xx, &i) > 0) { | ||
688 | pos += i; | ||
689 | pos += strspn (pos, " \t\r\n"); | ||
690 | } else { | ||
691 | pos += (size_t) strcspn (pos, "\r\n"); | ||
692 | pos += (size_t) strspn (pos, "\r\n"); | ||
693 | continue; | ||
694 | } | ||
695 | /* HDR_LOCATION, URI_HTTP, URI_HOST, URI_PORT, URI_PATH */ | ||
696 | if (sscanf (pos, HD1, server_type, server_address, server_port_text, server_url) == 4) { | ||
697 | if (host_name != NULL) free(host_name); | ||
698 | host_name = strdup(server_address); | ||
699 | use_ssl = server_type_check (server_type); | ||
700 | server_port = atoi (server_port_text); | ||
701 | check_http (); | ||
702 | } | ||
703 | /* HDR_LOCATION URI_HTTP URI_HOST URI_PATH */ | ||
704 | else if (sscanf (pos, HD2, server_type, server_address, server_url) == 3 ) { | ||
705 | if (host_name != NULL) free(host_name); | ||
706 | host_name = strdup(server_address); | ||
707 | use_ssl = server_type_check (server_type); | ||
708 | server_port = server_port_check (use_ssl); | ||
709 | check_http (); | ||
710 | } | ||
711 | /* HDR_LOCATION URI_HTTP URI_HOST URI_PORT */ | ||
712 | else if(sscanf (pos, HD3, server_type, server_address, server_port_text) == 3) { | ||
713 | if (host_name != NULL) free(host_name); | ||
714 | host_name = strdup(server_address); | ||
715 | strcpy (server_url, "/"); | ||
716 | use_ssl = server_type_check (server_type); | ||
717 | server_port = atoi (server_port_text); | ||
718 | check_http (); | ||
719 | } | ||
720 | /* HDR_LOCATION URI_HTTP URI_HOST */ | ||
721 | else if(sscanf (pos, HD4, server_type, server_address) == 2) { | ||
722 | if (host_name != NULL) free(host_name); | ||
723 | host_name = strdup(server_address); | ||
724 | strcpy (server_url, "/"); | ||
725 | use_ssl = server_type_check (server_type); | ||
726 | server_port = server_port_check (use_ssl); | ||
727 | check_http (); | ||
728 | } | ||
729 | /* HDR_LOCATION URI_PATH */ | ||
730 | else if (sscanf (pos, HD5, server_url) == 1) { | ||
731 | if ((server_url[0] != '/') && (x = strrchr(orig_url, '/'))) { | ||
732 | *x = '\0'; | ||
733 | asprintf (&server_url, "%s/%s", orig_url, server_url); | ||
734 | } | ||
735 | check_http (); | ||
736 | } | ||
737 | } /* end while (pos) */ | ||
738 | printf (_("UNKNOWN - Could not find redirect location - %s%s"), | ||
739 | status_line, (display_html ? "</A>" : "")); | ||
740 | exit (STATE_UNKNOWN); | ||
741 | } /* end if (onredirect == STATE_DEPENDENT) */ | ||
742 | |||
743 | else if (onredirect == STATE_UNKNOWN) | 661 | else if (onredirect == STATE_UNKNOWN) |
744 | printf (_("UNKNOWN")); | 662 | printf (_("UNKNOWN")); |
745 | else if (onredirect == STATE_OK) | 663 | else if (onredirect == STATE_OK) |
@@ -828,6 +746,149 @@ check_http (void) | |||
828 | 746 | ||
829 | 747 | ||
830 | 748 | ||
749 | |||
750 | /* per RFC 2396 */ | ||
751 | #define HDR_LOCATION "%*[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]: " | ||
752 | #define URI_HTTP "%[HTPShtps]://" | ||
753 | #define URI_HOST "%[-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]" | ||
754 | #define URI_PORT ":%[0123456789]" | ||
755 | #define URI_PATH "%[-_.!~*'();/?:@&=+$,%#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]" | ||
756 | #define HD1 URI_HTTP URI_HOST URI_PORT URI_PATH | ||
757 | #define HD2 URI_HTTP URI_HOST URI_PATH | ||
758 | #define HD3 URI_HTTP URI_HOST URI_PORT | ||
759 | #define HD4 URI_HTTP URI_HOST | ||
760 | #define HD5 URI_PATH | ||
761 | |||
762 | int | ||
763 | redir (char *pos, char *status_line) | ||
764 | { | ||
765 | int i = 0; | ||
766 | char *x; | ||
767 | char xx[2]; | ||
768 | char type[6]; | ||
769 | char *addr; | ||
770 | char port[6]; | ||
771 | char *url; | ||
772 | |||
773 | addr = malloc (MAX_IPV4_HOSTLENGTH + 1); | ||
774 | if (addr == NULL) | ||
775 | die (STATE_UNKNOWN, _("ERROR: could not allocate addr\n")); | ||
776 | |||
777 | url = malloc (strcspn (pos, "\r\n")); | ||
778 | if (url == NULL) | ||
779 | die (STATE_UNKNOWN, _("ERROR: could not allocate url\n")); | ||
780 | |||
781 | while (pos) { | ||
782 | |||
783 | if (sscanf (pos, "%[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]:%n", xx, &i) > 0) { | ||
784 | |||
785 | pos += i; | ||
786 | pos += strspn (pos, " \t\r\n"); | ||
787 | |||
788 | /* URI_HTTP, URI_HOST, URI_PORT, URI_PATH */ | ||
789 | if (sscanf (pos, HD1, type, addr, port, url) == 4) { | ||
790 | use_ssl = server_type_check (type); | ||
791 | i = atoi (port); | ||
792 | } | ||
793 | |||
794 | /* URI_HTTP URI_HOST URI_PATH */ | ||
795 | else if (sscanf (pos, HD2, type, addr, url) == 3 ) { | ||
796 | use_ssl = server_type_check (type); | ||
797 | i = server_port_check (use_ssl); | ||
798 | } | ||
799 | |||
800 | /* URI_HTTP URI_HOST URI_PORT */ | ||
801 | else if(sscanf (pos, HD3, type, addr, port) == 3) { | ||
802 | strcpy (url, HTTP_URL); | ||
803 | use_ssl = server_type_check (type); | ||
804 | i = atoi (port); | ||
805 | } | ||
806 | |||
807 | /* URI_HTTP URI_HOST */ | ||
808 | else if(sscanf (pos, HD4, type, addr) == 2) { | ||
809 | strcpy (url, HTTP_URL); | ||
810 | use_ssl = server_type_check (type); | ||
811 | i = server_port_check (use_ssl); | ||
812 | } | ||
813 | |||
814 | /* URI_PATH */ | ||
815 | else if (sscanf (pos, HD5, url) == 1) { | ||
816 | /* relative url */ | ||
817 | if ((url[0] != '/')) { | ||
818 | if (x = strrchr(url, '/')) | ||
819 | *x = '\0'; | ||
820 | asprintf (&server_url, "%s/%s", server_url, url); | ||
821 | } | ||
822 | i = server_port; | ||
823 | strcpy (type, server_type); | ||
824 | strcpy (addr, host_name); | ||
825 | } | ||
826 | |||
827 | else { | ||
828 | die (STATE_UNKNOWN, | ||
829 | _("UNKNOWN - Could not parse redirect location - %s%s\n"), | ||
830 | pos, (display_html ? "</A>" : "")); | ||
831 | } | ||
832 | |||
833 | break; | ||
834 | |||
835 | } else { | ||
836 | |||
837 | pos += (size_t) strcspn (pos, "\r\n"); | ||
838 | pos += (size_t) strspn (pos, "\r\n"); | ||
839 | if (strlen(pos) == 0) | ||
840 | die (STATE_UNKNOWN, | ||
841 | _("UNKNOWN - Could not find redirect location - %s%s\n"), | ||
842 | status_line, (display_html ? "</A>" : "")); | ||
843 | |||
844 | } | ||
845 | |||
846 | } /* end while (pos) */ | ||
847 | |||
848 | if (++redir_depth > max_depth) | ||
849 | die (STATE_WARNING, | ||
850 | _("WARNING - maximum redirection depth %d exceeded - %s://%s:%d%s%s\n"), | ||
851 | max_depth, type, addr, i, url, (display_html ? "</A>" : "")); | ||
852 | |||
853 | if (server_port==i && | ||
854 | !strcmp(server_address, addr) && | ||
855 | (host_name && !strcmp(host_name, addr)) && | ||
856 | !strcmp(server_url, url)) | ||
857 | die (STATE_WARNING, | ||
858 | _("WARNING - redirection creates an infinite loop - %s://%s:%d%s%s\n"), | ||
859 | type, addr, i, url, (display_html ? "</A>" : "")); | ||
860 | |||
861 | server_port = i; | ||
862 | strcpy (server_type, type); | ||
863 | asprintf (&host_name, "%s", addr); | ||
864 | asprintf (&server_address, "%s", addr); | ||
865 | asprintf (&server_url, "%s", url); | ||
866 | |||
867 | return check_http (); | ||
868 | } | ||
869 | |||
870 | |||
871 | |||
872 | int | ||
873 | server_type_check (const char *type) | ||
874 | { | ||
875 | if (strcmp (type, "https")) | ||
876 | return FALSE; | ||
877 | else | ||
878 | return TRUE; | ||
879 | } | ||
880 | |||
881 | int | ||
882 | server_port_check (int ssl_flag) | ||
883 | { | ||
884 | if (ssl_flag) | ||
885 | return HTTPS_PORT; | ||
886 | else | ||
887 | return HTTP_PORT; | ||
888 | } | ||
889 | |||
890 | |||
891 | |||
831 | #ifdef HAVE_SSL | 892 | #ifdef HAVE_SSL |
832 | int connect_SSL (void) | 893 | int connect_SSL (void) |
833 | { | 894 | { |