From ede8defad4f44478f69e148022b542a694498087 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Tue, 19 Jan 2021 18:32:27 +0100 Subject: check_curl: fixed help, usage and errors for TLS 1.3 --- plugins/check_curl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 2d69b310..ef77918b 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -1354,7 +1354,7 @@ process_arguments (int argc, char **argv) ssl_version = CURL_SSLVERSION_DEFAULT; #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0) */ else - usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2 (with optional '+' suffix)")); + usage4 (_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2, 1.3 (with optional '+' suffix)")); } #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) if (got_plus) { @@ -1659,7 +1659,7 @@ print_help (void) printf (" %s\n", "-S, --ssl=VERSION[+]"); printf (" %s\n", _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents")); printf (" %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,")); - printf (" %s\n", _("1.2 = TLSv1.2). With a '+' suffix, newer versions are also accepted.")); + printf (" %s\n", _("1.2 = TLSv1.2, 1.3 = TLSv1.3). With a '+' suffix, newer versions are also accepted.")); printf (" %s\n", _("Note: SSLv2 and SSLv3 are deprecated and are usually disabled in libcurl")); printf (" %s\n", "--sni"); printf (" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); -- cgit v1.2.3-74-g34f1 From d9a5d1faf0400b9da47dee516c035da1a93dc12c Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Tue, 19 Jan 2021 18:35:41 +0100 Subject: check_curl: fixed a potential buffer overflow in url buffer --- plugins/check_curl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index ef77918b..a3f63f16 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -1041,7 +1041,7 @@ redir (curlhelp_write_curlbuf* header_buf) const UriPathSegmentA* p = uri.pathHead; for (; p; p = p->next) { strncat (new_url, "/", DEFAULT_BUFFER_SIZE); - strncat (new_url, uri_string (p->text, buf, DEFAULT_BUFFER_SIZE), DEFAULT_BUFFER_SIZE); + strncat (new_url, uri_string (p->text, buf, DEFAULT_BUFFER_SIZE), DEFAULT_BUFFER_SIZE-1); } } -- cgit v1.2.3-74-g34f1 From 0f926a3566fb6f3333f3a24e47e2ad204fd0fba4 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Mon, 8 Mar 2021 19:46:43 +0100 Subject: check_curl: added string_statuscode function for printing HTTP/1.1 and HTTP/2 correctly --- plugins/check_curl.c | 33 ++++++++++++++++++++++++++++----- 1 file changed, 28 insertions(+), 5 deletions(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index a3f63f16..8f274c26 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -296,6 +296,28 @@ CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) #endif /* USE_OPENSSL */ #endif /* HAVE_SSL */ +/* returns a string "HTTP/1.x" or "HTTP/2" */ +static char *string_statuscode (int major, int minor) +{ + static char buf[10]; + + switch (major) { + case 1: + snprintf (buf, sizeof (buf), "HTTP/%d.%d", major, minor); + break; + case 2: + case 3: + snprintf (buf, sizeof (buf), "HTTP/%d", major); + break; + default: + /* assuming here HTTP/N with N>=4 */ + snprintf (buf, sizeof (buf), "HTTP/%d", major); + break; + } + + return buf; +} + /* Checks if the server 'reply' is one of the expected 'statuscodes' */ static int expected_statuscode (const char *reply, const char *statuscodes) @@ -746,7 +768,8 @@ GOT_FIRST_CERT: if (curlhelp_parse_statusline (header_buf.buf, &status_line) < 0) { snprintf (msg, DEFAULT_BUFFER_SIZE, "Unparsable status line in %.3g seconds response time|%s\n", total_time, perfstring); - die (STATE_CRITICAL, "HTTP CRITICAL HTTP/1.x %ld unknown - %s", code, msg); + /* we cannot know the major/minor version here for sure as we cannot parse the first line */ + die (STATE_CRITICAL, "HTTP CRITICAL HTTP/x.x %ld unknown - %s", code, msg); } /* get result code from cURL */ @@ -823,8 +846,8 @@ GOT_FIRST_CERT: /* check status codes, set exit status accordingly */ if( status_line.http_code != code ) { - die (STATE_CRITICAL, _("HTTP CRITICAL HTTP/%d.%d %d %s - different HTTP codes (cUrl has %ld)\n"), - status_line.http_major, status_line.http_minor, + die (STATE_CRITICAL, _("HTTP CRITICAL %s %d %s - different HTTP codes (cUrl has %ld)\n"), + string_statuscode (status_line.http_major, status_line.http_minor), status_line.http_code, status_line.msg, code); } @@ -895,8 +918,8 @@ GOT_FIRST_CERT: msg[strlen(msg)-3] = '\0'; /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */ - die (result, "HTTP %s: HTTP/%d.%d %d %s%s%s - %d bytes in %.3f second response time %s|%s\n", - state_text(result), status_line.http_major, status_line.http_minor, + die (result, "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n", + state_text(result), string_statuscode (status_line.http_major, status_line.http_minor), status_line.http_code, status_line.msg, strlen(msg) > 0 ? " - " : "", msg, page_len, total_time, -- cgit v1.2.3-74-g34f1 From 5cfc93d995cfd5cc7d1a469f3c1276c4884da2a2 Mon Sep 17 00:00:00 2001 From: Sven Nierlein Date: Thu, 11 Mar 2021 13:33:16 +0100 Subject: fix check_curl crash if http header contains leading spaces check_curl crashes when a (broken) http server returns invalid http header with leading spaces or double colons. This PR adds a fix and a test case for this. Signed-off-by: Sven Nierlein --- plugins/check_curl.c | 2 +- plugins/tests/check_curl.t | 16 +++++++++++++--- 2 files changed, 14 insertions(+), 4 deletions(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 2d69b310..ef96218c 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -2037,7 +2037,7 @@ get_header_value (const struct phr_header* headers, const size_t nof_headers, co { int i; for( i = 0; i < nof_headers; i++ ) { - if( strncasecmp( header, headers[i].name, max( headers[i].name_len, 4 ) ) == 0 ) { + if(headers[i].name != NULL && strncasecmp( header, headers[i].name, max( headers[i].name_len, 4 ) ) == 0 ) { return strndup( headers[i].value, headers[i].value_len ); } } diff --git a/plugins/tests/check_curl.t b/plugins/tests/check_curl.t index 1afbe4bb..0caad23d 100755 --- a/plugins/tests/check_curl.t +++ b/plugins/tests/check_curl.t @@ -21,7 +21,7 @@ use FindBin qw($Bin); $ENV{'LC_TIME'} = "C"; -my $common_tests = 70; +my $common_tests = 72; my $ssl_only_tests = 8; # Check that all dependent modules are available eval "use HTTP::Daemon 6.01;"; @@ -188,6 +188,12 @@ sub run_server { $c->send_basic_header; $c->send_header('foo'); $c->send_crlf; + } elsif ($r->url->path eq "/header_broken_check") { + $c->send_basic_header; + $c->send_header('foo'); + print $c "Test1:: broken\n"; + print $c " Test2: leading whitespace\n"; + $c->send_crlf; } elsif ($r->url->path eq "/virtual_port") { # return sent Host header $c->send_basic_header; @@ -247,7 +253,7 @@ my $cmd; # advanced checks with virtual hostname and virtual port SKIP: { skip "libcurl version is smaller than $required_version", 6 unless $use_advanced_checks; - + # http without virtual port $cmd = "./$plugin -H $virtual_host -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host:$port_http\$"; $result = NPTest->testCmd( $cmd ); @@ -259,7 +265,7 @@ SKIP: { $result = NPTest->testCmd( $cmd ); is( $result->return_code, 0, $cmd); like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - \d+ bytes in [\d\.]+ second/', "Output correct: ".$result->output ); - + # http with virtual port (80) $cmd = "./$plugin -H $virtual_host:80 -I 127.0.0.1 -p $port_http -u /virtual_port -r ^$virtual_host\$"; $result = NPTest->testCmd( $cmd ); @@ -321,6 +327,10 @@ sub run_common_tests { is( $result->return_code, 2, "Missing header string check"); like( $result->output, qr%^HTTP CRITICAL: HTTP/1\.1 200 OK - header 'bar' not found on 'https?://127\.0\.0\.1:\d+/header_check'%, "Shows search string and location"); + $result = NPTest->testCmd( "$command -u /header_broken_check" ); + is( $result->return_code, 0, "header_check search for string"); + like( $result->output, '/^HTTP OK: HTTP/1.1 200 OK - 138 bytes in [\d\.]+ second/', "Output correct" ); + my $cmd; $cmd = "$command -u /slow"; $result = NPTest->testCmd( $cmd ); -- cgit v1.2.3-74-g34f1 From 2482950e267a752b37d696c10ea091dc62d6d8a7 Mon Sep 17 00:00:00 2001 From: Barak Shohat Date: Tue, 6 Apr 2021 16:35:20 +0300 Subject: Updated check_curl.c to display a specific human-readable error message where possible --- plugins/check_curl.c | 6 +++--- plugins/t/check_curl.t | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 8f274c26..8cb2ff49 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -313,8 +313,8 @@ static char *string_statuscode (int major, int minor) /* assuming here HTTP/N with N>=4 */ snprintf (buf, sizeof (buf), "HTTP/%d", major); break; - } - + } + return buf; } @@ -662,7 +662,7 @@ check_http (void) /* Curl errors, result in critical Nagios state */ if (res != CURLE_OK) { snprintf (msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: cURL returned %d - %s"), - server_port, res, curl_easy_strerror(res)); + server_port, res, errbuf[0] ? errbuf : curl_easy_strerror(res)); die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); } diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t index 4bff538a..cc65f037 100644 --- a/plugins/t/check_curl.t +++ b/plugins/t/check_curl.t @@ -46,7 +46,7 @@ $res = NPTest->testCmd( ); cmp_ok( $res->return_code, '==', 2, "Webserver $host_nonresponsive not responding" ); # was CRITICAL only, but both check_curl and check_http print HTTP CRITICAL (puzzle?!) -cmp_ok( $res->output, 'eq', "HTTP CRITICAL - Invalid HTTP response received from host on port 80: cURL returned 28 - Timeout was reached", "Output OK"); +like( $res->output, "/HTTP CRITICAL - Invalid HTTP response received from host on port 80: cURL returned 28 - Connection timed out after/", "Output OK"); $res = NPTest->testCmd( "./$plugin $hostname_invalid -wt 1 -ct 2" @@ -56,7 +56,7 @@ cmp_ok( $res->return_code, '==', 2, "Webserver $hostname_invalid not valid" ); # On Debian, it is Name or service not known, on Darwin, it is No address associated with nodename # Is also possible to get a socket timeout if DNS is not responding fast enough # cURL gives us consistent strings from it's own 'lib/strerror.c' -like( $res->output, "/cURL returned 6 - Couldn't resolve host name/", "Output OK"); +like( $res->output, "/cURL returned 6 - Could not resolve host:/", "Output OK"); # host header checks $res = NPTest->testCmd("./$plugin -v -H $host_tcp_http"); -- cgit v1.2.3-74-g34f1 From 6993c216955a54845d98dc568534613334c0b545 Mon Sep 17 00:00:00 2001 From: Barak Shohat Date: Wed, 7 Apr 2021 12:34:46 +0300 Subject: Add an option to check_curl to verify the peer certificate & host using the system CA's --- plugins/check_curl.c | 17 ++++++++++++++--- plugins/t/check_curl.t | 5 ++++- 2 files changed, 18 insertions(+), 4 deletions(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 8f274c26..19f80b74 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -195,6 +195,7 @@ int ssl_version = CURL_SSLVERSION_DEFAULT; char *client_cert = NULL; char *client_privkey = NULL; char *ca_cert = NULL; +int verify_peer_and_host = FALSE; int is_openssl_callback = FALSE; #if defined(HAVE_SSL) && defined(USE_OPENSSL) X509 *cert = NULL; @@ -489,9 +490,11 @@ check_http (void) if (client_privkey) handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_SSLKEY, client_privkey), "CURLOPT_SSLKEY"); if (ca_cert) { + handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CAINFO, ca_cert), "CURLOPT_CAINFO"); + } + if (ca_cert || verify_peer_and_host) { /* per default if we have a CA verify both the peer and the * hostname in the certificate, can be switched off later */ - handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CAINFO, ca_cert), "CURLOPT_CAINFO"); handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_SSL_VERIFYPEER, 1), "CURLOPT_SSL_VERIFYPEER"); handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_SSL_VERIFYHOST, 2), "CURLOPT_SSL_VERIFYHOST"); } else { @@ -1159,6 +1162,7 @@ process_arguments (int argc, char **argv) {"client-cert", required_argument, 0, 'J'}, {"private-key", required_argument, 0, 'K'}, {"ca-cert", required_argument, 0, CA_CERT_OPTION}, + {"verify-cert", no_argument, 0, 'D'}, {"useragent", required_argument, 0, 'A'}, {"header", required_argument, 0, 'k'}, {"no-body", no_argument, 0, 'N'}, @@ -1193,7 +1197,7 @@ process_arguments (int argc, char **argv) server_url = strdup(DEFAULT_SERVER_URL); while (1) { - c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:nlLS::m:M:NE", longopts, &option); + c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:DnlLS::m:M:NE", longopts, &option); if (c == -1 || c == EOF || c == 1) break; @@ -1332,6 +1336,11 @@ process_arguments (int argc, char **argv) test_file(optarg); ca_cert = optarg; goto enable_ssl; +#endif +#ifdef LIBCURL_FEATURE_SSL + case 'D': /* verify peer certificate & host */ + verify_peer_and_host = TRUE; + goto enable_ssl; #endif case 'S': /* use SSL */ #ifdef LIBCURL_FEATURE_SSL @@ -1703,6 +1712,8 @@ print_help (void) printf (" %s\n", _("matching the client certificate")); printf (" %s\n", "--ca-cert=FILE"); printf (" %s\n", _("CA certificate file to verify peer against")); + printf (" %s\n", "-D, --verify-cert"); + printf (" %s\n", _("Verify the peer's SSL certificate and hostname")); #endif printf (" %s\n", "-e, --expect=STRING"); @@ -1836,7 +1847,7 @@ print_usage (void) { printf ("%s\n", _("Usage:")); printf (" %s -H | -I [-u ] [-p ]\n",progname); - printf (" [-J ] [-K ] [--ca-cert ]\n"); + printf (" [-J ] [-K ] [--ca-cert ] [-D]\n"); printf (" [-w ] [-c ] [-t ] [-L] [-E] [-a auth]\n"); printf (" [-b proxy_auth] [-f ]\n"); printf (" [-e ] [-d string] [-s string] [-l] [-r | -R ]\n"); diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t index 4bff538a..55577add 100644 --- a/plugins/t/check_curl.t +++ b/plugins/t/check_curl.t @@ -9,7 +9,7 @@ use Test::More; use POSIX qw/mktime strftime/; use NPTest; -plan tests => 57; +plan tests => 58; my $successOutput = '/OK.*HTTP.*second/'; @@ -94,6 +94,9 @@ SKIP: { $res = NPTest->testCmd("./$plugin -v -H $host_tls_http:443 -S -p 443"); like( $res->output, '/^Host: '.$host_tls_http.'\s*$/ms', "Host Header OK" ); + + $res = NPTest->testCmd("./$plugin -v -H $host_tls_http -D -p 443"); + like( $res->output, '/(^Host: '.$host_tls_http.'\s*$)|(cURL returned 60)/ms', "Host Header OK" ); }; SKIP: { -- cgit v1.2.3-74-g34f1 From f90aec83cb20263401ab620d07e4914355d9681d Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 8 Apr 2021 14:07:20 +0200 Subject: check_curl: Increase regexp limit (to 1024 as in check_http) --- plugins/check_curl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 8125ee84..f900f160 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -117,7 +117,7 @@ typedef enum curlhelp_ssl_library { enum { REGS = 2, - MAX_RE_SIZE = 256 + MAX_RE_SIZE = 1024 }; #include "regex.h" regex_t preg; -- cgit v1.2.3-74-g34f1 From a6acea7941a2a5519ab49d13b5adf946a50b5ea5 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 8 Apr 2021 14:15:54 +0200 Subject: check_curl: make -C obvious (from check_http) --- plugins/check_curl.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index f900f160..892300ae 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -1852,9 +1852,11 @@ print_usage (void) printf (" [-b proxy_auth] [-f ]\n"); printf (" [-e ] [-d string] [-s string] [-l] [-r | -R ]\n"); printf (" [-P string] [-m :] [-4|-6] [-N] [-M ]\n"); - printf (" [-A string] [-k string] [-S ] [--sni] [-C [,]]\n"); + printf (" [-A string] [-k string] [-S ] [--sni]\n"); printf (" [-T ] [-j method]\n"); printf (" [--http-version=]\n"); + printf (" %s -H | -I -C [,]\n",progname); + printf (" [-p ] [-t ] [-4|-6] [--sni]\n"); printf ("\n"); printf ("%s\n", _("WARNING: check_curl is experimental. Please use")); printf ("%s\n\n", _("check_http if you need a stable version.")); -- cgit v1.2.3-74-g34f1 From 1debd29b573f4d81eeba4d7f78f797c348b231ce Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 8 Apr 2021 15:14:53 +0200 Subject: check_curl: make -C obvious (from check_http, part 2) --- plugins/check_curl.c | 4 ++++ 1 file changed, 4 insertions(+) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 892300ae..8fc97f40 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -1858,6 +1858,10 @@ print_usage (void) printf (" %s -H | -I -C [,]\n",progname); printf (" [-p ] [-t ] [-4|-6] [--sni]\n"); printf ("\n"); +#ifdef LIBCURL_FEATURE_SSL + printf ("%s\n", _("In the first form, make an HTTP request.")); + printf ("%s\n\n", _("In the second form, connect to the server and check the TLS certificate.")); +#endif printf ("%s\n", _("WARNING: check_curl is experimental. Please use")); printf ("%s\n\n", _("check_http if you need a stable version.")); } -- cgit v1.2.3-74-g34f1 From cd358cd08a6ddceece836788078ec96b5f8eb0c5 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 8 Apr 2021 20:39:48 +0200 Subject: check_curl: backported --show-body/-B to print body (from check_http) --- plugins/check_curl.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 8fc97f40..99833f6f 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -145,6 +145,7 @@ thresholds *thlds; char user_agent[DEFAULT_BUFFER_SIZE]; int verbose = 0; int show_extended_perfdata = FALSE; +int show_body = FALSE; int min_page_len = 0; int max_page_len = 0; int redir_depth = 0; @@ -792,7 +793,9 @@ GOT_FIRST_CERT: snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host: %s\n"), status_line.first_line); else snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: %s\n"), server_port, status_line.first_line); - die (STATE_CRITICAL, "HTTP CRITICAL - %s", msg); + die (STATE_CRITICAL, "HTTP CRITICAL - %s%s%s", msg, + show_body ? "\n" : "", + show_body ? body_buf.buf : ""); } if( server_expect_yn ) { @@ -921,13 +924,15 @@ GOT_FIRST_CERT: msg[strlen(msg)-3] = '\0'; /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */ - die (result, "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n", + die (result, "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s", state_text(result), string_statuscode (status_line.http_major, status_line.http_minor), status_line.http_code, status_line.msg, strlen(msg) > 0 ? " - " : "", msg, page_len, total_time, (display_html ? "" : ""), - perfstring); + perfstring, + (show_body ? body_buf.buf : ""), + (show_body ? "\n" : "") ); /* proper cleanup after die? */ curlhelp_free_statusline(&status_line); @@ -1173,6 +1178,7 @@ process_arguments (int argc, char **argv) {"use-ipv4", no_argument, 0, '4'}, {"use-ipv6", no_argument, 0, '6'}, {"extended-perfdata", no_argument, 0, 'E'}, + {"show-body", no_argument, 0, 'B'}, {"http-version", required_argument, 0, HTTP_VERSION_OPTION}, {0, 0, 0, 0} }; @@ -1197,7 +1203,7 @@ process_arguments (int argc, char **argv) server_url = strdup(DEFAULT_SERVER_URL); while (1) { - c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:DnlLS::m:M:NE", longopts, &option); + c = getopt_long (argc, argv, "Vvh46t:c:w:A:k:H:P:j:T:I:a:b:d:e:p:s:R:r:u:f:C:J:K:DnlLS::m:M:NEB", longopts, &option); if (c == -1 || c == EOF || c == 1) break; @@ -1545,6 +1551,9 @@ process_arguments (int argc, char **argv) case 'E': /* show extended perfdata */ show_extended_perfdata = TRUE; break; + case 'B': /* print body content after status line */ + show_body = TRUE; + break; case HTTP_VERSION_OPTION: curl_http_version = CURL_HTTP_VERSION_NONE; if (strcmp (optarg, "1.0") == 0) { @@ -1757,6 +1766,8 @@ print_help (void) printf (" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers")); printf (" %s\n", "-E, --extended-perfdata"); printf (" %s\n", _("Print additional performance data")); + printf (" %s\n", "-B, --show-body"); + printf (" %s\n", _("Print body content below status line")); printf (" %s\n", "-L, --link"); printf (" %s\n", _("Wrap output in HTML link (obsoleted by urlize)")); printf (" %s\n", "-f, --onredirect="); -- cgit v1.2.3-74-g34f1 From f0ac7fcc7c40fab04c00fbbc8c091e89e77b0f74 Mon Sep 17 00:00:00 2001 From: Barak Shohat Date: Mon, 12 Apr 2021 19:06:27 +0300 Subject: check_curl: Fix bug where headers beginning with HTTP_ cause the status line parsing to fail. --- plugins/check_curl.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 99833f6f..3e0a6f94 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -1995,7 +1995,7 @@ curlhelp_parse_statusline (const char *buf, curlhelp_statusline *status_line) char *first_line_buf; /* find last start of a new header */ - start = strrstr2 (buf, "\r\nHTTP"); + start = strrstr2 (buf, "\r\nHTTP/"); if (start != NULL) { start += 2; buf = start; -- cgit v1.2.3-74-g34f1 From 63cb7ecfcf8d5b6c9f2be704eee7fa7cd9216f88 Mon Sep 17 00:00:00 2001 From: Barak Shohat Date: Mon, 24 May 2021 13:42:43 +0300 Subject: check_curl.c: bugfix: verify certificates option should not force SSL to be used --- plugins/check_curl.c | 2 +- plugins/t/check_curl.t | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 3e0a6f94..d29db0a6 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -1346,7 +1346,7 @@ process_arguments (int argc, char **argv) #ifdef LIBCURL_FEATURE_SSL case 'D': /* verify peer certificate & host */ verify_peer_and_host = TRUE; - goto enable_ssl; + break; #endif case 'S': /* use SSL */ #ifdef LIBCURL_FEATURE_SSL diff --git a/plugins/t/check_curl.t b/plugins/t/check_curl.t index 45ee5339..ada6a045 100644 --- a/plugins/t/check_curl.t +++ b/plugins/t/check_curl.t @@ -95,7 +95,7 @@ SKIP: { $res = NPTest->testCmd("./$plugin -v -H $host_tls_http:443 -S -p 443"); like( $res->output, '/^Host: '.$host_tls_http.'\s*$/ms', "Host Header OK" ); - $res = NPTest->testCmd("./$plugin -v -H $host_tls_http -D -p 443"); + $res = NPTest->testCmd("./$plugin -v -H $host_tls_http -D -S -p 443"); like( $res->output, '/(^Host: '.$host_tls_http.'\s*$)|(cURL returned 60)/ms', "Host Header OK" ); }; -- cgit v1.2.3-74-g34f1 From beb609ffcf8c24c133f59829e0d3d82102661b82 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 27 May 2021 15:32:08 +0200 Subject: check_curl: - added verbose output in verify_callback - pin refcounting for certs (avoid subject extraction error when checking certs in is_openssl_callback mode) --- plugins/check_curl.c | 12 ++++++++++++ 1 file changed, 12 insertions(+) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 3e0a6f94..59e398b2 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -285,6 +285,18 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) * TODO: is the last certificate always the server certificate? */ cert = X509_STORE_CTX_get_current_cert(x509_ctx); + X509_up_ref(cert); + if (verbose>=2) { + puts("* SSL verify callback with certificate:"); + X509_NAME *subject, *issuer; + printf("* issuer:\n"); + issuer = X509_get_issuer_name( cert ); + X509_NAME_print_ex_fp(stdout, issuer, 5, XN_FLAG_MULTILINE); + printf("* curl verify_callback:\n* subject:\n"); + subject = X509_get_subject_name( cert ); + X509_NAME_print_ex_fp(stdout, subject, 5, XN_FLAG_MULTILINE); + puts(""); + } return 1; } -- cgit v1.2.3-74-g34f1 From 20e9451fadb452636bc4b395fcb6aaf93a477c23 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 24 Jun 2021 11:02:28 +0200 Subject: added option --enable-automatic-decompression --- plugins/check_curl.c | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 59e398b2..d4442f51 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -206,6 +206,7 @@ int maximum_age = -1; int address_family = AF_UNSPEC; curlhelp_ssl_library ssl_library = CURLHELP_SSL_LIBRARY_UNKNOWN; int curl_http_version = CURL_HTTP_VERSION_NONE; +int automatic_decompression = FALSE; int process_arguments (int, char**); void handle_curl_option_return_code (CURLcode res, const char* option); @@ -383,6 +384,13 @@ check_http (void) /* print everything on stdout like check_http would do */ handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_STDERR, stdout), "CURLOPT_STDERR"); + if (automatic_decompression) +#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6) + handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""), "CURLOPT_ACCEPT_ENCODING"); +#else + handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_ENCODING, ""), "CURLOPT_ENCODING"); +#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6) */ + /* initialize buffer for body of the answer */ if (curlhelp_initwritebuffer(&body_buf) < 0) die (STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n"); @@ -1149,7 +1157,8 @@ process_arguments (int argc, char **argv) INVERT_REGEX = CHAR_MAX + 1, SNI_OPTION, CA_CERT_OPTION, - HTTP_VERSION_OPTION + HTTP_VERSION_OPTION, + AUTOMATIC_DECOMPRESSION }; int option = 0; @@ -1192,6 +1201,7 @@ process_arguments (int argc, char **argv) {"extended-perfdata", no_argument, 0, 'E'}, {"show-body", no_argument, 0, 'B'}, {"http-version", required_argument, 0, HTTP_VERSION_OPTION}, + {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION}, {0, 0, 0, 0} }; @@ -1583,6 +1593,9 @@ process_arguments (int argc, char **argv) exit (STATE_WARNING); } break; + case AUTOMATIC_DECOMPRESSION: + automatic_decompression = TRUE; + break; case '?': /* print short usage statement if args not parsable */ usage5 (); @@ -1793,6 +1806,8 @@ print_help (void) printf (" %s\n", "--http-version=VERSION"); printf (" %s\n", _("Connect via specific HTTP protocol.")); printf (" %s\n", _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)")); + printf (" %s\n", "--enable-automatic-decompression"); + printf (" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING).")); printf ("\n"); printf (UT_WARN_CRIT); -- cgit v1.2.3-74-g34f1 From 0b6838ffcaf372df419059771dd42f1bd69644c0 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Thu, 24 Jun 2021 17:08:20 +0000 Subject: fix for missing X509_up_ref on old systems with only OpenSSL 1.0 --- plugins/check_curl.c | 6 ++++++ 1 file changed, 6 insertions(+) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index d4442f51..daf64b0b 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -55,6 +55,10 @@ const char *email = "devel@monitoring-plugins.org"; #include +#if defined(HAVE_SSL) && defined(USE_OPENSSL) +#include +#endif + #define MAKE_LIBCURL_VERSION(major, minor, patch) ((major)*0x10000 + (minor)*0x100 + (patch)) #define DEFAULT_BUFFER_SIZE 2048 @@ -286,7 +290,9 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) * TODO: is the last certificate always the server certificate? */ cert = X509_STORE_CTX_get_current_cert(x509_ctx); +#if OPENSSL_VERSION_NUMBER >= 0x10100000L X509_up_ref(cert); +#endif if (verbose>=2) { puts("* SSL verify callback with certificate:"); X509_NAME *subject, *issuer; -- cgit v1.2.3-74-g34f1 From 6e696643a5701ddd18945593743286b35b5944cb Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 4 Jul 2021 18:43:42 +0200 Subject: check_curl: changed to STATE_CRITICAL for infinite loops (-ffollow) --- plugins/check_curl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index daf64b0b..ba08c36b 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -1106,8 +1106,8 @@ redir (curlhelp_write_curlbuf* header_buf) !strncmp(server_address, new_host, MAX_IPV4_HOSTLENGTH) && (host_name && !strncmp(host_name, new_host, MAX_IPV4_HOSTLENGTH)) && !strcmp(server_url, new_url)) - die (STATE_WARNING, - _("HTTP WARNING - redirection creates an infinite loop - %s://%s:%d%s%s\n"), + die (STATE_CRITICAL, + _("HTTP CRITICAL - redirection creates an infinite loop - %s://%s:%d%s%s\n"), use_ssl ? "https" : "http", new_host, new_port, new_url, (display_html ? "" : "")); /* set new values for redirected request */ -- cgit v1.2.3-74-g34f1 From 3f5c54c7830b0529030bb08e2c333497e70b6eb1 Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 25 Jul 2021 18:39:07 +0200 Subject: check_curl: fixed DNS caching for SSL hostnames (avoid CURLOPT_RESOLVE entry errors) --- plugins/check_curl.c | 54 +++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 51 insertions(+), 3 deletions(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index ba08c36b..2c91a275 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -59,6 +59,8 @@ const char *email = "devel@monitoring-plugins.org"; #include #endif +#include + #define MAKE_LIBCURL_VERSION(major, minor, patch) ((major)*0x10000 + (minor)*0x100 + (patch)) #define DEFAULT_BUFFER_SIZE 2048 @@ -369,6 +371,46 @@ handle_curl_option_return_code (CURLcode res, const char* option) } } +int +lookup_host (const char *host, char *buf, size_t buflen) +{ + struct addrinfo hints, *res, *result; + int errcode; + void *ptr; + + memset (&hints, 0, sizeof (hints)); + hints.ai_family = address_family; + hints.ai_socktype = SOCK_STREAM; + hints.ai_flags |= AI_CANONNAME; + + errcode = getaddrinfo (host, NULL, &hints, &result); + if (errcode != 0) + return errcode; + + res = result; + + while (res) { + inet_ntop (res->ai_family, res->ai_addr->sa_data, buf, buflen); + switch (res->ai_family) { + case AF_INET: + ptr = &((struct sockaddr_in *) res->ai_addr)->sin_addr; + break; + case AF_INET6: + ptr = &((struct sockaddr_in6 *) res->ai_addr)->sin6_addr; + break; + } + inet_ntop (res->ai_family, ptr, buf, buflen); + if (verbose >= 1) + printf ("* getaddrinfo IPv%d address: %s\n", + res->ai_family == PF_INET6 ? 6 : 4, buf); + res = res->ai_next; + } + + freeaddrinfo(result); + + return 0; +} + int check_http (void) { @@ -376,6 +418,9 @@ check_http (void) int page_len = 0; int i; char *force_host_header = NULL; + struct curl_slist *host = NULL; + char addrstr[100]; + char dnscache[DEFAULT_BUFFER_SIZE]; /* initialize curl */ if (curl_global_init (CURL_GLOBAL_DEFAULT) != CURLE_OK) @@ -418,9 +463,12 @@ check_http (void) // 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 if(use_ssl && host_name != NULL) { - struct curl_slist *host = NULL; - char dnscache[DEFAULT_BUFFER_SIZE]; - snprintf (dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, server_address); + if ( (res=lookup_host (server_address, addrstr, 100)) != 0) { + snprintf (msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), + server_address, res, gai_strerror (res)); + die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); + } + snprintf (dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", host_name, server_port, addrstr); host = curl_slist_append(NULL, dnscache); curl_easy_setopt(curl, CURLOPT_RESOLVE, host); if (verbose>=1) -- cgit v1.2.3-74-g34f1 From de5503063e4ea455a7a0a57afcc467a2041c859f Mon Sep 17 00:00:00 2001 From: Andreas Baumann Date: Sun, 25 Jul 2021 18:49:06 +0200 Subject: check_curl: fixed a potential buffer overflow in retir/uri_string --- plugins/check_curl.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'plugins/check_curl.c') diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 2c91a275..5990b95b 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c @@ -1033,8 +1033,8 @@ char* uri_string (const UriTextRangeA range, char* buf, size_t buflen) { if (!range.first) return "(null)"; - strncpy (buf, range.first, max (buflen, range.afterLast - range.first)); - buf[max (buflen, range.afterLast - range.first)] = '\0'; + strncpy (buf, range.first, max (buflen-1, range.afterLast - range.first)); + buf[max (buflen-1, range.afterLast - range.first)] = '\0'; buf[range.afterLast - range.first] = '\0'; return buf; } -- cgit v1.2.3-74-g34f1