diff options
Diffstat (limited to 'plugins/check_curl.c')
-rw-r--r-- | plugins/check_curl.c | 320 |
1 files changed, 228 insertions, 92 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index c37d45d..d0871c4 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
@@ -55,6 +55,7 @@ const char *email = "devel@monitoring-plugins.org"; | |||
55 | #include "uriparser/Uri.h" | 55 | #include "uriparser/Uri.h" |
56 | 56 | ||
57 | #include <arpa/inet.h> | 57 | #include <arpa/inet.h> |
58 | #include <netinet/in.h> | ||
58 | 59 | ||
59 | #if defined(HAVE_SSL) && defined(USE_OPENSSL) | 60 | #if defined(HAVE_SSL) && defined(USE_OPENSSL) |
60 | #include <openssl/opensslv.h> | 61 | #include <openssl/opensslv.h> |
@@ -243,7 +244,7 @@ void curlhelp_freewritebuffer (curlhelp_write_curlbuf*); | |||
243 | int curlhelp_initreadbuffer (curlhelp_read_curlbuf *, const char *, size_t); | 244 | int curlhelp_initreadbuffer (curlhelp_read_curlbuf *, const char *, size_t); |
244 | int curlhelp_buffer_read_callback (void *, size_t , size_t , void *); | 245 | int curlhelp_buffer_read_callback (void *, size_t , size_t , void *); |
245 | void curlhelp_freereadbuffer (curlhelp_read_curlbuf *); | 246 | void curlhelp_freereadbuffer (curlhelp_read_curlbuf *); |
246 | curlhelp_ssl_library curlhelp_get_ssl_library (CURL*); | 247 | curlhelp_ssl_library curlhelp_get_ssl_library (); |
247 | const char* curlhelp_get_ssl_library_string (curlhelp_ssl_library); | 248 | const char* curlhelp_get_ssl_library_string (curlhelp_ssl_library); |
248 | int net_noopenssl_check_certificate (cert_ptr_union*, int, int); | 249 | int net_noopenssl_check_certificate (cert_ptr_union*, int, int); |
249 | 250 | ||
@@ -296,6 +297,7 @@ main (int argc, char **argv) | |||
296 | 297 | ||
297 | int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) | 298 | int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) |
298 | { | 299 | { |
300 | (void) preverify_ok; | ||
299 | /* TODO: we get all certificates of the chain, so which ones | 301 | /* TODO: we get all certificates of the chain, so which ones |
300 | * should we test? | 302 | * should we test? |
301 | * TODO: is the last certificate always the server certificate? | 303 | * TODO: is the last certificate always the server certificate? |
@@ -320,6 +322,8 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) | |||
320 | 322 | ||
321 | CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) | 323 | CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) |
322 | { | 324 | { |
325 | (void) curl; // ignore unused parameter | ||
326 | (void) parm; // ignore unused parameter | ||
323 | SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, verify_callback); | 327 | SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, verify_callback); |
324 | 328 | ||
325 | return CURLE_OK; | 329 | return CURLE_OK; |
@@ -374,8 +378,12 @@ void | |||
374 | handle_curl_option_return_code (CURLcode res, const char* option) | 378 | handle_curl_option_return_code (CURLcode res, const char* option) |
375 | { | 379 | { |
376 | if (res != CURLE_OK) { | 380 | if (res != CURLE_OK) { |
377 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Error while setting cURL option '%s': cURL returned %d - %s"), | 381 | snprintf (msg, |
378 | option, res, curl_easy_strerror(res)); | 382 | DEFAULT_BUFFER_SIZE, |
383 | _("Error while setting cURL option '%s': cURL returned %d - %s"), | ||
384 | option, | ||
385 | res, | ||
386 | curl_easy_strerror(res)); | ||
379 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 387 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); |
380 | } | 388 | } |
381 | } | 389 | } |
@@ -384,8 +392,11 @@ int | |||
384 | lookup_host (const char *host, char *buf, size_t buflen) | 392 | lookup_host (const char *host, char *buf, size_t buflen) |
385 | { | 393 | { |
386 | struct addrinfo hints, *res, *result; | 394 | struct addrinfo hints, *res, *result; |
395 | char addrstr[100]; | ||
396 | size_t addrstr_len; | ||
387 | int errcode; | 397 | int errcode; |
388 | void *ptr; | 398 | void *ptr; |
399 | size_t buflen_remaining = buflen - 1; | ||
389 | 400 | ||
390 | memset (&hints, 0, sizeof (hints)); | 401 | memset (&hints, 0, sizeof (hints)); |
391 | hints.ai_family = address_family; | 402 | hints.ai_family = address_family; |
@@ -395,26 +406,40 @@ lookup_host (const char *host, char *buf, size_t buflen) | |||
395 | errcode = getaddrinfo (host, NULL, &hints, &result); | 406 | errcode = getaddrinfo (host, NULL, &hints, &result); |
396 | if (errcode != 0) | 407 | if (errcode != 0) |
397 | return errcode; | 408 | return errcode; |
398 | 409 | ||
410 | strcpy(buf, ""); | ||
399 | res = result; | 411 | res = result; |
400 | 412 | ||
401 | while (res) { | 413 | while (res) { |
402 | inet_ntop (res->ai_family, res->ai_addr->sa_data, buf, buflen); | 414 | switch (res->ai_family) { |
403 | switch (res->ai_family) { | 415 | case AF_INET: |
404 | case AF_INET: | 416 | ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; |
405 | ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; | 417 | break; |
406 | break; | 418 | case AF_INET6: |
407 | case AF_INET6: | 419 | ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; |
408 | ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; | 420 | break; |
409 | break; | ||
410 | } | 421 | } |
411 | inet_ntop (res->ai_family, ptr, buf, buflen); | 422 | |
412 | if (verbose >= 1) | 423 | inet_ntop (res->ai_family, ptr, addrstr, 100); |
424 | if (verbose >= 1) { | ||
413 | printf ("* getaddrinfo IPv%d address: %s\n", | 425 | printf ("* getaddrinfo IPv%d address: %s\n", |
414 | res->ai_family == PF_INET6 ? 6 : 4, buf); | 426 | res->ai_family == PF_INET6 ? 6 : 4, addrstr); |
427 | } | ||
428 | |||
429 | // Append all IPs to buf as a comma-separated string | ||
430 | addrstr_len = strlen(addrstr); | ||
431 | if (buflen_remaining > addrstr_len + 1) { | ||
432 | if (buf[0] != '\0') { | ||
433 | strncat(buf, ",", buflen_remaining); | ||
434 | buflen_remaining -= 1; | ||
435 | } | ||
436 | strncat(buf, addrstr, buflen_remaining); | ||
437 | buflen_remaining -= addrstr_len; | ||
438 | } | ||
439 | |||
415 | res = res->ai_next; | 440 | res = res->ai_next; |
416 | } | 441 | } |
417 | 442 | ||
418 | freeaddrinfo(result); | 443 | freeaddrinfo(result); |
419 | 444 | ||
420 | return 0; | 445 | return 0; |
@@ -445,7 +470,7 @@ check_http (void) | |||
445 | int i; | 470 | int i; |
446 | char *force_host_header = NULL; | 471 | char *force_host_header = NULL; |
447 | struct curl_slist *host = NULL; | 472 | struct curl_slist *host = NULL; |
448 | char addrstr[100]; | 473 | char addrstr[DEFAULT_BUFFER_SIZE/2]; |
449 | char dnscache[DEFAULT_BUFFER_SIZE]; | 474 | char dnscache[DEFAULT_BUFFER_SIZE]; |
450 | 475 | ||
451 | /* initialize curl */ | 476 | /* initialize curl */ |
@@ -497,10 +522,14 @@ check_http (void) | |||
497 | 522 | ||
498 | // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy | 523 | // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy |
499 | if(use_ssl && host_name != NULL) { | 524 | if(use_ssl && host_name != NULL) { |
500 | if ( (res=lookup_host (server_address, addrstr, 100)) != 0) { | 525 | if ( (res=lookup_host (server_address, addrstr, DEFAULT_BUFFER_SIZE/2)) != 0) { |
501 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), | 526 | snprintf (msg, |
502 | server_address, res, gai_strerror (res)); | 527 | DEFAULT_BUFFER_SIZE, |
503 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 528 | _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), |
529 | server_address, | ||
530 | res, | ||
531 | gai_strerror (res)); | ||
532 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | ||
504 | } | 533 | } |
505 | snprintf (dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, addrstr); | 534 | snprintf (dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, addrstr); |
506 | host = curl_slist_append(NULL, dnscache); | 535 | host = curl_slist_append(NULL, dnscache); |
@@ -524,7 +553,7 @@ check_http (void) | |||
524 | /* compose URL: use the address we want to connect to, set Host: header later */ | 553 | /* compose URL: use the address we want to connect to, set Host: header later */ |
525 | snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", | 554 | snprintf (url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", |
526 | use_ssl ? "https" : "http", | 555 | use_ssl ? "https" : "http", |
527 | use_ssl & host_name != NULL ? host_name : server_address, | 556 | ( use_ssl & ( host_name != NULL ) ) ? host_name : server_address, |
528 | server_port, | 557 | server_port, |
529 | server_url | 558 | server_url |
530 | ); | 559 | ); |
@@ -600,7 +629,7 @@ check_http (void) | |||
600 | 629 | ||
601 | #ifdef LIBCURL_FEATURE_SSL | 630 | #ifdef LIBCURL_FEATURE_SSL |
602 | 631 | ||
603 | /* set SSL version, warn about unsecure or unsupported versions */ | 632 | /* set SSL version, warn about insecure or unsupported versions */ |
604 | if (use_ssl) { | 633 | if (use_ssl) { |
605 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_SSLVERSION, ssl_version), "CURLOPT_SSLVERSION"); | 634 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_SSLVERSION, ssl_version), "CURLOPT_SSLVERSION"); |
606 | } | 635 | } |
@@ -628,7 +657,7 @@ check_http (void) | |||
628 | } | 657 | } |
629 | 658 | ||
630 | /* detect SSL library used by libcurl */ | 659 | /* detect SSL library used by libcurl */ |
631 | ssl_library = curlhelp_get_ssl_library (curl); | 660 | ssl_library = curlhelp_get_ssl_library (); |
632 | 661 | ||
633 | /* try hard to get a stack of certificates to verify against */ | 662 | /* try hard to get a stack of certificates to verify against */ |
634 | if (check_cert) { | 663 | if (check_cert) { |
@@ -792,12 +821,19 @@ check_http (void) | |||
792 | /* free header and server IP resolve lists, we don't need it anymore */ | 821 | /* free header and server IP resolve lists, we don't need it anymore */ |
793 | curl_slist_free_all (header_list); header_list = NULL; | 822 | curl_slist_free_all (header_list); header_list = NULL; |
794 | curl_slist_free_all (server_ips); server_ips = NULL; | 823 | curl_slist_free_all (server_ips); server_ips = NULL; |
824 | if (host) { | ||
825 | curl_slist_free_all (host); host = NULL; | ||
826 | } | ||
795 | 827 | ||
796 | /* Curl errors, result in critical Nagios state */ | 828 | /* Curl errors, result in critical Nagios state */ |
797 | if (res != CURLE_OK) { | 829 | if (res != CURLE_OK) { |
798 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: cURL returned %d - %s"), | 830 | snprintf (msg, |
799 | server_port, res, errbuf[0] ? errbuf : curl_easy_strerror(res)); | 831 | DEFAULT_BUFFER_SIZE, |
800 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 832 | _("Invalid HTTP response received from host on port %d: cURL returned %d - %s"), |
833 | server_port, | ||
834 | res, | ||
835 | errbuf[0] ? errbuf : curl_easy_strerror(res)); | ||
836 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | ||
801 | } | 837 | } |
802 | 838 | ||
803 | /* certificate checks */ | 839 | /* certificate checks */ |
@@ -840,15 +876,19 @@ check_http (void) | |||
840 | } | 876 | } |
841 | GOT_FIRST_CERT: | 877 | GOT_FIRST_CERT: |
842 | if (!raw_cert) { | 878 | if (!raw_cert) { |
843 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Cannot retrieve certificates from CERTINFO information - certificate data was empty")); | 879 | snprintf (msg, |
844 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 880 | DEFAULT_BUFFER_SIZE, |
881 | _("Cannot retrieve certificates from CERTINFO information - certificate data was empty")); | ||
882 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | ||
845 | } | 883 | } |
846 | BIO* cert_BIO = BIO_new (BIO_s_mem()); | 884 | BIO* cert_BIO = BIO_new (BIO_s_mem()); |
847 | BIO_write (cert_BIO, raw_cert, strlen(raw_cert)); | 885 | BIO_write (cert_BIO, raw_cert, strlen(raw_cert)); |
848 | cert = PEM_read_bio_X509 (cert_BIO, NULL, NULL, NULL); | 886 | cert = PEM_read_bio_X509 (cert_BIO, NULL, NULL, NULL); |
849 | if (!cert) { | 887 | if (!cert) { |
850 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Cannot read certificate from CERTINFO information - BIO error")); | 888 | snprintf (msg, |
851 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 889 | DEFAULT_BUFFER_SIZE, |
890 | _("Cannot read certificate from CERTINFO information - BIO error")); | ||
891 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | ||
852 | } | 892 | } |
853 | BIO_free (cert_BIO); | 893 | BIO_free (cert_BIO); |
854 | result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); | 894 | result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); |
@@ -865,9 +905,12 @@ GOT_FIRST_CERT: | |||
865 | } | 905 | } |
866 | #endif /* USE_OPENSSL */ | 906 | #endif /* USE_OPENSSL */ |
867 | } else { | 907 | } else { |
868 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("Cannot retrieve certificates - cURL returned %d - %s"), | 908 | snprintf (msg, |
869 | res, curl_easy_strerror(res)); | 909 | DEFAULT_BUFFER_SIZE, |
870 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 910 | _("Cannot retrieve certificates - cURL returned %d - %s"), |
911 | res, | ||
912 | curl_easy_strerror(res)); | ||
913 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | ||
871 | } | 914 | } |
872 | } | 915 | } |
873 | } | 916 | } |
@@ -906,8 +949,11 @@ GOT_FIRST_CERT: | |||
906 | 949 | ||
907 | /* get status line of answer, check sanity of HTTP code */ | 950 | /* get status line of answer, check sanity of HTTP code */ |
908 | if (curlhelp_parse_statusline (header_buf.buf, &status_line) < 0) { | 951 | if (curlhelp_parse_statusline (header_buf.buf, &status_line) < 0) { |
909 | snprintf (msg, DEFAULT_BUFFER_SIZE, "Unparsable status line in %.3g seconds response time|%s\n", | 952 | snprintf (msg, |
910 | total_time, perfstring); | 953 | DEFAULT_BUFFER_SIZE, |
954 | "Unparsable status line in %.3g seconds response time|%s\n", | ||
955 | total_time, | ||
956 | perfstring); | ||
911 | /* we cannot know the major/minor version here for sure as we cannot parse the first line */ | 957 | /* we cannot know the major/minor version here for sure as we cannot parse the first line */ |
912 | die (STATE_CRITICAL, "HTTP CRITICAL HTTP/x.x %ld unknown - %s", code, msg); | 958 | die (STATE_CRITICAL, "HTTP CRITICAL HTTP/x.x %ld unknown - %s", code, msg); |
913 | } | 959 | } |
@@ -927,9 +973,16 @@ GOT_FIRST_CERT: | |||
927 | /* make sure the status line matches the response we are looking for */ | 973 | /* make sure the status line matches the response we are looking for */ |
928 | if (!expected_statuscode(status_line.first_line, server_expect)) { | 974 | if (!expected_statuscode(status_line.first_line, server_expect)) { |
929 | if (server_port == HTTP_PORT) | 975 | if (server_port == HTTP_PORT) |
930 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host: %s\n"), status_line.first_line); | 976 | snprintf(msg, |
977 | DEFAULT_BUFFER_SIZE, | ||
978 | _("Invalid HTTP response received from host: %s\n"), | ||
979 | status_line.first_line); | ||
931 | else | 980 | else |
932 | snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: %s\n"), server_port, status_line.first_line); | 981 | snprintf(msg, |
982 | DEFAULT_BUFFER_SIZE, | ||
983 | _("Invalid HTTP response received from host on port %d: %s\n"), | ||
984 | server_port, | ||
985 | status_line.first_line); | ||
933 | die (STATE_CRITICAL, "HTTP CRITICAL - %s%s%s", msg, | 986 | die (STATE_CRITICAL, "HTTP CRITICAL - %s%s%s", msg, |
934 | show_body ? "\n" : "", | 987 | show_body ? "\n" : "", |
935 | show_body ? body_buf.buf : ""); | 988 | show_body ? body_buf.buf : ""); |
@@ -965,7 +1018,7 @@ GOT_FIRST_CERT: | |||
965 | } | 1018 | } |
966 | } else { | 1019 | } else { |
967 | /* this is a specific code in the command line to | 1020 | /* this is a specific code in the command line to |
968 | * be returned when a redirection is encoutered | 1021 | * be returned when a redirection is encountered |
969 | */ | 1022 | */ |
970 | } | 1023 | } |
971 | result = max_state_alt (onredirect, result); | 1024 | result = max_state_alt (onredirect, result); |
@@ -1002,23 +1055,55 @@ GOT_FIRST_CERT: | |||
1002 | 1055 | ||
1003 | if (strlen (header_expect)) { | 1056 | if (strlen (header_expect)) { |
1004 | if (!strstr (header_buf.buf, header_expect)) { | 1057 | if (!strstr (header_buf.buf, header_expect)) { |
1058 | |||
1005 | strncpy(&output_header_search[0],header_expect,sizeof(output_header_search)); | 1059 | strncpy(&output_header_search[0],header_expect,sizeof(output_header_search)); |
1060 | |||
1006 | if(output_header_search[sizeof(output_header_search)-1]!='\0') { | 1061 | if(output_header_search[sizeof(output_header_search)-1]!='\0') { |
1007 | bcopy("...",&output_header_search[sizeof(output_header_search)-4],4); | 1062 | bcopy("...",&output_header_search[sizeof(output_header_search)-4],4); |
1008 | } | 1063 | } |
1009 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%sheader '%s' not found on '%s://%s:%d%s', "), msg, output_header_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); | 1064 | |
1010 | result = STATE_CRITICAL; | 1065 | char tmp[DEFAULT_BUFFER_SIZE]; |
1066 | |||
1067 | snprintf (tmp, | ||
1068 | DEFAULT_BUFFER_SIZE, | ||
1069 | _("%sheader '%s' not found on '%s://%s:%d%s', "), | ||
1070 | msg, | ||
1071 | output_header_search, | ||
1072 | use_ssl ? "https" : "http", | ||
1073 | host_name ? host_name : server_address, | ||
1074 | server_port, | ||
1075 | server_url); | ||
1076 | |||
1077 | strcpy(msg, tmp); | ||
1078 | |||
1079 | result = STATE_CRITICAL; | ||
1011 | } | 1080 | } |
1012 | } | 1081 | } |
1013 | 1082 | ||
1014 | if (strlen (string_expect)) { | 1083 | if (strlen (string_expect)) { |
1015 | if (!strstr (body_buf.buf, string_expect)) { | 1084 | if (!strstr (body_buf.buf, string_expect)) { |
1085 | |||
1016 | strncpy(&output_string_search[0],string_expect,sizeof(output_string_search)); | 1086 | strncpy(&output_string_search[0],string_expect,sizeof(output_string_search)); |
1087 | |||
1017 | if(output_string_search[sizeof(output_string_search)-1]!='\0') { | 1088 | if(output_string_search[sizeof(output_string_search)-1]!='\0') { |
1018 | bcopy("...",&output_string_search[sizeof(output_string_search)-4],4); | 1089 | bcopy("...",&output_string_search[sizeof(output_string_search)-4],4); |
1019 | } | 1090 | } |
1020 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, use_ssl ? "https" : "http", host_name ? host_name : server_address, server_port, server_url); | 1091 | |
1021 | result = STATE_CRITICAL; | 1092 | char tmp[DEFAULT_BUFFER_SIZE]; |
1093 | |||
1094 | snprintf (tmp, | ||
1095 | DEFAULT_BUFFER_SIZE, | ||
1096 | _("%sstring '%s' not found on '%s://%s:%d%s', "), | ||
1097 | msg, | ||
1098 | output_string_search, | ||
1099 | use_ssl ? "https" : "http", | ||
1100 | host_name ? host_name : server_address, | ||
1101 | server_port, | ||
1102 | server_url); | ||
1103 | |||
1104 | strcpy(msg, tmp); | ||
1105 | |||
1106 | result = STATE_CRITICAL; | ||
1022 | } | 1107 | } |
1023 | } | 1108 | } |
1024 | 1109 | ||
@@ -1029,27 +1114,48 @@ GOT_FIRST_CERT: | |||
1029 | result = max_state_alt(STATE_OK, result); | 1114 | result = max_state_alt(STATE_OK, result); |
1030 | } | 1115 | } |
1031 | else if ((errcode == REG_NOMATCH && !invert_regex) || (errcode == 0 && invert_regex)) { | 1116 | else if ((errcode == REG_NOMATCH && !invert_regex) || (errcode == 0 && invert_regex)) { |
1032 | if (!invert_regex) | 1117 | if (!invert_regex) { |
1033 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern not found, "), msg); | 1118 | char tmp[DEFAULT_BUFFER_SIZE]; |
1034 | else | 1119 | |
1035 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spattern found, "), msg); | 1120 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%spattern not found, "), msg); |
1036 | result = STATE_CRITICAL; | 1121 | strcpy(msg, tmp); |
1037 | } | 1122 | |
1038 | else { | 1123 | } else { |
1039 | regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); | 1124 | char tmp[DEFAULT_BUFFER_SIZE]; |
1040 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%sExecute Error: %s, "), msg, errbuf); | 1125 | |
1041 | result = STATE_UNKNOWN; | 1126 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%spattern found, "), msg); |
1042 | } | 1127 | strcpy(msg, tmp); |
1128 | |||
1129 | } | ||
1130 | result = STATE_CRITICAL; | ||
1131 | } else { | ||
1132 | regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); | ||
1133 | |||
1134 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
1135 | |||
1136 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sExecute Error: %s, "), msg, errbuf); | ||
1137 | strcpy(msg, tmp); | ||
1138 | result = STATE_UNKNOWN; | ||
1139 | } | ||
1043 | } | 1140 | } |
1044 | 1141 | ||
1045 | /* make sure the page is of an appropriate size */ | 1142 | /* make sure the page is of an appropriate size */ |
1046 | if ((max_page_len > 0) && (page_len > max_page_len)) { | 1143 | if ((max_page_len > 0) && (page_len > max_page_len)) { |
1047 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spage size %d too large, "), msg, page_len); | 1144 | char tmp[DEFAULT_BUFFER_SIZE]; |
1048 | result = max_state_alt(STATE_WARNING, result); | 1145 | |
1049 | } else if ((min_page_len > 0) && (page_len < min_page_len)) { | 1146 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%spage size %d too large, "), msg, page_len); |
1050 | snprintf (msg, DEFAULT_BUFFER_SIZE, _("%spage size %d too small, "), msg, page_len); | 1147 | |
1051 | result = max_state_alt(STATE_WARNING, result); | 1148 | strcpy(msg, tmp); |
1052 | } | 1149 | |
1150 | result = max_state_alt(STATE_WARNING, result); | ||
1151 | |||
1152 | } else if ((min_page_len > 0) && (page_len < min_page_len)) { | ||
1153 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
1154 | |||
1155 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%spage size %d too small, "), msg, page_len); | ||
1156 | strcpy(msg, tmp); | ||
1157 | result = max_state_alt(STATE_WARNING, result); | ||
1158 | } | ||
1053 | 1159 | ||
1054 | /* -w, -c: check warning and critical level */ | 1160 | /* -w, -c: check warning and critical level */ |
1055 | result = max_state_alt(get_status(total_time, thlds), result); | 1161 | result = max_state_alt(get_status(total_time, thlds), result); |
@@ -1633,6 +1739,7 @@ process_arguments (int argc, char **argv) | |||
1633 | break; | 1739 | break; |
1634 | case 'R': /* regex */ | 1740 | case 'R': /* regex */ |
1635 | cflags |= REG_ICASE; | 1741 | cflags |= REG_ICASE; |
1742 | // fall through | ||
1636 | case 'r': /* regex */ | 1743 | case 'r': /* regex */ |
1637 | strncpy (regexp, optarg, MAX_RE_SIZE - 1); | 1744 | strncpy (regexp, optarg, MAX_RE_SIZE - 1); |
1638 | regexp[MAX_RE_SIZE - 1] = 0; | 1745 | regexp[MAX_RE_SIZE - 1] = 0; |
@@ -2030,7 +2137,7 @@ print_usage (void) | |||
2030 | printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); | 2137 | printf (" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n",progname); |
2031 | printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>] [-D]\n"); | 2138 | printf (" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>] [-D]\n"); |
2032 | printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); | 2139 | printf (" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); |
2033 | printf (" [-b proxy_auth] [-f <ok|warning|critcal|follow|sticky|stickyport|curl>]\n"); | 2140 | printf (" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport|curl>]\n"); |
2034 | printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); | 2141 | printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); |
2035 | printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); | 2142 | printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); |
2036 | printf (" [-A string] [-k string] [-S <version>] [--sni]\n"); | 2143 | printf (" [-A string] [-k string] [-S <version>] [--sni]\n"); |
@@ -2196,11 +2303,10 @@ curlhelp_parse_statusline (const char *buf, curlhelp_statusline *status_line) | |||
2196 | if( strchr( p, '.' ) != NULL ) { | 2303 | if( strchr( p, '.' ) != NULL ) { |
2197 | 2304 | ||
2198 | /* HTTP 1.x case */ | 2305 | /* HTTP 1.x case */ |
2199 | char *ppp; | 2306 | strtok( p, "." ); |
2200 | ppp = strtok( p, "." ); | ||
2201 | status_line->http_major = (int)strtol( p, &pp, 10 ); | 2307 | status_line->http_major = (int)strtol( p, &pp, 10 ); |
2202 | if( *pp != '\0' ) { free( first_line_buf ); return -1; } | 2308 | if( *pp != '\0' ) { free( first_line_buf ); return -1; } |
2203 | ppp = strtok( NULL, " " ); | 2309 | strtok( NULL, " " ); |
2204 | status_line->http_minor = (int)strtol( p, &pp, 10 ); | 2310 | status_line->http_minor = (int)strtol( p, &pp, 10 ); |
2205 | if( *pp != '\0' ) { free( first_line_buf ); return -1; } | 2311 | if( *pp != '\0' ) { free( first_line_buf ); return -1; } |
2206 | p += 4; /* 1.x SP */ | 2312 | p += 4; /* 1.x SP */ |
@@ -2287,37 +2393,67 @@ check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFA | |||
2287 | server_date = get_header_value (headers, nof_headers, "date"); | 2393 | server_date = get_header_value (headers, nof_headers, "date"); |
2288 | document_date = get_header_value (headers, nof_headers, "last-modified"); | 2394 | document_date = get_header_value (headers, nof_headers, "last-modified"); |
2289 | 2395 | ||
2290 | if (!server_date || !*server_date) { | 2396 | if (!server_date || !*server_date) { |
2291 | snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sServer date unknown, "), *msg); | 2397 | char tmp[DEFAULT_BUFFER_SIZE]; |
2292 | date_result = max_state_alt(STATE_UNKNOWN, date_result); | 2398 | |
2293 | } else if (!document_date || !*document_date) { | 2399 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sServer date unknown, "), *msg); |
2294 | snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sDocument modification date unknown, "), *msg); | 2400 | strcpy(*msg, tmp); |
2295 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 2401 | |
2402 | date_result = max_state_alt(STATE_UNKNOWN, date_result); | ||
2403 | |||
2404 | } else if (!document_date || !*document_date) { | ||
2405 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
2406 | |||
2407 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sDocument modification date unknown, "), *msg); | ||
2408 | strcpy(*msg, tmp); | ||
2409 | |||
2410 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
2411 | |||
2296 | } else { | 2412 | } else { |
2297 | time_t srv_data = curl_getdate (server_date, NULL); | 2413 | time_t srv_data = curl_getdate (server_date, NULL); |
2298 | time_t doc_data = curl_getdate (document_date, NULL); | 2414 | time_t doc_data = curl_getdate (document_date, NULL); |
2299 | if (verbose >= 2) | 2415 | if (verbose >= 2) |
2300 | printf ("* server date: '%s' (%d), doc_date: '%s' (%d)\n", server_date, (int)srv_data, document_date, (int)doc_data); | 2416 | printf ("* server date: '%s' (%d), doc_date: '%s' (%d)\n", server_date, (int)srv_data, document_date, (int)doc_data); |
2301 | if (srv_data <= 0) { | 2417 | if (srv_data <= 0) { |
2302 | snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sServer date \"%100s\" unparsable, "), *msg, server_date); | 2418 | char tmp[DEFAULT_BUFFER_SIZE]; |
2303 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 2419 | |
2304 | } else if (doc_data <= 0) { | 2420 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sServer date \"%100s\" unparsable, "), *msg, server_date); |
2305 | snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sDocument date \"%100s\" unparsable, "), *msg, document_date); | 2421 | strcpy(*msg, tmp); |
2306 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 2422 | |
2307 | } else if (doc_data > srv_data + 30) { | 2423 | date_result = max_state_alt(STATE_CRITICAL, date_result); |
2308 | snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sDocument is %d seconds in the future, "), *msg, (int)doc_data - (int)srv_data); | 2424 | } else if (doc_data <= 0) { |
2309 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 2425 | char tmp[DEFAULT_BUFFER_SIZE]; |
2310 | } else if (doc_data < srv_data - maximum_age) { | 2426 | |
2311 | int n = (srv_data - doc_data); | 2427 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sDocument date \"%100s\" unparsable, "), *msg, document_date); |
2312 | if (n > (60 * 60 * 24 * 2)) { | 2428 | strcpy(*msg, tmp); |
2313 | snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sLast modified %.1f days ago, "), *msg, ((float) n) / (60 * 60 * 24)); | 2429 | |
2314 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 2430 | date_result = max_state_alt(STATE_CRITICAL, date_result); |
2315 | } else { | 2431 | } else if (doc_data > srv_data + 30) { |
2316 | snprintf (*msg, DEFAULT_BUFFER_SIZE, _("%sLast modified %d:%02d:%02d ago, "), *msg, n / (60 * 60), (n / 60) % 60, n % 60); | 2432 | char tmp[DEFAULT_BUFFER_SIZE]; |
2317 | date_result = max_state_alt(STATE_CRITICAL, date_result); | 2433 | |
2318 | } | 2434 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sDocument is %d seconds in the future, "), *msg, (int)doc_data - (int)srv_data); |
2319 | } | 2435 | strcpy(*msg, tmp); |
2320 | } | 2436 | |
2437 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
2438 | } else if (doc_data < srv_data - maximum_age) { | ||
2439 | int n = (srv_data - doc_data); | ||
2440 | if (n > (60 * 60 * 24 * 2)) { | ||
2441 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
2442 | |||
2443 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sLast modified %.1f days ago, "), *msg, ((float) n) / (60 * 60 * 24)); | ||
2444 | strcpy(*msg, tmp); | ||
2445 | |||
2446 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
2447 | } else { | ||
2448 | char tmp[DEFAULT_BUFFER_SIZE]; | ||
2449 | |||
2450 | snprintf (tmp, DEFAULT_BUFFER_SIZE, _("%sLast modified %d:%02d:%02d ago, "), *msg, n / (60 * 60), (n / 60) % 60, n % 60); | ||
2451 | strcpy(*msg, tmp); | ||
2452 | |||
2453 | date_result = max_state_alt(STATE_CRITICAL, date_result); | ||
2454 | } | ||
2455 | } | ||
2456 | } | ||
2321 | 2457 | ||
2322 | if (server_date) free (server_date); | 2458 | if (server_date) free (server_date); |
2323 | if (document_date) free (document_date); | 2459 | if (document_date) free (document_date); |
@@ -2359,7 +2495,7 @@ get_content_length (const curlhelp_write_curlbuf* header_buf, const curlhelp_wri | |||
2359 | 2495 | ||
2360 | /* TODO: is there a better way in libcurl to check for the SSL library? */ | 2496 | /* TODO: is there a better way in libcurl to check for the SSL library? */ |
2361 | curlhelp_ssl_library | 2497 | curlhelp_ssl_library |
2362 | curlhelp_get_ssl_library (CURL* curl) | 2498 | curlhelp_get_ssl_library () |
2363 | { | 2499 | { |
2364 | curl_version_info_data* version_data; | 2500 | curl_version_info_data* version_data; |
2365 | char *ssl_version; | 2501 | char *ssl_version; |