X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=plugins%2Fcheck_http.c;h=3ec9e4992211ce2fe3a6b7368f4533dd3b691a77;hb=22bd672d19c378f1e6124ee18e64e5a88cf53739;hp=27127d6af63e8bafd7097a9b146a39251555aa1b;hpb=f4f92be60c94fd4e0dd4b2b4b3101543eedb706a;p=nagiosplug.git diff --git a/plugins/check_http.c b/plugins/check_http.c index 27127d6..3ec9e49 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c @@ -79,11 +79,6 @@ int errcode; struct timeval tv; -#define server_type_check(server_type) \ -(strcmp (server_type, "https") ? FALSE : TRUE) - -#define server_port_check(use_ssl) (use_ssl ? HTTPS_PORT : HTTP_PORT) - #define HTTP_URL "/" #define CRLF "\r\n" @@ -110,13 +105,18 @@ int use_ssl = FALSE; int verbose = FALSE; int sd; int min_page_len = 0; +int redir_depth = 0; +int max_depth = 15; char *http_method; char *http_post_data; char buffer[MAX_INPUT_BUFFER]; int process_arguments (int, char **); -static char *base64 (char *bin, size_t len); +static char *base64 (const char *bin, size_t len); int check_http (void); +int redir (char *pos, char *status_line); +int server_type_check(const char *type); +int server_port_check(int ssl_flag); int my_recv (void); int my_close (void); void print_help (void); @@ -304,13 +304,13 @@ process_arguments (int argc, char **argv) break; /* Note: H, I, and u must be malloc'd or will fail on redirects */ case 'H': /* Host Name (virtual host) */ - host_name = optarg; + host_name = strdup (optarg); break; case 'I': /* Server IP-address */ - server_address = optarg; + server_address = strdup (optarg); break; case 'u': /* URL path */ - asprintf (&server_url, "%s", optarg); + server_url = strdup (optarg); server_url_length = strlen (server_url); break; case 'p': /* Server port */ @@ -328,7 +328,7 @@ process_arguments (int argc, char **argv) case 'P': /* HTTP POST data in URL encoded format */ if (http_method || http_post_data) break; http_method = strdup("POST"); - http_post_data = optarg; + http_post_data = strdup (optarg); break; case 's': /* string or substring */ strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); @@ -387,7 +387,7 @@ process_arguments (int argc, char **argv) server_address = strdup (argv[c++]); if (host_name == NULL && c < argc) - asprintf (&host_name, "%s", argv[c++]); + host_name = strdup (argv[c++]); if (server_address == NULL) { if (host_name == NULL) @@ -409,7 +409,7 @@ process_arguments (int argc, char **argv) /* written by lauri alanko */ static char * -base64 (char *bin, size_t len) +base64 (const char *bin, size_t len) { char *buf = (char *) malloc ((len + 2) / 3 * 4 + 1); @@ -450,17 +450,7 @@ base64 (char *bin, size_t len) -/* per RFC 2396 */ -#define HDR_LOCATION "%*[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]: " -#define URI_HTTP "%[HTPShtps]://" -#define URI_HOST "%[-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]" -#define URI_PORT ":%[0123456789]" -#define URI_PATH "%[-_.!~*'();/?:@&=+$,%#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]" -#define HD1 HDR_LOCATION URI_HTTP URI_HOST URI_PORT URI_PATH -#define HD2 HDR_LOCATION URI_HTTP URI_HOST URI_PATH -#define HD3 HDR_LOCATION URI_HTTP URI_HOST URI_PORT -#define HD4 HDR_LOCATION URI_HTTP URI_HOST -#define HD5 HDR_LOCATION URI_PATH + int check_http (void) @@ -475,8 +465,6 @@ check_http (void) char *full_page; char *buf; char *pos; - char *x; - char *orig_url; long microsec; double elapsed_time; int page_len = 0; @@ -489,7 +477,7 @@ check_http (void) if (use_ssl == TRUE) { if (connect_SSL () != OK) { - die (STATE_CRITICAL, _("Unable to open TCP socket")); + die (STATE_CRITICAL, _("Unable to open TCP socket\n")); } if ((server_cert = SSL_get_peer_certificate (ssl)) != NULL) { @@ -504,7 +492,7 @@ check_http (void) else { #endif if (my_tcp_connect (server_address, server_port, &sd) != STATE_OK) - die (STATE_CRITICAL, _("Unable to open TCP socket")); + die (STATE_CRITICAL, _("Unable to open TCP socket\n")); #ifdef HAVE_SSL } #endif @@ -565,12 +553,12 @@ check_http (void) if ( sslerr == SSL_ERROR_SSL ) { die (STATE_WARNING, _("Client Certificate Required\n")); } else { - die (STATE_CRITICAL, _("Error in recv()")); + die (STATE_CRITICAL, _("Error in recv()\n")); } } else { #endif - die (STATE_CRITICAL, _("Error in recv()")); + die (STATE_CRITICAL, _("Error in recv()\n")); #ifdef HAVE_SSL } #endif @@ -578,7 +566,7 @@ check_http (void) /* return a CRITICAL status if we couldn't read any data */ if (pagesize == (size_t) 0) - die (STATE_CRITICAL, _("No data received %s"), timestamp); + die (STATE_CRITICAL, _("No data received %s\n"), timestamp); /* close the connection */ my_close (); @@ -590,7 +578,7 @@ check_http (void) page = full_page; if (verbose) - printf ("Page is %d characters\n", pagesize); + printf ("%s://%s:%d%s is %d characters\n", server_type, server_address, server_port, server_url, pagesize); /* find status line and null-terminate it */ status_line = page; @@ -643,92 +631,33 @@ check_http (void) /* check the return code */ /* server errors result in a critical state */ - if (strstr (status_line, "500") || - strstr (status_line, "501") || - strstr (status_line, "502") || - strstr (status_line, "503")) { - die (STATE_CRITICAL, _("HTTP CRITICAL: %s\n"), status_line); + if (strstr (status_line, "500") || strstr (status_line, "501") || + strstr (status_line, "502") || strstr (status_line, "503") || + strstr (status_line, "504") || strstr (status_line, "505")) { + die (STATE_CRITICAL, _("HTTP CRITICAL: %s\n"), status_line); } /* client errors result in a warning state */ - if (strstr (status_line, "400") || - strstr (status_line, "401") || - strstr (status_line, "402") || - strstr (status_line, "403") || - strstr (status_line, "404")) { + if (strstr (status_line, "400") || strstr (status_line, "401") || + strstr (status_line, "402") || strstr (status_line, "403") || + strstr (status_line, "404") || strstr (status_line, "405") || + strstr (status_line, "406") || strstr (status_line, "407") || + strstr (status_line, "408") || strstr (status_line, "409") || + strstr (status_line, "410") || strstr (status_line, "411") || + strstr (status_line, "412") || strstr (status_line, "413") || + strstr (status_line, "414") || strstr (status_line, "415") || + strstr (status_line, "416") || strstr (status_line, "417")) { die (STATE_WARNING, _("HTTP WARNING: %s\n"), status_line); } /* check redirected page if specified */ - if (strstr (status_line, "300") || - strstr (status_line, "301") || - strstr (status_line, "302") || - strstr (status_line, "303") || - strstr (status_line, "304")) { - if (onredirect == STATE_DEPENDENT) { - - asprintf (&orig_url, "%s", server_url); - pos = header; - while (pos) { - server_address = realloc (server_address, MAX_IPV4_HOSTLENGTH + 1); - if (server_address == NULL) - die (STATE_UNKNOWN,_("ERROR: could not allocate server_address")); - if (strcspn (pos, "\r\n") > (size_t)server_url_length) { - server_url = realloc (server_url, strcspn (pos, "\r\n")); - if (server_url == NULL) - die (STATE_UNKNOWN, _("ERROR: could not allocate server_url")); - server_url_length = strcspn (pos, "\r\n"); - } - /* HDR_LOCATION, URI_HTTP, URI_HOST, URI_PORT, URI_PATH */ - if (sscanf (pos, HD1, server_type, server_address, server_port_text, server_url) == 4) { - if (host_name != NULL) free(host_name); - host_name = strdup(server_address); - use_ssl = server_type_check (server_type); - server_port = atoi (server_port_text); - check_http (); - } - /* HDR_LOCATION URI_HTTP URI_HOST URI_PATH */ - else if (sscanf (pos, HD2, server_type, server_address, server_url) == 3 ) { - if (host_name != NULL) free(host_name); - host_name = strdup(server_address); - use_ssl = server_type_check (server_type); - server_port = server_port_check (use_ssl); - check_http (); - } - /* HDR_LOCATION URI_HTTP URI_HOST URI_PORT */ - else if(sscanf (pos, HD3, server_type, server_address, server_port_text) == 3) { - if (host_name != NULL) free(host_name); - host_name = strdup(server_address); - strcpy (server_url, "/"); - use_ssl = server_type_check (server_type); - server_port = atoi (server_port_text); - check_http (); - } - /* HDR_LOCATION URI_HTTP URI_HOST */ - else if(sscanf (pos, HD4, server_type, server_address) == 2) { - if (host_name != NULL) free(host_name); - host_name = strdup(server_address); - strcpy (server_url, "/"); - use_ssl = server_type_check (server_type); - server_port = server_port_check (use_ssl); - check_http (); - } - /* HDR_LOCATION URI_PATH */ - else if (sscanf (pos, HD5, server_url) == 1) { - if ((server_url[0] != '/') && (x = strrchr(orig_url, '/'))) { - *x = '\0'; - asprintf (&server_url, "%s/%s", orig_url, server_url); - } - check_http (); - } - pos += (size_t) strcspn (pos, "\r\n"); - pos += (size_t) strspn (pos, "\r\n"); - } /* end while (pos) */ - printf (_("UNKNOWN - Could not find redirect location - %s%s"), - status_line, (display_html ? "" : "")); - exit (STATE_UNKNOWN); - } /* end if (onredirect == STATE_DEPENDENT) */ - + if (strstr (status_line, "300") || strstr (status_line, "301") || + strstr (status_line, "302") || strstr (status_line, "303") || + strstr (status_line, "304") || strstr (status_line, "305") || + strstr (status_line, "306")) { + + if (onredirect == STATE_DEPENDENT) + redir (header, status_line); else if (onredirect == STATE_UNKNOWN) printf (_("UNKNOWN")); else if (onredirect == STATE_OK) @@ -817,6 +746,149 @@ check_http (void) + +/* per RFC 2396 */ +#define HDR_LOCATION "%*[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]: " +#define URI_HTTP "%[HTPShtps]://" +#define URI_HOST "%[-.abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]" +#define URI_PORT ":%[0123456789]" +#define URI_PATH "%[-_.!~*'();/?:@&=+$,%#abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789]" +#define HD1 URI_HTTP URI_HOST URI_PORT URI_PATH +#define HD2 URI_HTTP URI_HOST URI_PATH +#define HD3 URI_HTTP URI_HOST URI_PORT +#define HD4 URI_HTTP URI_HOST +#define HD5 URI_PATH + +int +redir (char *pos, char *status_line) +{ + int i = 0; + char *x; + char xx[2]; + char type[6]; + char *addr; + char port[6]; + char *url; + + addr = malloc (MAX_IPV4_HOSTLENGTH + 1); + if (addr == NULL) + die (STATE_UNKNOWN, _("ERROR: could not allocate addr\n")); + + url = malloc (strcspn (pos, "\r\n")); + if (url == NULL) + die (STATE_UNKNOWN, _("ERROR: could not allocate url\n")); + + while (pos) { + + if (sscanf (pos, "%[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]:%n", xx, &i) > 0) { + + pos += i; + pos += strspn (pos, " \t\r\n"); + + /* URI_HTTP, URI_HOST, URI_PORT, URI_PATH */ + if (sscanf (pos, HD1, type, addr, port, url) == 4) { + use_ssl = server_type_check (type); + i = atoi (port); + } + + /* URI_HTTP URI_HOST URI_PATH */ + else if (sscanf (pos, HD2, type, addr, url) == 3 ) { + use_ssl = server_type_check (type); + i = server_port_check (use_ssl); + } + + /* URI_HTTP URI_HOST URI_PORT */ + else if(sscanf (pos, HD3, type, addr, port) == 3) { + strcpy (url, HTTP_URL); + use_ssl = server_type_check (type); + i = atoi (port); + } + + /* URI_HTTP URI_HOST */ + else if(sscanf (pos, HD4, type, addr) == 2) { + strcpy (url, HTTP_URL); + use_ssl = server_type_check (type); + i = server_port_check (use_ssl); + } + + /* URI_PATH */ + else if (sscanf (pos, HD5, url) == 1) { + /* relative url */ + if ((url[0] != '/')) { + if ((x = strrchr(url, '/'))) + *x = '\0'; + asprintf (&server_url, "%s/%s", server_url, url); + } + i = server_port; + strcpy (type, server_type); + strcpy (addr, host_name); + } + + else { + die (STATE_UNKNOWN, + _("UNKNOWN - Could not parse redirect location - %s%s\n"), + pos, (display_html ? "" : "")); + } + + break; + + } else { + + pos += (size_t) strcspn (pos, "\r\n"); + pos += (size_t) strspn (pos, "\r\n"); + if (strlen(pos) == 0) + die (STATE_UNKNOWN, + _("UNKNOWN - Could not find redirect location - %s%s\n"), + status_line, (display_html ? "" : "")); + + } + + } /* end while (pos) */ + + if (++redir_depth > max_depth) + die (STATE_WARNING, + _("WARNING - maximum redirection depth %d exceeded - %s://%s:%d%s%s\n"), + max_depth, type, addr, i, url, (display_html ? "" : "")); + + if (server_port==i && + !strcmp(server_address, addr) && + (host_name && !strcmp(host_name, addr)) && + !strcmp(server_url, url)) + die (STATE_WARNING, + _("WARNING - redirection creates an infinite loop - %s://%s:%d%s%s\n"), + type, addr, i, url, (display_html ? "" : "")); + + server_port = i; + strcpy (server_type, type); + asprintf (&host_name, "%s", addr); + asprintf (&server_address, "%s", addr); + asprintf (&server_url, "%s", url); + + return check_http (); +} + + + +int +server_type_check (const char *type) +{ + if (strcmp (type, "https")) + return FALSE; + else + return TRUE; +} + +int +server_port_check (int ssl_flag) +{ + if (ssl_flag) + return HTTPS_PORT; + else + return HTTP_PORT; +} + + + #ifdef HAVE_SSL int connect_SSL (void) { @@ -920,7 +992,7 @@ check_certificate (X509 ** certificate) days_left = (mktime (&stamp) - time (NULL)) / 86400; snprintf - (timestamp, 16, "%02d/%02d/%04d %02d:%02d", + (timestamp, 17, "%02d/%02d/%04d %02d:%02d", stamp.tm_mon + 1, stamp.tm_mday, stamp.tm_year + 1900, stamp.tm_hour, stamp.tm_min);