diff options
Diffstat (limited to 'plugins')
| -rw-r--r-- | plugins/check_curl.c | 97 |
1 files changed, 75 insertions, 22 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index ccbc6a8b..57b6e124 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
| @@ -49,6 +49,7 @@ const char *email = "devel@monitoring-plugins.org"; | |||
| 49 | 49 | ||
| 50 | #define DEFAULT_BUFFER_SIZE 2048 | 50 | #define DEFAULT_BUFFER_SIZE 2048 |
| 51 | #define DEFAULT_SERVER_URL "/" | 51 | #define DEFAULT_SERVER_URL "/" |
| 52 | #define HTTP_EXPECT "HTTP/1." | ||
| 52 | enum { | 53 | enum { |
| 53 | HTTP_PORT = 80, | 54 | HTTP_PORT = 80, |
| 54 | HTTPS_PORT = 443, | 55 | HTTPS_PORT = 443, |
| @@ -122,6 +123,8 @@ char url[DEFAULT_BUFFER_SIZE]; | |||
| 122 | char msg[DEFAULT_BUFFER_SIZE]; | 123 | char msg[DEFAULT_BUFFER_SIZE]; |
| 123 | char perfstring[DEFAULT_BUFFER_SIZE]; | 124 | char perfstring[DEFAULT_BUFFER_SIZE]; |
| 124 | char string_expect[MAX_INPUT_BUFFER] = ""; | 125 | char string_expect[MAX_INPUT_BUFFER] = ""; |
| 126 | char server_expect[MAX_INPUT_BUFFER] = HTTP_EXPECT; | ||
| 127 | int server_expect_yn = 0; | ||
| 125 | char user_auth[MAX_INPUT_BUFFER] = ""; | 128 | char user_auth[MAX_INPUT_BUFFER] = ""; |
| 126 | int onredirect = STATE_OK; | 129 | int onredirect = STATE_OK; |
| 127 | int use_ssl = FALSE; | 130 | int use_ssl = FALSE; |
| @@ -188,6 +191,26 @@ CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) | |||
| 188 | return CURLE_OK; | 191 | return CURLE_OK; |
| 189 | } | 192 | } |
| 190 | 193 | ||
| 194 | /* Checks if the server 'reply' is one of the expected 'statuscodes' */ | ||
| 195 | static int | ||
| 196 | expected_statuscode (const char *reply, const char *statuscodes) | ||
| 197 | { | ||
| 198 | char *expected, *code; | ||
| 199 | int result = 0; | ||
| 200 | |||
| 201 | if ((expected = strdup (statuscodes)) == NULL) | ||
| 202 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Memory allocation error\n")); | ||
| 203 | |||
| 204 | for (code = strtok (expected, ","); code != NULL; code = strtok (NULL, ",")) | ||
| 205 | if (strstr (reply, code) != NULL) { | ||
| 206 | result = 1; | ||
| 207 | break; | ||
| 208 | } | ||
| 209 | |||
| 210 | free (expected); | ||
| 211 | return result; | ||
| 212 | } | ||
| 213 | |||
| 191 | int | 214 | int |
| 192 | check_http (void) | 215 | check_http (void) |
| 193 | { | 216 | { |
| @@ -416,28 +439,47 @@ check_http (void) | |||
| 416 | (no_body ? " [[ skipped ]]" : body_buf.buf)); | 439 | (no_body ? " [[ skipped ]]" : body_buf.buf)); |
| 417 | } | 440 | } |
| 418 | 441 | ||
| 419 | /* illegal return codes result in a critical state */ | 442 | /* make sure the status line matches the response we are looking for */ |
| 420 | if (code >= 600 || code < 100) { | 443 | if (!expected_statuscode(header_buf.buf, server_expect)) { |
| 421 | die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%d, %.40s)\n"), status_line.http_code, status_line.msg); | 444 | /* TODO: fix first_line being cut off */ |
| 422 | /* server errors result in a critical state */ | 445 | if (server_port == HTTP_PORT) |
| 423 | } else if (code >= 500) { | 446 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host: %s\n"), status_line.first_line); |
| 424 | result = STATE_CRITICAL; | 447 | else |
| 425 | /* client errors result in a warning state */ | 448 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: %s\n"), server_port, status_line.first_line); |
| 426 | } else if (code >= 400) { | 449 | die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg); |
| 427 | result = STATE_WARNING; | 450 | } |
| 428 | /* check redirected page if specified */ | 451 | |
| 429 | } else if (code >= 300) { | 452 | /* TODO: implement -d header tests */ |
| 430 | if (onredirect == STATE_DEPENDENT) { | 453 | if( server_expect_yn ) { |
| 431 | code = status_line.http_code; | 454 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Status line output matched \"%s\" - "), server_expect); |
| 432 | } | 455 | if (verbose) |
| 433 | result = max_state_alt (onredirect, result); | 456 | printf ("%s\n",msg); |
| 434 | /* TODO: make sure the last status line has been | ||
| 435 | parsed into the status_line structure | ||
| 436 | */ | ||
| 437 | /* all other codes are considered ok */ | ||
| 438 | } else { | ||
| 439 | result = STATE_OK; | 457 | result = STATE_OK; |
| 440 | } | 458 | } |
| 459 | else { | ||
| 460 | /* illegal return codes result in a critical state */ | ||
| 461 | if (code >= 600 || code < 100) { | ||
| 462 | die (STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%d, %.40s)\n"), status_line.http_code, status_line.msg); | ||
| 463 | /* server errors result in a critical state */ | ||
| 464 | } else if (code >= 500) { | ||
| 465 | result = STATE_CRITICAL; | ||
| 466 | /* client errors result in a warning state */ | ||
| 467 | } else if (code >= 400) { | ||
| 468 | result = STATE_WARNING; | ||
| 469 | /* check redirected page if specified */ | ||
| 470 | } else if (code >= 300) { | ||
| 471 | if (onredirect == STATE_DEPENDENT) { | ||
| 472 | code = status_line.http_code; | ||
| 473 | } | ||
| 474 | result = max_state_alt (onredirect, result); | ||
| 475 | /* TODO: make sure the last status line has been | ||
| 476 | parsed into the status_line structure | ||
| 477 | */ | ||
| 478 | /* all other codes are considered ok */ | ||
| 479 | } else { | ||
| 480 | result = STATE_OK; | ||
| 481 | } | ||
| 482 | } | ||
| 441 | 483 | ||
| 442 | /* check status codes, set exit status accordingly */ | 484 | /* check status codes, set exit status accordingly */ |
| 443 | if( status_line.http_code != code ) { | 485 | if( status_line.http_code != code ) { |
| @@ -551,6 +593,7 @@ process_arguments (int argc, char **argv) | |||
| 551 | {"port", required_argument, 0, 'p'}, | 593 | {"port", required_argument, 0, 'p'}, |
| 552 | {"authorization", required_argument, 0, 'a'}, | 594 | {"authorization", required_argument, 0, 'a'}, |
| 553 | {"string", required_argument, 0, 's'}, | 595 | {"string", required_argument, 0, 's'}, |
| 596 | {"expect", required_argument, 0, 'e'}, | ||
| 554 | {"regex", required_argument, 0, 'r'}, | 597 | {"regex", required_argument, 0, 'r'}, |
| 555 | {"ereg", required_argument, 0, 'r'}, | 598 | {"ereg", required_argument, 0, 'r'}, |
| 556 | {"eregi", required_argument, 0, 'R'}, | 599 | {"eregi", required_argument, 0, 'R'}, |
| @@ -588,7 +631,7 @@ process_arguments (int argc, char **argv) | |||
| 588 | } | 631 | } |
| 589 | 632 | ||
| 590 | while (1) { | 633 | while (1) { |
| 591 | c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:j:I:a:p:s:R:r:u:f:C:J:K:S::m:NE", longopts, &option); | 634 | c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:j:I:a:p:e:s:R:r:u:f:C:J:K:S::m:NE", longopts, &option); |
| 592 | if (c == -1 || c == EOF || c == 1) | 635 | if (c == -1 || c == EOF || c == 1) |
| 593 | break; | 636 | break; |
| 594 | 637 | ||
| @@ -758,6 +801,11 @@ process_arguments (int argc, char **argv) | |||
| 758 | strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); | 801 | strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); |
| 759 | string_expect[MAX_INPUT_BUFFER - 1] = 0; | 802 | string_expect[MAX_INPUT_BUFFER - 1] = 0; |
| 760 | break; | 803 | break; |
| 804 | case 'e': /* string or substring */ | ||
| 805 | strncpy (server_expect, optarg, MAX_INPUT_BUFFER - 1); | ||
| 806 | server_expect[MAX_INPUT_BUFFER - 1] = 0; | ||
| 807 | server_expect_yn = 1; | ||
| 808 | break; | ||
| 761 | case 'R': /* regex */ | 809 | case 'R': /* regex */ |
| 762 | cflags |= REG_ICASE; | 810 | cflags |= REG_ICASE; |
| 763 | case 'r': /* regex */ | 811 | case 'r': /* regex */ |
| @@ -917,6 +965,11 @@ print_help (void) | |||
| 917 | printf (" %s\n", _("CA certificate file to verify peer against")); | 965 | printf (" %s\n", _("CA certificate file to verify peer against")); |
| 918 | #endif | 966 | #endif |
| 919 | 967 | ||
| 968 | printf (" %s\n", "-e, --expect=STRING"); | ||
| 969 | printf (" %s\n", _("Comma-delimited list of strings, at least one of them is expected in")); | ||
| 970 | printf (" %s", _("the first (status) line of the server response (default: ")); | ||
| 971 | printf ("%s)\n", HTTP_EXPECT); | ||
| 972 | printf (" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)")); | ||
| 920 | printf (" %s\n", "-s, --string=STRING"); | 973 | printf (" %s\n", "-s, --string=STRING"); |
| 921 | printf (" %s\n", _("String to expect in the content")); | 974 | printf (" %s\n", _("String to expect in the content")); |
| 922 | printf (" %s\n", "-u, --url=PATH"); | 975 | printf (" %s\n", "-u, --url=PATH"); |
| @@ -1012,7 +1065,7 @@ print_usage (void) | |||
| 1012 | printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>]\n"); | 1065 | printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>]\n"); |
| 1013 | printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-E] [-a auth]\n"); | 1066 | printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-E] [-a auth]\n"); |
| 1014 | printf (" [-f <ok|warning|critcal|follow>]\n"); | 1067 | printf (" [-f <ok|warning|critcal|follow>]\n"); |
| 1015 | printf (" [-s string] [-r <regex> | -R <case-insensitive regex>]\n"); | 1068 | printf (" [-e <expect>] [-s string] [-r <regex> | -R <case-insensitive regex>]\n"); |
| 1016 | printf (" [-m <min_pg_size>:<max_pg_size>] [-N]\n"); | 1069 | printf (" [-m <min_pg_size>:<max_pg_size>] [-N]\n"); |
| 1017 | printf (" [-4|-6] [-N]\n"); | 1070 | printf (" [-4|-6] [-N]\n"); |
| 1018 | printf (" [-A string] [-k string] [-S <version>] [-C]\n"); | 1071 | printf (" [-A string] [-k string] [-S <version>] [-C]\n"); |
