diff options
| -rw-r--r-- | plugins/check_curl.c | 119 |
1 files changed, 109 insertions, 10 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 3b4f2ed5..a0e6d8f9 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
| @@ -49,9 +49,11 @@ 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 DEFAULT_HTTP_PORT 80 | 52 | enum { |
| 53 | #define DEFAULT_HTTPS_PORT 443 | 53 | HTTP_PORT = 80, |
| 54 | #define MAX_PORT 65535 | 54 | HTTPS_PORT = 443, |
| 55 | MAX_PORT = 65535 | ||
| 56 | }; | ||
| 55 | 57 | ||
| 56 | /* for buffers for header and body */ | 58 | /* for buffers for header and body */ |
| 57 | typedef struct { | 59 | typedef struct { |
| @@ -72,10 +74,22 @@ typedef struct { | |||
| 72 | char *first_line; /* a copy of the first line */ | 74 | char *first_line; /* a copy of the first line */ |
| 73 | } curlhelp_statusline; | 75 | } curlhelp_statusline; |
| 74 | 76 | ||
| 77 | enum { | ||
| 78 | REGS = 2, | ||
| 79 | MAX_RE_SIZE = 256 | ||
| 80 | }; | ||
| 81 | #include "regex.h" | ||
| 82 | regex_t preg; | ||
| 83 | regmatch_t pmatch[REGS]; | ||
| 84 | char regexp[MAX_RE_SIZE]; | ||
| 85 | int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; | ||
| 86 | int errcode; | ||
| 87 | int invert_regex = 0; | ||
| 88 | |||
| 75 | char *server_address; | 89 | char *server_address; |
| 76 | char *host_name; | 90 | char *host_name; |
| 77 | char *server_url = DEFAULT_SERVER_URL; | 91 | char *server_url = DEFAULT_SERVER_URL; |
| 78 | unsigned short server_port = DEFAULT_HTTP_PORT; | 92 | unsigned short server_port = HTTP_PORT; |
| 79 | char output_string_search[30] = ""; | 93 | char output_string_search[30] = ""; |
| 80 | char *warning_thresholds = NULL; | 94 | char *warning_thresholds = NULL; |
| 81 | char *critical_thresholds = NULL; | 95 | char *critical_thresholds = NULL; |
| @@ -341,6 +355,27 @@ main (int argc, char **argv) | |||
| 341 | } | 355 | } |
| 342 | } | 356 | } |
| 343 | 357 | ||
| 358 | if (strlen (regexp)) { | ||
| 359 | errcode = regexec (&preg, body_buf.buf, REGS, pmatch, 0); | ||
| 360 | if ((errcode == 0 && invert_regex == 0) || (errcode == REG_NOMATCH && invert_regex == 1)) { | ||
| 361 | /* OK - No-op to avoid changing the logic around it */ | ||
| 362 | result = max_state_alt(STATE_OK, result); | ||
| 363 | } | ||
| 364 | else if ((errcode == REG_NOMATCH && invert_regex == 0) || (errcode == 0 && invert_regex == 1)) { | ||
| 365 | if (invert_regex == 0) | ||
| 366 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern not found"), msg); | ||
| 367 | else | ||
| 368 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern found"), msg); | ||
| 369 | result = STATE_CRITICAL; | ||
| 370 | } | ||
| 371 | else { | ||
| 372 | /* FIXME: Shouldn't that be UNKNOWN? */ | ||
| 373 | regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); | ||
| 374 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%sExecute Error: %s, "), msg, errbuf); | ||
| 375 | result = STATE_CRITICAL; | ||
| 376 | } | ||
| 377 | } | ||
| 378 | |||
| 344 | /* -w, -c: check warning and critical level */ | 379 | /* -w, -c: check warning and critical level */ |
| 345 | result = max_state_alt(get_status(total_time, thlds), result); | 380 | result = max_state_alt(get_status(total_time, thlds), result); |
| 346 | 381 | ||
| @@ -375,7 +410,8 @@ process_arguments (int argc, char **argv) | |||
| 375 | int c; | 410 | int c; |
| 376 | 411 | ||
| 377 | enum { | 412 | enum { |
| 378 | SNI_OPTION = CHAR_MAX + 1, | 413 | INVERT_REGEX = CHAR_MAX + 1, |
| 414 | SNI_OPTION, | ||
| 379 | CA_CERT_OPTION | 415 | CA_CERT_OPTION |
| 380 | }; | 416 | }; |
| 381 | 417 | ||
| @@ -388,6 +424,7 @@ process_arguments (int argc, char **argv) | |||
| 388 | {"port", required_argument, 0, 'p'}, | 424 | {"port", required_argument, 0, 'p'}, |
| 389 | {"authorization", required_argument, 0, 'a'}, | 425 | {"authorization", required_argument, 0, 'a'}, |
| 390 | {"string", required_argument, 0, 's'}, | 426 | {"string", required_argument, 0, 's'}, |
| 427 | {"regex", required_argument, 0, 'r'}, | ||
| 391 | {"onredirect", required_argument, 0, 'f'}, | 428 | {"onredirect", required_argument, 0, 'f'}, |
| 392 | {"client-cert", required_argument, 0, 'J'}, | 429 | {"client-cert", required_argument, 0, 'J'}, |
| 393 | {"private-key", required_argument, 0, 'K'}, | 430 | {"private-key", required_argument, 0, 'K'}, |
| @@ -401,7 +438,7 @@ process_arguments (int argc, char **argv) | |||
| 401 | usage ("\n"); | 438 | usage ("\n"); |
| 402 | 439 | ||
| 403 | while (1) { | 440 | while (1) { |
| 404 | c = getopt_long (argc, argv, "Vvht:c:w:A:H:I:a:p:s:u:f:C:J:K:S::", longopts, &option); | 441 | c = getopt_long (argc, argv, "Vvht:c:w:A:H:I:a:p:s:r:u:f:C:J:K:S::", longopts, &option); |
| 405 | if (c == -1 || c == EOF || c == 1) | 442 | if (c == -1 || c == EOF || c == 1) |
| 406 | break; | 443 | break; |
| 407 | 444 | ||
| @@ -503,8 +540,8 @@ process_arguments (int argc, char **argv) | |||
| 503 | else | 540 | else |
| 504 | usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)")); | 541 | usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)")); |
| 505 | } | 542 | } |
| 506 | if (server_port == DEFAULT_HTTP_PORT) | 543 | if (server_port == HTTP_PORT) |
| 507 | server_port = DEFAULT_HTTPS_PORT; | 544 | server_port = HTTPS_PORT; |
| 508 | #else | 545 | #else |
| 509 | /* -C -J and -K fall through to here without SSL */ | 546 | /* -C -J and -K fall through to here without SSL */ |
| 510 | usage4 (_("Invalid option - SSL is not available")); | 547 | usage4 (_("Invalid option - SSL is not available")); |
| @@ -532,6 +569,19 @@ process_arguments (int argc, char **argv) | |||
| 532 | strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); | 569 | strncpy (string_expect, optarg, MAX_INPUT_BUFFER - 1); |
| 533 | string_expect[MAX_INPUT_BUFFER - 1] = 0; | 570 | string_expect[MAX_INPUT_BUFFER - 1] = 0; |
| 534 | break; | 571 | break; |
| 572 | case 'r': /* regex */ | ||
| 573 | strncpy (regexp, optarg, MAX_RE_SIZE - 1); | ||
| 574 | regexp[MAX_RE_SIZE - 1] = 0; | ||
| 575 | errcode = regcomp (&preg, regexp, cflags); | ||
| 576 | if (errcode != 0) { | ||
| 577 | (void) regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); | ||
| 578 | printf (_("Could Not Compile Regular Expression: %s"), errbuf); | ||
| 579 | return ERROR; | ||
| 580 | } | ||
| 581 | break; | ||
| 582 | case INVERT_REGEX: | ||
| 583 | invert_regex = 1; | ||
| 584 | break; | ||
| 535 | case '?': | 585 | case '?': |
| 536 | /* print short usage statement if args not parsable */ | 586 | /* print short usage statement if args not parsable */ |
| 537 | usage5 (); | 587 | usage5 (); |
| @@ -608,7 +658,7 @@ print_help (void) | |||
| 608 | printf (" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup).")); | 658 | printf (" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup).")); |
| 609 | printf (" %s\n", "-p, --port=INTEGER"); | 659 | printf (" %s\n", "-p, --port=INTEGER"); |
| 610 | printf (" %s", _("Port number (default: ")); | 660 | printf (" %s", _("Port number (default: ")); |
| 611 | printf ("%d)\n", DEFAULT_HTTP_PORT); | 661 | printf ("%d)\n", HTTP_PORT); |
| 612 | 662 | ||
| 613 | #ifdef LIBCURL_FEATURE_SSL | 663 | #ifdef LIBCURL_FEATURE_SSL |
| 614 | printf (" %s\n", "-S, --ssl=VERSION[+]"); | 664 | printf (" %s\n", "-S, --ssl=VERSION[+]"); |
| @@ -640,7 +690,8 @@ print_help (void) | |||
| 640 | printf (" %s\n", _("String to expect in the content")); | 690 | printf (" %s\n", _("String to expect in the content")); |
| 641 | printf (" %s\n", "-u, --url=PATH"); | 691 | printf (" %s\n", "-u, --url=PATH"); |
| 642 | printf (" %s\n", _("URL to GET or POST (default: /)")); | 692 | printf (" %s\n", _("URL to GET or POST (default: /)")); |
| 643 | 693 | printf (" %s\n", "-r, --regex, --ereg=STRING"); | |
| 694 | printf (" %s\n", _("Search page for regex STRING")); | ||
| 644 | printf (" %s\n", "-a, --authorization=AUTH_PAIR"); | 695 | printf (" %s\n", "-a, --authorization=AUTH_PAIR"); |
| 645 | printf (" %s\n", _("Username:password on sites with basic authentication")); | 696 | printf (" %s\n", _("Username:password on sites with basic authentication")); |
| 646 | printf (" %s\n", "-A, --useragent=STRING"); | 697 | printf (" %s\n", "-A, --useragent=STRING"); |
| @@ -654,6 +705,53 @@ print_help (void) | |||
| 654 | 705 | ||
| 655 | printf (UT_VERBOSE); | 706 | printf (UT_VERBOSE); |
| 656 | 707 | ||
| 708 | printf ("\n"); | ||
| 709 | printf ("%s\n", _("Notes:")); | ||
| 710 | printf (" %s\n", _("This plugin will attempt to open an HTTP connection with the host.")); | ||
| 711 | printf (" %s\n", _("Successful connects return STATE_OK, refusals and timeouts return STATE_CRITICAL")); | ||
| 712 | printf (" %s\n", _("other errors return STATE_UNKNOWN. Successful connects, but incorrect response")); | ||
| 713 | printf (" %s\n", _("messages from the host result in STATE_WARNING return values. If you are")); | ||
| 714 | printf (" %s\n", _("checking a virtual server that uses 'host headers' you must supply the FQDN")); | ||
| 715 | printf (" %s\n", _("(fully qualified domain name) as the [host_name] argument.")); | ||
| 716 | |||
| 717 | #ifdef LIBCURL_FEATURE_SSL | ||
| 718 | printf ("\n"); | ||
| 719 | printf (" %s\n", _("This plugin can also check whether an SSL enabled web server is able to")); | ||
| 720 | printf (" %s\n", _("serve content (optionally within a specified time) or whether the X509 ")); | ||
| 721 | printf (" %s\n", _("certificate is still valid for the specified number of days.")); | ||
| 722 | printf ("\n"); | ||
| 723 | printf (" %s\n", _("Please note that this plugin does not check if the presented server")); | ||
| 724 | printf (" %s\n", _("certificate matches the hostname of the server, or if the certificate")); | ||
| 725 | printf (" %s\n", _("has a valid chain of trust to one of the locally installed CAs.")); | ||
| 726 | printf ("\n"); | ||
| 727 | printf ("%s\n", _("Examples:")); | ||
| 728 | printf (" %s\n\n", "CHECK CONTENT: check_http -w 5 -c 10 --ssl -H www.verisign.com"); | ||
| 729 | printf (" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,")); | ||
| 730 | printf (" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds")); | ||
| 731 | printf (" %s\n", _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); | ||
| 732 | printf (" %s\n", _("a STATE_CRITICAL will be returned.")); | ||
| 733 | printf ("\n"); | ||
| 734 | printf (" %s\n\n", "CHECK CERTIFICATE: check_http -H www.verisign.com -C 14"); | ||
| 735 | printf (" %s\n", _("When the certificate of 'www.verisign.com' is valid for more than 14 days,")); | ||
| 736 | printf (" %s\n", _("a STATE_OK is returned. When the certificate is still valid, but for less than")); | ||
| 737 | printf (" %s\n", _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when")); | ||
| 738 | printf (" %s\n\n", _("the certificate is expired.")); | ||
| 739 | printf ("\n"); | ||
| 740 | printf (" %s\n\n", "CHECK CERTIFICATE: check_http -H www.verisign.com -C 30,14"); | ||
| 741 | printf (" %s\n", _("When the certificate of 'www.verisign.com' is valid for more than 30 days,")); | ||
| 742 | printf (" %s\n", _("a STATE_OK is returned. When the certificate is still valid, but for less than")); | ||
| 743 | printf (" %s\n", _("30 days, but more than 14 days, a STATE_WARNING is returned.")); | ||
| 744 | printf (" %s\n", _("A STATE_CRITICAL will be returned when certificate expires in less than 14 days")); | ||
| 745 | |||
| 746 | printf (" %s\n\n", "CHECK SSL WEBSERVER CONTENT VIA PROXY USING HTTP 1.1 CONNECT: "); | ||
| 747 | printf (" %s\n", _("check_http -I 192.168.100.35 -p 80 -u https://www.verisign.com/ -S -j CONNECT -H www.verisign.com ")); | ||
| 748 | printf (" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> -S(sl) -j CONNECT -H <webserver>")); | ||
| 749 | printf (" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds")); | ||
| 750 | printf (" %s\n", _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); | ||
| 751 | printf (" %s\n", _("a STATE_CRITICAL will be returned.")); | ||
| 752 | |||
| 753 | #endif | ||
| 754 | |||
| 657 | printf (UT_SUPPORT); | 755 | printf (UT_SUPPORT); |
| 658 | } | 756 | } |
| 659 | 757 | ||
| @@ -665,6 +763,7 @@ print_usage (void) | |||
| 665 | printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>]\n"); | 763 | printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>]\n"); |
| 666 | printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-a auth]\n"); | 764 | printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-a auth]\n"); |
| 667 | printf (" [-f <ok|warning|critcal|follow>]\n"); | 765 | printf (" [-f <ok|warning|critcal|follow>]\n"); |
| 766 | printf (" [-s string] [-r <regex>\n"); | ||
| 668 | printf (" [-A string] [-S <version>] [-C]\n"); | 767 | printf (" [-A string] [-S <version>] [-C]\n"); |
| 669 | printf (" [-v verbose]\n", progname); | 768 | printf (" [-v verbose]\n", progname); |
| 670 | printf ("\n"); | 769 | printf ("\n"); |
