X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=plugins%2Fcheck_http.c;h=abd8aa8dadf968f45a2fcf22ef1e02a823c5af12;hb=b699c208e858032ffd1218a4e22cb822895fa097;hp=54e5ff29619fd55b502718135111253ccc59c20b;hpb=cd8b45f633bfda6a414b4120672efa96123119f6;p=nagiosplug.git diff --git a/plugins/check_http.c b/plugins/check_http.c index 54e5ff2..abd8aa8 100644 --- a/plugins/check_http.c +++ b/plugins/check_http.c @@ -1,18 +1,37 @@ /****************************************************************************** - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. +* +* Nagios check_http plugin +* +* License: GPL +* Copyright (c) 1999-2006 nagios-plugins team +* +* Last Modified: $Date$ +* +* Description: +* +* This file contains the check_http plugin +* +* This plugin tests the HTTP service on the specified host. It can test +* normal (http) and secure (https) servers, follow redirects, search for +* strings and regular expressions, check connection times, and report on +* certificate expiration times. +* +* +* License Information: +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation; either version 2 of the License, or +* (at your option) any later version. +* +* This program is distributed in the hope that it will be useful, +* but WITHOUT ANY WARRANTY; without even the implied warranty of +* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +* GNU General Public License for more details. +* +* You should have received a copy of the GNU General Public License +* along with this program; if not, write to the Free Software +* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. $Id$ @@ -21,7 +40,7 @@ const char *progname = "check_http"; const char *revision = "$Revision$"; -const char *copyright = "1999-2005"; +const char *copyright = "1999-2006"; const char *email = "nagiosplug-devel@lists.sourceforge.net"; #include "common.h" @@ -51,19 +70,18 @@ X509 *server_cert; int no_body = FALSE; int maximum_age = -1; -#ifdef HAVE_REGEX_H enum { REGS = 2, MAX_RE_SIZE = 256 }; -#include +#include "regex.h" regex_t preg; regmatch_t pmatch[REGS]; char regexp[MAX_RE_SIZE]; char errbuf[MAX_INPUT_BUFFER]; int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; int errcode; -#endif +int invert_regex = 0; struct timeval tv; @@ -89,7 +107,8 @@ double critical_time = 0; int check_critical_time = FALSE; char user_auth[MAX_INPUT_BUFFER] = ""; int display_html = FALSE; -char *http_opt_headers; +char **http_opt_headers; +int http_opt_headers_count = 0; int onredirect = STATE_OK; int use_ssl = FALSE; int verbose = FALSE; @@ -157,6 +176,10 @@ process_arguments (int argc, char **argv) { int c = 1; + enum { + INVERT_REGEX = CHAR_MAX + 1 + }; + int option = 0; static struct option longopts[] = { STD_LONG_OPTS, @@ -181,6 +204,7 @@ process_arguments (int argc, char **argv) {"max-age", required_argument, 0, 'M'}, {"content-type", required_argument, 0, 'T'}, {"pagesize", required_argument, 0, 'm'}, + {"invert-regex", no_argument, NULL, INVERT_REGEX}, {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, {0, 0, 0, 0} @@ -245,7 +269,12 @@ process_arguments (int argc, char **argv) asprintf (&user_agent, "User-Agent: %s", optarg); break; case 'k': /* Additional headers */ - asprintf (&http_opt_headers, "%s", optarg); + if (http_opt_headers_count == 0) + http_opt_headers = malloc (sizeof (char *) * (++http_opt_headers_count)); + else + http_opt_headers = realloc (http_opt_headers, sizeof (char *) * (++http_opt_headers_count)); + http_opt_headers[http_opt_headers_count - 1] = optarg; + //asprintf (&http_opt_headers, "%s", optarg); break; case 'L': /* show html link */ display_html = TRUE; @@ -253,25 +282,23 @@ process_arguments (int argc, char **argv) case 'n': /* do not show html link */ display_html = FALSE; break; - case 'S': /* use SSL */ -#ifndef HAVE_SSL - usage4 (_("Invalid option - SSL is not available")); -#endif - use_ssl = TRUE; - if (specify_port == FALSE) - server_port = HTTPS_PORT; - break; case 'C': /* Check SSL cert validity */ -#ifdef USE_OPENSSL +#ifdef HAVE_SSL if (!is_intnonneg (optarg)) usage2 (_("Invalid certificate expiration period"), optarg); else { days_till_exp = atoi (optarg); check_cert = TRUE; } -#else + /* Fall through to -S option */ +#endif + case 'S': /* use SSL */ +#ifndef HAVE_SSL usage4 (_("Invalid option - SSL is not available")); #endif + use_ssl = TRUE; + if (specify_port == FALSE) + server_port = HTTPS_PORT; break; case 'f': /* onredirect */ if (!strcmp (optarg, "follow")) @@ -329,13 +356,6 @@ process_arguments (int argc, char **argv) case 'T': /* Content-type */ asprintf (&http_content_type, "%s", optarg); break; -#ifndef HAVE_REGEX_H - case 'l': /* linespan */ - case 'r': /* linespan */ - case 'R': /* linespan */ - usage4 (_("Call for regex which was not a compiled option")); - break; -#else case 'l': /* linespan */ cflags &= ~REG_NEWLINE; break; @@ -351,7 +371,9 @@ process_arguments (int argc, char **argv) return ERROR; } break; -#endif + case INVERT_REGEX: + invert_regex = 1; + break; case '4': address_family = AF_INET; break; @@ -769,9 +791,12 @@ check_http (void) asprintf (&buf, "%sHost: %s\r\n", buf, host_name); /* optionally send any other header tag */ - if (http_opt_headers) { - for ((pos = strtok(http_opt_headers, INPUT_DELIMITER)); pos; (pos = strtok(NULL, INPUT_DELIMITER))) - asprintf (&buf, "%s%s\r\n", buf, pos); + if (http_opt_headers_count) { + for (i = 0; i < http_opt_headers_count ; i++) { + for ((pos = strtok(http_opt_headers[i], INPUT_DELIMITER)); pos; (pos = strtok(NULL, INPUT_DELIMITER))) + asprintf (&buf, "%s%s\r\n", buf, pos); + } + free(http_opt_headers); } /* optionally send the authentication info */ @@ -985,31 +1010,34 @@ check_http (void) exit (STATE_CRITICAL); } } -#ifdef HAVE_REGEX_H + if (strlen (regexp)) { errcode = regexec (&preg, page, REGS, pmatch, 0); - if (errcode == 0) { + if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { printf (_("HTTP OK %s - %.3f second response time %s%s|%s %s\n"), status_line, elapsed_time, timestamp, (display_html ? "" : ""), perfd_time (elapsed_time), perfd_size (pagesize)); exit (STATE_OK); } + else if ((errcode == REG_NOMATCH && invert_regex == 0) || (errcode == 0 && invert_regex == 1)) { + if (invert_regex == 0) + msg = strdup(_("pattern not found")); + else + msg = strdup(_("pattern found")); + printf (_("%s - %s%s|%s %s\n"), + _("CRITICAL"), + msg, + (display_html ? "" : ""), + perfd_time (elapsed_time), perfd_size (pagesize)); + exit (STATE_CRITICAL); + } else { - if (errcode == REG_NOMATCH) { - printf (_("CRITICAL - pattern not found%s|%s %s\n"), - (display_html ? "" : ""), - perfd_time (elapsed_time), perfd_size (pagesize)); - exit (STATE_CRITICAL); - } - else { - regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); - printf (_("CRITICAL - Execute Error: %s\n"), errbuf); - exit (STATE_CRITICAL); - } + regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); + printf (_("CRITICAL - Execute Error: %s\n"), errbuf); + exit (STATE_CRITICAL); } } -#endif /* make sure the page is of an appropriate size */ /* page_len = get_content_length(header); */ @@ -1066,9 +1094,8 @@ redir (char *pos, char *status_line) die (STATE_UNKNOWN, _("Could not allocate url\n")); while (pos) { - - if (sscanf (pos, "%[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]:%n", xx, &i) < 1) { - + sscanf (pos, "%[Ll]%*[Oo]%*[Cc]%*[Aa]%*[Tt]%*[Ii]%*[Oo]%*[Nn]:%n", xx, &i); + if (i == 0) { pos += (size_t) strcspn (pos, "\r\n"); pos += (size_t) strspn (pos, "\r\n"); if (strlen(pos) == 0) @@ -1208,11 +1235,10 @@ print_help (void) printf ("Copyright (c) 1999 Ethan Galstad \n"); printf (COPYRIGHT, copyright, email); - printf (_("\ -This plugin tests the HTTP service on the specified host. It can test\n\ -normal (http) and secure (https) servers, follow redirects, search for\n\ -strings and regular expressions, check connection times, and report on\n\ -certificate expiration times.")); + printf ("%s\n", _("This plugin tests the HTTP service on the specified host. It can test")); + printf ("%s\n", _("normal (http) and secure (https) servers, follow redirects, search for")); + printf ("%s\n", _("strings and regular expressions, check connection times, and report on")); + printf ("%s\n", _("certificate expiration times.")); printf ("\n\n"); @@ -1224,68 +1250,65 @@ certificate expiration times.")); printf (_(UT_HELP_VRSN)); - printf (_("\ - -H, --hostname=ADDRESS\n\ - Host name argument for servers using host headers (virtual host)\n\ - Append a port to include it in the header (eg: example.com:5000)\n\ - -I, --IP-address=ADDRESS\n\ - IP address or name (use numeric address if possible to bypass DNS lookup).\n\ - -p, --port=INTEGER\n\ - Port number (default: %d)\n"), HTTP_PORT); + printf (" %s\n", "-H, --hostname=ADDRESS"); + printf (" %s\n", _("Host name argument for servers using host headers (virtual host)")); + printf (" %s\n", _("Append a port to include it in the header (eg: example.com:5000)")); + printf (" %s\n", "-I, --IP-address=ADDRESS"); + printf (" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup).")); + printf (" %s\n", "-p, --port=INTEGER"); + printf (" %s", _("Port number (default: ")); + printf ("%d)\n", HTTP_PORT); printf (_(UT_IPv46)); #ifdef HAVE_SSL - printf (_("\ - -S, --ssl\n\ - Connect via SSL\n\ - -C, --certificate=INTEGER\n\ - Minimum number of days a certificate has to be valid.\n\ - (when this option is used the url is not checked.)\n")); -#endif - - printf (_("\ - -e, --expect=STRING\n\ - String to expect in first (status) line of server response (default: %s)\n\ - If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)\n\ - -s, --string=STRING\n\ - String to expect in the content\n\ - -u, --url=PATH\n\ - URL to GET or POST (default: /)\n\ - -P, --post=STRING\n\ - URL encoded http POST data\n\ - -N, --no-body\n\ - Don't wait for document body: stop reading after headers.\n\ - (Note that this still does an HTTP GET or POST, not a HEAD.)\n\ - -M, --max-age=SECONDS\n\ - Warn if document is more than SECONDS old. the number can also be of \n\ - the form \"10m\" for minutes, \"10h\" for hours, or \"10d\" for days.\n\ - -T, --content-type=STRING\n\ - specify Content-Type header media type when POSTing\n"), HTTP_EXPECT); - -#ifdef HAVE_REGEX_H - printf (_("\ - -l, --linespan\n\ - Allow regex to span newlines (must precede -r or -R)\n\ - -r, --regex, --ereg=STRING\n\ - Search page for regex STRING\n\ - -R, --eregi=STRING\n\ - Search page for case-insensitive regex STRING\n")); + printf (" %s\n", "-S, --ssl"); + printf (" %s\n", _("Connect via SSL")); + printf (" %s\n", "-C, --certificate=INTEGER"); + printf (" %s\n", _("Minimum number of days a certificate has to be valid.")); + printf (" %s\n", _("(when this option is used the url is not checked.)\n")); #endif - printf (_("\ - -a, --authorization=AUTH_PAIR\n\ - Username:password on sites with basic authentication\n\ - -A, --useragent=STRING\n\ - String to be sent in http header as \"User Agent\"\n\ - -k, --header=STRING\n\ - Any other tags to be sent in http header, separated by semicolon\n\ - -L, --link=URL\n\ - Wrap output in HTML link (obsoleted by urlize)\n\ - -f, --onredirect=\n\ - How to handle redirected pages\n\ - -m, --pagesize=INTEGER<:INTEGER>\n\ - Minimum page size required (bytes) : Maximum page size required (bytes)\n")); + printf (" %s\n", "-e, --expect=STRING"); + printf (" %s\n", _("String to expect in first (status) line of server response (default: ")); + printf ("%s\n", HTTP_EXPECT); + printf (" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)")); + printf (" %s\n", "-s, --string=STRING"); + printf (" %s\n", _("String to expect in the content")); + printf (" %s\n", "-u, --url=PATH"); + printf (" %s\n", _("URL to GET or POST (default: /)")); + printf (" %s\n," "-P, --post=STRING"); + printf (" %s\n", _("URL encoded http POST data")); + printf (" %s\n", "-N, --no-body"); + printf (" %s\n", _("Don't wait for document body: stop reading after headers.")); + printf (" %s\n", _("(Note that this still does an HTTP GET or POST, not a HEAD.)")); + printf (" %s\n", "-M, --max-age=SECONDS"); + printf (" %s\n", _("Warn if document is more than SECONDS old. the number can also be of")); + printf (" %s\n", _("the form \"10m\" for minutes, \"10h\" for hours, or \"10d\" for days.")); + printf (" %s\n", "-T, --content-type=STRING"); + printf (" %s\n", _("specify Content-Type header media type when POSTing\n")); + + printf (" %s\n", "-l, --linespan"); + printf (" %s\n", _("Allow regex to span newlines (must precede -r or -R)")); + printf (" %s\n", "-r, --regex, --ereg=STRING"); + printf (" %s\n", _("Search page for regex STRING")); + printf (" %s\n", "-R, --eregi=STRING"); + printf (" %s\n", _("Search page for case-insensitive regex STRING")); + printf (" %s\n", "--invert-regex"); + printf (" %s\n", _("Return CRITICAL if found, OK if not\n")); + + printf (" %s\n", "-a, --authorization=AUTH_PAIR"); + printf (" %s\n", _("Username:password on sites with basic authentication")); + printf (" %s\n", "-A, --useragent=STRING"); + printf (" %s\n", _("String to be sent in http header as \"User Agent\"")); + printf (" %s\n", "-k, --header=STRING"); + printf (" %s\n", _(" Any other tags to be sent in http header. Use multiple times for additional headers")); + printf (" %s\n", "-L, --link=URL"); + printf (" %s\n", _("Wrap output in HTML link (obsoleted by urlize)")); + printf (" %s\n", "-f, --onredirect="); + printf (" %s\n", _("How to handle redirected pages")); + printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); + printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)")); printf (_(UT_WARN_CRIT)); @@ -1293,32 +1316,30 @@ certificate expiration times.")); printf (_(UT_VERBOSE)); - printf (_("\ -This plugin will attempt to open an HTTP connection with the host. Successful\n\ -connects return STATE_OK, refusals and timeouts return STATE_CRITICAL, other\n\ -errors return STATE_UNKNOWN. Successful connects, but incorrect reponse\n\ -messages from the host result in STATE_WARNING return values. If you are\n\ -checking a virtual server that uses 'host headers' you must supply the FQDN\n\ -(fully qualified domain name) as the [host_name] argument.\n")); + printf (_("Notes:")); + printf (" %s\n", _("This plugin will attempt to open an HTTP connection with the host.")); + printf (" %s\n", _("Successful connects return STATE_OK, refusals and timeouts return STATE_CRITICAL")); + printf (" %s\n", _("other errors return STATE_UNKNOWN. Successful connects, but incorrect reponse")); + printf (" %s\n", _("messages from the host result in STATE_WARNING return values. If you are")); + printf (" %s\n", _("checking a virtual server that uses 'host headers' you must supply the FQDN")); + printf (" %s\n", _("(fully qualified domain name) as the [host_name] argument.")); #ifdef HAVE_SSL - printf (_("\n\ -This plugin can also check whether an SSL enabled web server is able to\n\ -serve content (optionally within a specified time) or whether the X509 \n\ -certificate is still valid for the specified number of days.\n")); - printf (_("\n\ -CHECK CONTENT: check_http -w 5 -c 10 --ssl www.verisign.com\n\n\ -When the 'www.verisign.com' server returns its content within 5 seconds, a\n\ -STATE_OK will be returned. When the server returns its content but exceeds\n\ -the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,\n\ -a STATE_CRITICAL will be returned.\n\n")); - - printf (_("\ -CHECK CERTIFICATE: check_http www.verisign.com -C 14\n\n\ -When the certificate of 'www.verisign.com' is valid for more than 14 days, a\n\ -STATE_OK is returned. When the certificate is still valid, but for less than\n\ -14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when\n\ -the certificate is expired.\n")); + printf (" %s\n", _("This plugin can also check whether an SSL enabled web server is able to")); + printf (" %s\n", _("serve content (optionally within a specified time) or whether the X509 ")); + printf (" %s\n", _("certificate is still valid for the specified number of days.")); + printf (_("Examples:")); + printf (" %s\n\n", "CHECK CONTENT: check_http -w 5 -c 10 --ssl www.verisign.com"); + printf (" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,")); + printf (" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds")); + printf (" %s\n", _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); + printf (" %s\n\n", _("a STATE_CRITICAL will be returned.")); + + printf (" %s\n\n", "CHECK CERTIFICATE: check_http www.verisign.com -C 14"); + printf (" %s\n", _("When the certificate of 'www.verisign.com' is valid for more than 14 days,")); + printf (" %s\n", _("a STATE_OK is returned. When the certificate is still valid, but for less than")); + printf (" %s\n", _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when")); + printf (" %s\n\n", _("the certificate is expired.")); #endif printf (_(UT_SUPPORT));