New upstream version 2.3.2
This commit is contained in:
parent
09f4277f49
commit
21323d25dd
104 changed files with 34386 additions and 7430 deletions
|
@ -55,18 +55,24 @@ const char *email = "devel@monitoring-plugins.org";
|
|||
|
||||
#include <arpa/inet.h>
|
||||
|
||||
#if defined(HAVE_SSL) && defined(USE_OPENSSL)
|
||||
#include <openssl/opensslv.h>
|
||||
#endif
|
||||
|
||||
#include <netdb.h>
|
||||
|
||||
#define MAKE_LIBCURL_VERSION(major, minor, patch) ((major)*0x10000 + (minor)*0x100 + (patch))
|
||||
|
||||
#define DEFAULT_BUFFER_SIZE 2048
|
||||
#define DEFAULT_SERVER_URL "/"
|
||||
#define HTTP_EXPECT "HTTP/"
|
||||
#define DEFAULT_MAX_REDIRS 15
|
||||
#define INET_ADDR_MAX_SIZE INET6_ADDRSTRLEN
|
||||
enum {
|
||||
MAX_IPV4_HOSTLENGTH = 255,
|
||||
HTTP_PORT = 80,
|
||||
HTTPS_PORT = 443,
|
||||
MAX_PORT = 65535
|
||||
MAX_PORT = 65535,
|
||||
DEFAULT_MAX_REDIRS = 15
|
||||
};
|
||||
|
||||
enum {
|
||||
|
@ -187,6 +193,7 @@ int followsticky = STICKY_NONE;
|
|||
int use_ssl = FALSE;
|
||||
int use_sni = TRUE;
|
||||
int check_cert = FALSE;
|
||||
int continue_after_check_cert = FALSE;
|
||||
typedef union {
|
||||
struct curl_slist* to_info;
|
||||
struct curl_certinfo* to_certinfo;
|
||||
|
@ -206,6 +213,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);
|
||||
|
@ -285,6 +293,20 @@ 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;
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -350,6 +372,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)
|
||||
{
|
||||
|
@ -357,6 +419,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)
|
||||
|
@ -371,6 +436,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");
|
||||
|
@ -392,9 +464,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)
|
||||
|
@ -680,7 +755,9 @@ check_http (void)
|
|||
* and we actually have OpenSSL in the monitoring tools
|
||||
*/
|
||||
result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
|
||||
return result;
|
||||
if (continue_after_check_cert == FALSE) {
|
||||
return result;
|
||||
}
|
||||
#else /* USE_OPENSSL */
|
||||
die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n");
|
||||
#endif /* USE_OPENSSL */
|
||||
|
@ -720,13 +797,17 @@ GOT_FIRST_CERT:
|
|||
}
|
||||
BIO_free (cert_BIO);
|
||||
result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit);
|
||||
return result;
|
||||
if (continue_after_check_cert == FALSE) {
|
||||
return result;
|
||||
}
|
||||
#else /* USE_OPENSSL */
|
||||
/* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal,
|
||||
* so we use the libcurl CURLINFO data
|
||||
*/
|
||||
result = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit);
|
||||
return result;
|
||||
if (continue_after_check_cert == FALSE) {
|
||||
return result;
|
||||
}
|
||||
#endif /* USE_OPENSSL */
|
||||
} else {
|
||||
snprintf (msg, DEFAULT_BUFFER_SIZE, _("Cannot retrieve certificates - cURL returned %d - %s"),
|
||||
|
@ -959,8 +1040,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;
|
||||
}
|
||||
|
@ -980,7 +1061,7 @@ redir (curlhelp_write_curlbuf* header_buf)
|
|||
char *new_url;
|
||||
|
||||
int res = phr_parse_response (header_buf->buf, header_buf->buflen,
|
||||
&status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
|
||||
&status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
|
||||
headers, &nof_headers, 0);
|
||||
|
||||
location = get_header_value (headers, nof_headers, "location");
|
||||
|
@ -1080,8 +1161,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 ? "</A>" : ""));
|
||||
|
||||
/* set new values for redirected request */
|
||||
|
@ -1136,8 +1217,11 @@ process_arguments (int argc, char **argv)
|
|||
enum {
|
||||
INVERT_REGEX = CHAR_MAX + 1,
|
||||
SNI_OPTION,
|
||||
MAX_REDIRS_OPTION,
|
||||
CONTINUE_AFTER_CHECK_CERT,
|
||||
CA_CERT_OPTION,
|
||||
HTTP_VERSION_OPTION
|
||||
HTTP_VERSION_OPTION,
|
||||
AUTOMATIC_DECOMPRESSION
|
||||
};
|
||||
|
||||
int option = 0;
|
||||
|
@ -1168,6 +1252,7 @@ process_arguments (int argc, char **argv)
|
|||
{"private-key", required_argument, 0, 'K'},
|
||||
{"ca-cert", required_argument, 0, CA_CERT_OPTION},
|
||||
{"verify-cert", no_argument, 0, 'D'},
|
||||
{"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT},
|
||||
{"useragent", required_argument, 0, 'A'},
|
||||
{"header", required_argument, 0, 'k'},
|
||||
{"no-body", no_argument, 0, 'N'},
|
||||
|
@ -1179,7 +1264,9 @@ process_arguments (int argc, char **argv)
|
|||
{"use-ipv6", no_argument, 0, '6'},
|
||||
{"extended-perfdata", no_argument, 0, 'E'},
|
||||
{"show-body", no_argument, 0, 'B'},
|
||||
{"max-redirs", required_argument, 0, MAX_REDIRS_OPTION},
|
||||
{"http-version", required_argument, 0, HTTP_VERSION_OPTION},
|
||||
{"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION},
|
||||
{0, 0, 0, 0}
|
||||
};
|
||||
|
||||
|
@ -1324,6 +1411,11 @@ process_arguments (int argc, char **argv)
|
|||
}
|
||||
check_cert = TRUE;
|
||||
goto enable_ssl;
|
||||
#endif
|
||||
case CONTINUE_AFTER_CHECK_CERT: /* don't stop after the certificate is checked */
|
||||
#ifdef HAVE_SSL
|
||||
continue_after_check_cert = TRUE;
|
||||
break;
|
||||
#endif
|
||||
case 'J': /* use client certificate */
|
||||
#ifdef LIBCURL_FEATURE_SSL
|
||||
|
@ -1346,7 +1438,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
|
||||
|
@ -1436,6 +1528,13 @@ process_arguments (int argc, char **argv)
|
|||
use_sni = TRUE;
|
||||
break;
|
||||
#endif /* LIBCURL_FEATURE_SSL */
|
||||
case MAX_REDIRS_OPTION:
|
||||
if (!is_intnonneg (optarg))
|
||||
usage2 (_("Invalid max_redirs count"), optarg);
|
||||
else {
|
||||
max_depth = atoi (optarg);
|
||||
}
|
||||
break;
|
||||
case 'f': /* onredirect */
|
||||
if (!strcmp (optarg, "ok"))
|
||||
onredirect = STATE_OK;
|
||||
|
@ -1571,6 +1670,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 ();
|
||||
|
@ -1712,7 +1814,11 @@ print_help (void)
|
|||
#endif
|
||||
printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]");
|
||||
printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443"));
|
||||
printf (" %s\n", _("(when this option is used the URL is not checked.)"));
|
||||
printf (" %s\n", _("(when this option is used the URL is not checked by default. You can use"));
|
||||
printf (" %s\n", _(" --continue-after-certificate to override this behavior)"));
|
||||
printf (" %s\n", "--continue-after-certificate");
|
||||
printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check."));
|
||||
printf (" %s\n", _("Does nothing unless -C is used."));
|
||||
printf (" %s\n", "-J, --client-cert=FILE");
|
||||
printf (" %s\n", _("Name of file that contains the client certificate (PEM format)"));
|
||||
printf (" %s\n", _("to be used in establishing the SSL session"));
|
||||
|
@ -1775,12 +1881,17 @@ print_help (void)
|
|||
printf (" %s\n", _("specified IP address. stickyport also ensures port stays the same."));
|
||||
printf (" %s\n", _("follow uses the old redirection algorithm of check_http."));
|
||||
printf (" %s\n", _("curl uses CURL_FOLLOWLOCATION built into libcurl."));
|
||||
printf (" %s\n", "--max-redirs=INTEGER");
|
||||
printf (" %s", _("Maximal number of redirects (default: "));
|
||||
printf ("%d)\n", DEFAULT_MAX_REDIRS);
|
||||
printf (" %s\n", "-m, --pagesize=INTEGER<:INTEGER>");
|
||||
printf (" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)"));
|
||||
printf ("\n");
|
||||
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);
|
||||
|
@ -1995,7 +2106,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;
|
||||
|
@ -2107,7 +2218,7 @@ check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFA
|
|||
size_t msglen;
|
||||
|
||||
int res = phr_parse_response (header_buf->buf, header_buf->buflen,
|
||||
&status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
|
||||
&status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
|
||||
headers, &nof_headers, 0);
|
||||
|
||||
server_date = get_header_value (headers, nof_headers, "date");
|
||||
|
@ -2165,7 +2276,7 @@ get_content_length (const curlhelp_write_curlbuf* header_buf, const curlhelp_wri
|
|||
curlhelp_statusline status_line;
|
||||
|
||||
int res = phr_parse_response (header_buf->buf, header_buf->buflen,
|
||||
&status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
|
||||
&status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen,
|
||||
headers, &nof_headers, 0);
|
||||
|
||||
content_length_s = get_header_value (headers, nof_headers, "content-length");
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue