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 | { |
