summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-07-06 23:46:16 +0200
committerLorenz Kästle <12514511+RincewindsHat@users.noreply.github.com>2025-07-06 23:46:16 +0200
commite855107eeb882d25ce777562d16886ea9aa2633e (patch)
tree0df46a1f4d7883d5c8ed8e2f7f37101c42244576
parent45ea3e7b9ffc1486ec89fcf7d702e59b15d414a6 (diff)
downloadmonitoring-plugins-e855107eeb882d25ce777562d16886ea9aa2633e.tar.gz
check_curl: clang-format
-rw-r--r--plugins/check_curl.c771
1 files changed, 495 insertions, 276 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c
index 4806bf14..5b8a06be 100644
--- a/plugins/check_curl.c
+++ b/plugins/check_curl.c
@@ -169,10 +169,13 @@ static void print_help(void);
169void print_usage(void); 169void print_usage(void);
170static void print_curl_version(void); 170static void print_curl_version(void);
171static int curlhelp_initwritebuffer(curlhelp_write_curlbuf * /*buf*/); 171static int curlhelp_initwritebuffer(curlhelp_write_curlbuf * /*buf*/);
172static size_t curlhelp_buffer_write_callback(void * /*buffer*/, size_t /*size*/, size_t /*nmemb*/, void * /*stream*/); 172static size_t curlhelp_buffer_write_callback(void * /*buffer*/, size_t /*size*/, size_t /*nmemb*/,
173 void * /*stream*/);
173static void curlhelp_freewritebuffer(curlhelp_write_curlbuf * /*buf*/); 174static void curlhelp_freewritebuffer(curlhelp_write_curlbuf * /*buf*/);
174static int curlhelp_initreadbuffer(curlhelp_read_curlbuf * /*buf*/, const char * /*data*/, size_t /*datalen*/); 175static int curlhelp_initreadbuffer(curlhelp_read_curlbuf * /*buf*/, const char * /*data*/,
175static size_t curlhelp_buffer_read_callback(void * /*buffer*/, size_t /*size*/, size_t /*nmemb*/, void * /*stream*/); 176 size_t /*datalen*/);
177static size_t curlhelp_buffer_read_callback(void * /*buffer*/, size_t /*size*/, size_t /*nmemb*/,
178 void * /*stream*/);
176static void curlhelp_freereadbuffer(curlhelp_read_curlbuf * /*buf*/); 179static void curlhelp_freereadbuffer(curlhelp_read_curlbuf * /*buf*/);
177static curlhelp_ssl_library curlhelp_get_ssl_library(void); 180static curlhelp_ssl_library curlhelp_get_ssl_library(void);
178static const char *curlhelp_get_ssl_library_string(curlhelp_ssl_library /*ssl_library*/); 181static const char *curlhelp_get_ssl_library_string(curlhelp_ssl_library /*ssl_library*/);
@@ -180,9 +183,12 @@ int net_noopenssl_check_certificate(cert_ptr_union *, int, int);
180 183
181static int curlhelp_parse_statusline(const char * /*buf*/, curlhelp_statusline * /*status_line*/); 184static int curlhelp_parse_statusline(const char * /*buf*/, curlhelp_statusline * /*status_line*/);
182static void curlhelp_free_statusline(curlhelp_statusline * /*status_line*/); 185static void curlhelp_free_statusline(curlhelp_statusline * /*status_line*/);
183static char *get_header_value(const struct phr_header *headers, size_t nof_headers, const char *header); 186static char *get_header_value(const struct phr_header *headers, size_t nof_headers,
184static int check_document_dates(const curlhelp_write_curlbuf * /*header_buf*/, char (*msg)[DEFAULT_BUFFER_SIZE], int /*maximum_age*/); 187 const char *header);
185static int get_content_length(const curlhelp_write_curlbuf *header_buf, const curlhelp_write_curlbuf *body_buf); 188static int check_document_dates(const curlhelp_write_curlbuf * /*header_buf*/,
189 char (*msg)[DEFAULT_BUFFER_SIZE], int /*maximum_age*/);
190static int get_content_length(const curlhelp_write_curlbuf *header_buf,
191 const curlhelp_write_curlbuf *body_buf);
186 192
187#if defined(HAVE_SSL) && defined(USE_OPENSSL) 193#if defined(HAVE_SSL) && defined(USE_OPENSSL)
188int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int days_till_exp_crit); 194int np_net_ssl_check_certificate(X509 *certificate, int days_till_exp_warn, int days_till_exp_crit);
@@ -208,14 +214,14 @@ int main(int argc, char **argv) {
208 214
209 /* set defaults */ 215 /* set defaults */
210 if (config.user_agent == NULL) { 216 if (config.user_agent == NULL) {
211 snprintf(config.user_agent, DEFAULT_BUFFER_SIZE, "%s/v%s (monitoring-plugins %s, %s)", progname, NP_VERSION, VERSION, 217 snprintf(config.user_agent, DEFAULT_BUFFER_SIZE, "%s/v%s (monitoring-plugins %s, %s)",
212 curl_version()); 218 progname, NP_VERSION, VERSION, curl_version());
213 } 219 }
214 220
215 if (config.display_html) { 221 if (config.display_html) {
216 printf("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", config.use_ssl ? "https" : "http", 222 printf("<A HREF=\"%s://%s:%d%s\" target=\"_blank\">", config.use_ssl ? "https" : "http",
217 config.host_name ? config.host_name : config.server_address, config.virtual_port ? config.virtual_port : config.server_port, 223 config.host_name ? config.host_name : config.server_address,
218 config.server_url); 224 config.virtual_port ? config.virtual_port : config.server_port, config.server_url);
219 } 225 }
220 226
221 exit(check_http(config)); 227 exit(check_http(config));
@@ -313,7 +319,8 @@ static int expected_statuscode(const char *reply, const char *statuscodes) {
313 319
314void handle_curl_option_return_code(CURLcode res, const char *option) { 320void handle_curl_option_return_code(CURLcode res, const char *option) {
315 if (res != CURLE_OK) { 321 if (res != CURLE_OK) {
316 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Error while setting cURL option '%s': cURL returned %d - %s"), option, res, 322 snprintf(msg, DEFAULT_BUFFER_SIZE,
323 _("Error while setting cURL option '%s': cURL returned %d - %s"), option, res,
317 curl_easy_strerror(res)); 324 curl_easy_strerror(res));
318 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 325 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
319 } 326 }
@@ -351,7 +358,8 @@ int lookup_host(const char *host, char *buf, size_t buflen) {
351 358
352 inet_ntop(res->ai_family, ptr, addrstr, 100); 359 inet_ntop(res->ai_family, ptr, addrstr, 100);
353 if (verbose >= 1) { 360 if (verbose >= 1) {
354 printf("* getaddrinfo IPv%d address: %s\n", res->ai_family == PF_INET6 ? 6 : 4, addrstr); 361 printf("* getaddrinfo IPv%d address: %s\n", res->ai_family == PF_INET6 ? 6 : 4,
362 addrstr);
355 } 363 }
356 364
357 // Append all IPs to buf as a comma-separated string 365 // Append all IPs to buf as a comma-separated string
@@ -416,17 +424,21 @@ mp_state_enum check_http(check_curl_config config) {
416 atexit(cleanup); 424 atexit(cleanup);
417 425
418 if (verbose >= 1) { 426 if (verbose >= 1) {
419 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_VERBOSE, 1), "CURLOPT_VERBOSE"); 427 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_VERBOSE, 1),
428 "CURLOPT_VERBOSE");
420 } 429 }
421 430
422 /* print everything on stdout like check_http would do */ 431 /* print everything on stdout like check_http would do */
423 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_STDERR, stdout), "CURLOPT_STDERR"); 432 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_STDERR, stdout),
433 "CURLOPT_STDERR");
424 434
425 if (config.automatic_decompression) 435 if (config.automatic_decompression)
426#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6) 436#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6)
427 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""), "CURLOPT_ACCEPT_ENCODING"); 437 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_ACCEPT_ENCODING, ""),
438 "CURLOPT_ACCEPT_ENCODING");
428#else 439#else
429 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_ENCODING, ""), "CURLOPT_ENCODING"); 440 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_ENCODING, ""),
441 "CURLOPT_ENCODING");
430#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6) */ 442#endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 21, 6) */
431 443
432 /* initialize buffer for body of the answer */ 444 /* initialize buffer for body of the answer */
@@ -434,44 +446,57 @@ mp_state_enum check_http(check_curl_config config) {
434 die(STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n"); 446 die(STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for body\n");
435 } 447 }
436 body_buf_initialized = true; 448 body_buf_initialized = true;
437 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), 449 handle_curl_option_return_code(
438 "CURLOPT_WRITEFUNCTION"); 450 curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION,
439 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&body_buf), "CURLOPT_WRITEDATA"); 451 (curl_write_callback)curlhelp_buffer_write_callback),
452 "CURLOPT_WRITEFUNCTION");
453 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&body_buf),
454 "CURLOPT_WRITEDATA");
440 455
441 /* initialize buffer for header of the answer */ 456 /* initialize buffer for header of the answer */
442 if (curlhelp_initwritebuffer(&header_buf) < 0) { 457 if (curlhelp_initwritebuffer(&header_buf) < 0) {
443 die(STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n"); 458 die(STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating buffer for header\n");
444 } 459 }
445 header_buf_initialized = true; 460 header_buf_initialized = true;
446 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, (curl_write_callback)curlhelp_buffer_write_callback), 461 handle_curl_option_return_code(
447 "CURLOPT_HEADERFUNCTION"); 462 curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION,
448 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *)&header_buf), "CURLOPT_WRITEHEADER"); 463 (curl_write_callback)curlhelp_buffer_write_callback),
464 "CURLOPT_HEADERFUNCTION");
465 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_WRITEHEADER, (void *)&header_buf),
466 "CURLOPT_WRITEHEADER");
449 467
450 /* set the error buffer */ 468 /* set the error buffer */
451 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf), "CURLOPT_ERRORBUFFER"); 469 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errbuf),
470 "CURLOPT_ERRORBUFFER");
452 471
453 /* set timeouts */ 472 /* set timeouts */
454 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, config.socket_timeout), "CURLOPT_CONNECTTIMEOUT"); 473 handle_curl_option_return_code(
455 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_TIMEOUT, config.socket_timeout), "CURLOPT_TIMEOUT"); 474 curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, config.socket_timeout),
475 "CURLOPT_CONNECTTIMEOUT");
476 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_TIMEOUT, config.socket_timeout),
477 "CURLOPT_TIMEOUT");
456 478
457 /* enable haproxy protocol */ 479 /* enable haproxy protocol */
458 if (config.haproxy_protocol) { 480 if (config.haproxy_protocol) {
459 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_HAPROXYPROTOCOL, 1L), "CURLOPT_HAPROXYPROTOCOL"); 481 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_HAPROXYPROTOCOL, 1L),
482 "CURLOPT_HAPROXYPROTOCOL");
460 } 483 }
461 484
462 // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we 485 // fill dns resolve cache to make curl connect to the given server_address instead of the
463 // use the host_name later on to make SNI happy 486 // host_name, only required for ssl, because we use the host_name later on to make SNI happy
464 struct curl_slist *host = NULL; 487 struct curl_slist *host = NULL;
465 char dnscache[DEFAULT_BUFFER_SIZE]; 488 char dnscache[DEFAULT_BUFFER_SIZE];
466 char addrstr[DEFAULT_BUFFER_SIZE / 2]; 489 char addrstr[DEFAULT_BUFFER_SIZE / 2];
467 if (config.use_ssl && config.host_name != NULL) { 490 if (config.use_ssl && config.host_name != NULL) {
468 CURLcode res; 491 CURLcode res;
469 if ((res = lookup_host(config.server_address, addrstr, DEFAULT_BUFFER_SIZE / 2)) != 0) { 492 if ((res = lookup_host(config.server_address, addrstr, DEFAULT_BUFFER_SIZE / 2)) != 0) {
470 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"), 493 snprintf(msg, DEFAULT_BUFFER_SIZE,
494 _("Unable to lookup IP address for '%s': getaddrinfo returned %d - %s"),
471 config.server_address, res, gai_strerror(res)); 495 config.server_address, res, gai_strerror(res));
472 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 496 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
473 } 497 }
474 snprintf(dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", config.host_name, config.server_port, addrstr); 498 snprintf(dnscache, DEFAULT_BUFFER_SIZE, "%s:%d:%s", config.host_name, config.server_port,
499 addrstr);
475 host = curl_slist_append(NULL, dnscache); 500 host = curl_slist_append(NULL, dnscache);
476 curl_easy_setopt(curl, CURLOPT_RESOLVE, host); 501 curl_easy_setopt(curl, CURLOPT_RESOLVE, host);
477 if (verbose >= 1) { 502 if (verbose >= 1) {
@@ -486,7 +511,8 @@ mp_state_enum check_http(check_curl_config config) {
486 if (new_server_address == NULL) { 511 if (new_server_address == NULL) {
487 die(STATE_UNKNOWN, "HTTP UNKNOWN - Unable to allocate memory\n"); 512 die(STATE_UNKNOWN, "HTTP UNKNOWN - Unable to allocate memory\n");
488 } 513 }
489 snprintf(new_server_address, strlen(config.server_address) + 3, "[%s]", config.server_address); 514 snprintf(new_server_address, strlen(config.server_address) + 3, "[%s]",
515 config.server_address);
490 free(config.server_address); 516 free(config.server_address);
491 config.server_address = new_server_address; 517 config.server_address = new_server_address;
492 } 518 }
@@ -494,8 +520,9 @@ mp_state_enum check_http(check_curl_config config) {
494 /* compose URL: use the address we want to connect to, set Host: header later */ 520 /* compose URL: use the address we want to connect to, set Host: header later */
495 char url[DEFAULT_BUFFER_SIZE]; 521 char url[DEFAULT_BUFFER_SIZE];
496 snprintf(url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", config.use_ssl ? "https" : "http", 522 snprintf(url, DEFAULT_BUFFER_SIZE, "%s://%s:%d%s", config.use_ssl ? "https" : "http",
497 (config.use_ssl & (config.host_name != NULL)) ? config.host_name : config.server_address, config.server_port, 523 (config.use_ssl & (config.host_name != NULL)) ? config.host_name
498 config.server_url); 524 : config.server_address,
525 config.server_port, config.server_url);
499 526
500 if (verbose >= 1) { 527 if (verbose >= 1) {
501 printf("* curl CURLOPT_URL: %s\n", url); 528 printf("* curl CURLOPT_URL: %s\n", url);
@@ -503,14 +530,19 @@ mp_state_enum check_http(check_curl_config config) {
503 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_URL, url), "CURLOPT_URL"); 530 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_URL, url), "CURLOPT_URL");
504 531
505 /* extract proxy information for legacy proxy https requests */ 532 /* extract proxy information for legacy proxy https requests */
506 if (!strcmp(config.http_method, "CONNECT") || strstr(config.server_url, "http") == config.server_url) { 533 if (!strcmp(config.http_method, "CONNECT") ||
507 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_PROXY, config.server_address), "CURLOPT_PROXY"); 534 strstr(config.server_url, "http") == config.server_url) {
508 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_PROXYPORT, (long)config.server_port), "CURLOPT_PROXYPORT"); 535 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_PROXY, config.server_address),
536 "CURLOPT_PROXY");
537 handle_curl_option_return_code(
538 curl_easy_setopt(curl, CURLOPT_PROXYPORT, (long)config.server_port),
539 "CURLOPT_PROXYPORT");
509 if (verbose >= 2) { 540 if (verbose >= 2) {
510 printf("* curl CURLOPT_PROXY: %s:%d\n", config.server_address, config.server_port); 541 printf("* curl CURLOPT_PROXY: %s:%d\n", config.server_address, config.server_port);
511 } 542 }
512 config.http_method = "GET"; 543 config.http_method = "GET";
513 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_URL, config.server_url), "CURLOPT_URL"); 544 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_URL, config.server_url),
545 "CURLOPT_URL");
514 } 546 }
515 547
516 /* disable body for HEAD request */ 548 /* disable body for HEAD request */
@@ -519,16 +551,21 @@ mp_state_enum check_http(check_curl_config config) {
519 } 551 }
520 552
521 /* set HTTP protocol version */ 553 /* set HTTP protocol version */
522 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, config.curl_http_version), "CURLOPT_HTTP_VERSION"); 554 handle_curl_option_return_code(
555 curl_easy_setopt(curl, CURLOPT_HTTP_VERSION, config.curl_http_version),
556 "CURLOPT_HTTP_VERSION");
523 557
524 /* set HTTP method */ 558 /* set HTTP method */
525 if (config.http_method) { 559 if (config.http_method) {
526 if (!strcmp(config.http_method, "POST")) { 560 if (!strcmp(config.http_method, "POST")) {
527 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_POST, 1), "CURLOPT_POST"); 561 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_POST, 1), "CURLOPT_POST");
528 } else if (!strcmp(config.http_method, "PUT")) { 562 } else if (!strcmp(config.http_method, "PUT")) {
529 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_UPLOAD, 1), "CURLOPT_UPLOAD"); 563 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_UPLOAD, 1),
564 "CURLOPT_UPLOAD");
530 } else { 565 } else {
531 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, config.http_method), "CURLOPT_CUSTOMREQUEST"); 566 handle_curl_option_return_code(
567 curl_easy_setopt(curl, CURLOPT_CUSTOMREQUEST, config.http_method),
568 "CURLOPT_CUSTOMREQUEST");
532 } 569 }
533 } 570 }
534 571
@@ -545,8 +582,10 @@ mp_state_enum check_http(check_curl_config config) {
545 /* set hostname (virtual hosts), not needed if CURLOPT_CONNECT_TO is used, but left in anyway */ 582 /* set hostname (virtual hosts), not needed if CURLOPT_CONNECT_TO is used, but left in anyway */
546 char http_header[DEFAULT_BUFFER_SIZE]; 583 char http_header[DEFAULT_BUFFER_SIZE];
547 if (config.host_name != NULL && force_host_header == NULL) { 584 if (config.host_name != NULL && force_host_header == NULL) {
548 if ((config.virtual_port != HTTP_PORT && !config.use_ssl) || (config.virtual_port != HTTPS_PORT && config.use_ssl)) { 585 if ((config.virtual_port != HTTP_PORT && !config.use_ssl) ||
549 snprintf(http_header, DEFAULT_BUFFER_SIZE, "Host: %s:%d", config.host_name, config.virtual_port); 586 (config.virtual_port != HTTPS_PORT && config.use_ssl)) {
587 snprintf(http_header, DEFAULT_BUFFER_SIZE, "Host: %s:%d", config.host_name,
588 config.virtual_port);
550 } else { 589 } else {
551 snprintf(http_header, DEFAULT_BUFFER_SIZE, "Host: %s", config.host_name); 590 snprintf(http_header, DEFAULT_BUFFER_SIZE, "Host: %s", config.host_name);
552 } 591 }
@@ -563,43 +602,53 @@ mp_state_enum check_http(check_curl_config config) {
563 for (int i = 0; i < config.http_opt_headers_count; i++) { 602 for (int i = 0; i < config.http_opt_headers_count; i++) {
564 header_list = curl_slist_append(header_list, config.http_opt_headers[i]); 603 header_list = curl_slist_append(header_list, config.http_opt_headers[i]);
565 } 604 }
566 /* This cannot be free'd here because a redirection will then try to access this and segfault */ 605 /* This cannot be free'd here because a redirection will then try to access this and
606 * segfault */
567 /* Covered in a testcase in tests/check_http.t */ 607 /* Covered in a testcase in tests/check_http.t */
568 /* free(http_opt_headers); */ 608 /* free(http_opt_headers); */
569 } 609 }
570 610
571 /* set HTTP headers */ 611 /* set HTTP headers */
572 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list), "CURLOPT_HTTPHEADER"); 612 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header_list),
613 "CURLOPT_HTTPHEADER");
573 614
574#ifdef LIBCURL_FEATURE_SSL 615#ifdef LIBCURL_FEATURE_SSL
575 616
576 /* set SSL version, warn about insecure or unsupported versions */ 617 /* set SSL version, warn about insecure or unsupported versions */
577 if (config.use_ssl) { 618 if (config.use_ssl) {
578 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSLVERSION, config.ssl_version), "CURLOPT_SSLVERSION"); 619 handle_curl_option_return_code(
620 curl_easy_setopt(curl, CURLOPT_SSLVERSION, config.ssl_version), "CURLOPT_SSLVERSION");
579 } 621 }
580 622
581 /* client certificate and key to present to server (SSL) */ 623 /* client certificate and key to present to server (SSL) */
582 if (config.client_cert) { 624 if (config.client_cert) {
583 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSLCERT, config.client_cert), "CURLOPT_SSLCERT"); 625 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSLCERT, config.client_cert),
626 "CURLOPT_SSLCERT");
584 } 627 }
585 if (config.client_privkey) { 628 if (config.client_privkey) {
586 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSLKEY, config.client_privkey), "CURLOPT_SSLKEY"); 629 handle_curl_option_return_code(
630 curl_easy_setopt(curl, CURLOPT_SSLKEY, config.client_privkey), "CURLOPT_SSLKEY");
587 } 631 }
588 if (config.ca_cert) { 632 if (config.ca_cert) {
589 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CAINFO, config.ca_cert), "CURLOPT_CAINFO"); 633 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CAINFO, config.ca_cert),
634 "CURLOPT_CAINFO");
590 } 635 }
591 if (config.ca_cert || config.verify_peer_and_host) { 636 if (config.ca_cert || config.verify_peer_and_host) {
592 /* per default if we have a CA verify both the peer and the 637 /* per default if we have a CA verify both the peer and the
593 * hostname in the certificate, can be switched off later */ 638 * hostname in the certificate, can be switched off later */
594 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1), "CURLOPT_SSL_VERIFYPEER"); 639 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 1),
595 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2), "CURLOPT_SSL_VERIFYHOST"); 640 "CURLOPT_SSL_VERIFYPEER");
641 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 2),
642 "CURLOPT_SSL_VERIFYHOST");
596 } else { 643 } else {
597 /* backward-compatible behaviour, be tolerant in checks 644 /* backward-compatible behaviour, be tolerant in checks
598 * TODO: depending on more options have aspects we want 645 * TODO: depending on more options have aspects we want
599 * to be less tolerant about ssl verfications 646 * to be less tolerant about ssl verfications
600 */ 647 */
601 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0), "CURLOPT_SSL_VERIFYPEER"); 648 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0),
602 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0), "CURLOPT_SSL_VERIFYHOST"); 649 "CURLOPT_SSL_VERIFYPEER");
650 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0),
651 "CURLOPT_SSL_VERIFYHOST");
603 } 652 }
604 653
605 /* detect SSL library used by libcurl */ 654 /* detect SSL library used by libcurl */
@@ -621,15 +670,19 @@ mp_state_enum check_http(check_curl_config config) {
621# endif /* USE_OPENSSL */ 670# endif /* USE_OPENSSL */
622 /* libcurl is built with OpenSSL, monitoring plugins, so falling 671 /* libcurl is built with OpenSSL, monitoring plugins, so falling
623 * back to manually extracting certificate information */ 672 * back to manually extracting certificate information */
624 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L), "CURLOPT_CERTINFO"); 673 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L),
674 "CURLOPT_CERTINFO");
625 break; 675 break;
626 676
627 case CURLHELP_SSL_LIBRARY_NSS: 677 case CURLHELP_SSL_LIBRARY_NSS:
628# if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) 678# if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0)
629 /* NSS: support for CERTINFO is implemented since 7.34.0 */ 679 /* NSS: support for CERTINFO is implemented since 7.34.0 */
630 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L), "CURLOPT_CERTINFO"); 680 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L),
681 "CURLOPT_CERTINFO");
631# else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ 682# else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */
632 die(STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library '%s' is too old)\n", 683 die(STATE_CRITICAL,
684 "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library "
685 "'%s' is too old)\n",
633 curlhelp_get_ssl_library_string(ssl_library)); 686 curlhelp_get_ssl_library_string(ssl_library));
634# endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */ 687# endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 34, 0) */
635 break; 688 break;
@@ -637,50 +690,63 @@ mp_state_enum check_http(check_curl_config config) {
637 case CURLHELP_SSL_LIBRARY_GNUTLS: 690 case CURLHELP_SSL_LIBRARY_GNUTLS:
638# if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) 691# if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0)
639 /* GnuTLS: support for CERTINFO is implemented since 7.42.0 */ 692 /* GnuTLS: support for CERTINFO is implemented since 7.42.0 */
640 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L), "CURLOPT_CERTINFO"); 693 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_CERTINFO, 1L),
694 "CURLOPT_CERTINFO");
641# else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) */ 695# else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) */
642 die(STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library '%s' is too old)\n", 696 die(STATE_CRITICAL,
697 "HTTP CRITICAL - Cannot retrieve certificates (libcurl linked with SSL library "
698 "'%s' is too old)\n",
643 curlhelp_get_ssl_library_string(ssl_library)); 699 curlhelp_get_ssl_library_string(ssl_library));
644# endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) */ 700# endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 42, 0) */
645 break; 701 break;
646 702
647 case CURLHELP_SSL_LIBRARY_UNKNOWN: 703 case CURLHELP_SSL_LIBRARY_UNKNOWN:
648 default: 704 default:
649 die(STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (unknown SSL library '%s', must implement first)\n", 705 die(STATE_CRITICAL,
706 "HTTP CRITICAL - Cannot retrieve certificates (unknown SSL library '%s', must "
707 "implement first)\n",
650 curlhelp_get_ssl_library_string(ssl_library)); 708 curlhelp_get_ssl_library_string(ssl_library));
651 break; 709 break;
652 } 710 }
653# else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ 711# else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */
654 /* old libcurl, our only hope is OpenSSL, otherwise we are out of luck */ 712 /* old libcurl, our only hope is OpenSSL, otherwise we are out of luck */
655 if (ssl_library == CURLHELP_SSL_LIBRARY_OPENSSL || ssl_library == CURLHELP_SSL_LIBRARY_LIBRESSL) { 713 if (ssl_library == CURLHELP_SSL_LIBRARY_OPENSSL ||
714 ssl_library == CURLHELP_SSL_LIBRARY_LIBRESSL) {
656 add_sslctx_verify_fun = true; 715 add_sslctx_verify_fun = true;
657 } else { 716 } else {
658 die(STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (no CURLOPT_SSL_CTX_FUNCTION, no OpenSSL library or libcurl " 717 die(STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (no "
718 "CURLOPT_SSL_CTX_FUNCTION, no OpenSSL library or libcurl "
659 "too old and has no CURLOPT_CERTINFO)\n"); 719 "too old and has no CURLOPT_CERTINFO)\n");
660 } 720 }
661# endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ 721# endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */
662 } 722 }
663 723
664# if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 10, 6) /* required for CURLOPT_SSL_CTX_FUNCTION */ 724# if LIBCURL_VERSION_NUM >= \
725 MAKE_LIBCURL_VERSION(7, 10, 6) /* required for CURLOPT_SSL_CTX_FUNCTION */
665 // ssl ctx function is not available with all ssl backends 726 // ssl ctx function is not available with all ssl backends
666 if (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, NULL) != CURLE_UNKNOWN_OPTION) { 727 if (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, NULL) != CURLE_UNKNOWN_OPTION) {
667 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION"); 728 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun),
729 "CURLOPT_SSL_CTX_FUNCTION");
668 } 730 }
669# endif 731# endif
670 732
671#endif /* LIBCURL_FEATURE_SSL */ 733#endif /* LIBCURL_FEATURE_SSL */
672 734
673 /* set default or user-given user agent identification */ 735 /* set default or user-given user agent identification */
674 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_USERAGENT, config.user_agent), "CURLOPT_USERAGENT"); 736 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_USERAGENT, config.user_agent),
737 "CURLOPT_USERAGENT");
675 738
676 /* proxy-authentication */ 739 /* proxy-authentication */
677 if (strcmp(config.proxy_auth, "")) { 740 if (strcmp(config.proxy_auth, "")) {
678 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, config.proxy_auth), "CURLOPT_PROXYUSERPWD"); 741 handle_curl_option_return_code(
742 curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, config.proxy_auth),
743 "CURLOPT_PROXYUSERPWD");
679 } 744 }
680 745
681 /* authentication */ 746 /* authentication */
682 if (strcmp(config.user_auth, "")) { 747 if (strcmp(config.user_auth, "")) {
683 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_USERPWD, config.user_auth), "CURLOPT_USERPWD"); 748 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_USERPWD, config.user_auth),
749 "CURLOPT_USERPWD");
684 } 750 }
685 751
686 /* TODO: parameter auth method, bitfield of following methods: 752 /* TODO: parameter auth method, bitfield of following methods:
@@ -695,26 +761,32 @@ mp_state_enum check_http(check_curl_config config) {
695 * CURLAUTH_ANYSAFE: most secure, without BASIC 761 * CURLAUTH_ANYSAFE: most secure, without BASIC
696 * or CURLAUTH_ANY: most secure, even BASIC if necessary 762 * or CURLAUTH_ANY: most secure, even BASIC if necessary
697 * 763 *
698 * handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_HTTPAUTH, (long)CURLAUTH_DIGEST ), "CURLOPT_HTTPAUTH"); 764 * handle_curl_option_return_code (curl_easy_setopt( curl, CURLOPT_HTTPAUTH,
765 * (long)CURLAUTH_DIGEST ), "CURLOPT_HTTPAUTH");
699 */ 766 */
700 767
701 /* handle redirections */ 768 /* handle redirections */
702 if (config.onredirect == STATE_DEPENDENT) { 769 if (config.onredirect == STATE_DEPENDENT) {
703 if (config.followmethod == FOLLOW_LIBCURL) { 770 if (config.followmethod == FOLLOW_LIBCURL) {
704 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1), "CURLOPT_FOLLOWLOCATION"); 771 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1),
772 "CURLOPT_FOLLOWLOCATION");
705 773
706 /* default -1 is infinite, not good, could lead to zombie plugins! 774 /* default -1 is infinite, not good, could lead to zombie plugins!
707 Setting it to one bigger than maximal limit to handle errors nicely below 775 Setting it to one bigger than maximal limit to handle errors nicely below
708 */ 776 */
709 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_MAXREDIRS, config.max_depth + 1), "CURLOPT_MAXREDIRS"); 777 handle_curl_option_return_code(
778 curl_easy_setopt(curl, CURLOPT_MAXREDIRS, config.max_depth + 1),
779 "CURLOPT_MAXREDIRS");
710 780
711 /* for now allow only http and https (we are a http(s) check plugin in the end) */ 781 /* for now allow only http and https (we are a http(s) check plugin in the end) */
712#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 85, 0) 782#if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 85, 0)
713 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"), 783 handle_curl_option_return_code(
714 "CURLOPT_REDIR_PROTOCOLS_STR"); 784 curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"),
785 "CURLOPT_REDIR_PROTOCOLS_STR");
715#elif LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4) 786#elif LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 4)
716 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS), 787 handle_curl_option_return_code(
717 "CURLOPT_REDIRECT_PROTOCOLS"); 788 curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS),
789 "CURLOPT_REDIRECT_PROTOCOLS");
718#endif 790#endif
719 791
720 /* TODO: handle the following aspects of redirection, make them 792 /* TODO: handle the following aspects of redirection, make them
@@ -722,7 +794,8 @@ mp_state_enum check_http(check_curl_config config) {
722 CURLOPT_POSTREDIR: method switch 794 CURLOPT_POSTREDIR: method switch
723 CURLINFO_REDIRECT_URL: custom redirect option 795 CURLINFO_REDIRECT_URL: custom redirect option
724 CURLOPT_REDIRECT_PROTOCOLS: allow people to step outside safe protocols 796 CURLOPT_REDIRECT_PROTOCOLS: allow people to step outside safe protocols
725 CURLINFO_REDIRECT_COUNT: get the number of redirects, print it, maybe a range option here is nice like for expected page size? 797 CURLINFO_REDIRECT_COUNT: get the number of redirects, print it, maybe a range option
798 here is nice like for expected page size?
726 */ 799 */
727 } else { 800 } else {
728 /* old style redirection is handled below */ 801 /* old style redirection is handled below */
@@ -736,8 +809,9 @@ mp_state_enum check_http(check_curl_config config) {
736 809
737 /* IPv4 or IPv6 forced DNS resolution */ 810 /* IPv4 or IPv6 forced DNS resolution */
738 if (address_family == AF_UNSPEC) { 811 if (address_family == AF_UNSPEC) {
739 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER), 812 handle_curl_option_return_code(
740 "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_WHATEVER)"); 813 curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_WHATEVER),
814 "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_WHATEVER)");
741 } else if (address_family == AF_INET) { 815 } else if (address_family == AF_INET) {
742 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4), 816 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4),
743 "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_V4)"); 817 "CURLOPT_IPRESOLVE(CURL_IPRESOLVE_V4)");
@@ -753,7 +827,8 @@ mp_state_enum check_http(check_curl_config config) {
753 if (!strcmp(config.http_method, "POST") || !strcmp(config.http_method, "PUT")) { 827 if (!strcmp(config.http_method, "POST") || !strcmp(config.http_method, "PUT")) {
754 /* set content of payload for POST and PUT */ 828 /* set content of payload for POST and PUT */
755 if (config.http_content_type) { 829 if (config.http_content_type) {
756 snprintf(http_header, DEFAULT_BUFFER_SIZE, "Content-Type: %s", config.http_content_type); 830 snprintf(http_header, DEFAULT_BUFFER_SIZE, "Content-Type: %s",
831 config.http_content_type);
757 header_list = curl_slist_append(header_list, http_header); 832 header_list = curl_slist_append(header_list, http_header);
758 } 833 }
759 /* NULL indicates "HTTP Continue" in libcurl, provide an empty string 834 /* NULL indicates "HTTP Continue" in libcurl, provide an empty string
@@ -763,27 +838,42 @@ mp_state_enum check_http(check_curl_config config) {
763 } 838 }
764 if (!strcmp(config.http_method, "POST")) { 839 if (!strcmp(config.http_method, "POST")) {
765 /* POST method, set payload with CURLOPT_POSTFIELDS */ 840 /* POST method, set payload with CURLOPT_POSTFIELDS */
766 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_POSTFIELDS, config.http_post_data), "CURLOPT_POSTFIELDS"); 841 handle_curl_option_return_code(
842 curl_easy_setopt(curl, CURLOPT_POSTFIELDS, config.http_post_data),
843 "CURLOPT_POSTFIELDS");
767 } else if (!strcmp(config.http_method, "PUT")) { 844 } else if (!strcmp(config.http_method, "PUT")) {
768 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_READFUNCTION, (curl_read_callback)curlhelp_buffer_read_callback), 845 handle_curl_option_return_code(
769 "CURLOPT_READFUNCTION"); 846 curl_easy_setopt(curl, CURLOPT_READFUNCTION,
770 if (curlhelp_initreadbuffer(&put_buf, config.http_post_data, strlen(config.http_post_data)) < 0) { 847 (curl_read_callback)curlhelp_buffer_read_callback),
771 die(STATE_UNKNOWN, "HTTP CRITICAL - out of memory allocating read buffer for PUT\n"); 848 "CURLOPT_READFUNCTION");
849 if (curlhelp_initreadbuffer(&put_buf, config.http_post_data,
850 strlen(config.http_post_data)) < 0) {
851 die(STATE_UNKNOWN,
852 "HTTP CRITICAL - out of memory allocating read buffer for PUT\n");
772 } 853 }
773 put_buf_initialized = true; 854 put_buf_initialized = true;
774 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_READDATA, (void *)&put_buf), "CURLOPT_READDATA"); 855 handle_curl_option_return_code(
775 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_INFILESIZE, (curl_off_t)strlen(config.http_post_data)), 856 curl_easy_setopt(curl, CURLOPT_READDATA, (void *)&put_buf), "CURLOPT_READDATA");
776 "CURLOPT_INFILESIZE"); 857 handle_curl_option_return_code(
858 curl_easy_setopt(curl, CURLOPT_INFILESIZE,
859 (curl_off_t)strlen(config.http_post_data)),
860 "CURLOPT_INFILESIZE");
777 } 861 }
778 } 862 }
779 863
780 /* cookie handling */ 864 /* cookie handling */
781 if (config.cookie_jar_file != NULL) { 865 if (config.cookie_jar_file != NULL) {
782 /* enable reading cookies from a file, and if the filename is an empty string, only enable the curl cookie engine */ 866 /* enable reading cookies from a file, and if the filename is an empty string, only enable
783 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_COOKIEFILE, config.cookie_jar_file), "CURLOPT_COOKIEFILE"); 867 * the curl cookie engine */
784 /* now enable saving cookies to a file, but only if the filename is not an empty string, since writing it would fail */ 868 handle_curl_option_return_code(
869 curl_easy_setopt(curl, CURLOPT_COOKIEFILE, config.cookie_jar_file),
870 "CURLOPT_COOKIEFILE");
871 /* now enable saving cookies to a file, but only if the filename is not an empty string,
872 * since writing it would fail */
785 if (*config.cookie_jar_file) { 873 if (*config.cookie_jar_file) {
786 handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_COOKIEJAR, config.cookie_jar_file), "CURLOPT_COOKIEJAR"); 874 handle_curl_option_return_code(
875 curl_easy_setopt(curl, CURLOPT_COOKIEJAR, config.cookie_jar_file),
876 "CURLOPT_COOKIEJAR");
787 } 877 }
788 } 878 }
789 879
@@ -806,7 +896,8 @@ mp_state_enum check_http(check_curl_config config) {
806 896
807 /* Curl errors, result in critical Nagios state */ 897 /* Curl errors, result in critical Nagios state */
808 if (res != CURLE_OK) { 898 if (res != CURLE_OK) {
809 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: cURL returned %d - %s"), 899 snprintf(msg, DEFAULT_BUFFER_SIZE,
900 _("Invalid HTTP response received from host on port %d: cURL returned %d - %s"),
810 config.server_port, res, errbuf[0] ? errbuf : curl_easy_strerror(res)); 901 config.server_port, res, errbuf[0] ? errbuf : curl_easy_strerror(res));
811 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 902 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
812 } 903 }
@@ -821,13 +912,14 @@ mp_state_enum check_http(check_curl_config config) {
821 /* check certificate with OpenSSL functions, curl has been built against OpenSSL 912 /* check certificate with OpenSSL functions, curl has been built against OpenSSL
822 * and we actually have OpenSSL in the monitoring tools 913 * and we actually have OpenSSL in the monitoring tools
823 */ 914 */
824 result_ssl = np_net_ssl_check_certificate(cert, config.days_till_exp_warn, config.days_till_exp_crit); 915 result_ssl = np_net_ssl_check_certificate(cert, config.days_till_exp_warn,
916 config.days_till_exp_crit);
825 if (!config.continue_after_check_cert) { 917 if (!config.continue_after_check_cert) {
826 return result_ssl; 918 return result_ssl;
827 } 919 }
828# else /* USE_OPENSSL */ 920# else /* USE_OPENSSL */
829 die(STATE_CRITICAL, 921 die(STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL "
830 "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n"); 922 "callback used and not linked against OpenSSL\n");
831# endif /* USE_OPENSSL */ 923# endif /* USE_OPENSSL */
832 } else { 924 } else {
833 struct curl_slist *slist; 925 struct curl_slist *slist;
@@ -841,7 +933,8 @@ mp_state_enum check_http(check_curl_config config) {
841 */ 933 */
842 const char *raw_cert = NULL; 934 const char *raw_cert = NULL;
843 for (int i = 0; i < cert_ptr.to_certinfo->num_of_certs; i++) { 935 for (int i = 0; i < cert_ptr.to_certinfo->num_of_certs; i++) {
844 for (slist = cert_ptr.to_certinfo->certinfo[i]; slist; slist = slist->next) { 936 for (slist = cert_ptr.to_certinfo->certinfo[i]; slist;
937 slist = slist->next) {
845 if (verbose >= 2) { 938 if (verbose >= 2) {
846 printf("%d ** %s\n", i, slist->data); 939 printf("%d ** %s\n", i, slist->data);
847 } 940 }
@@ -854,32 +947,38 @@ mp_state_enum check_http(check_curl_config config) {
854 GOT_FIRST_CERT: 947 GOT_FIRST_CERT:
855 if (!raw_cert) { 948 if (!raw_cert) {
856 snprintf(msg, DEFAULT_BUFFER_SIZE, 949 snprintf(msg, DEFAULT_BUFFER_SIZE,
857 _("Cannot retrieve certificates from CERTINFO information - certificate data was empty")); 950 _("Cannot retrieve certificates from CERTINFO information - "
951 "certificate data was empty"));
858 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 952 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
859 } 953 }
860 BIO *cert_BIO = BIO_new(BIO_s_mem()); 954 BIO *cert_BIO = BIO_new(BIO_s_mem());
861 BIO_write(cert_BIO, raw_cert, strlen(raw_cert)); 955 BIO_write(cert_BIO, raw_cert, strlen(raw_cert));
862 cert = PEM_read_bio_X509(cert_BIO, NULL, NULL, NULL); 956 cert = PEM_read_bio_X509(cert_BIO, NULL, NULL, NULL);
863 if (!cert) { 957 if (!cert) {
864 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Cannot read certificate from CERTINFO information - BIO error")); 958 snprintf(
959 msg, DEFAULT_BUFFER_SIZE,
960 _("Cannot read certificate from CERTINFO information - BIO error"));
865 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 961 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
866 } 962 }
867 BIO_free(cert_BIO); 963 BIO_free(cert_BIO);
868 result_ssl = np_net_ssl_check_certificate(cert, config.days_till_exp_warn, config.days_till_exp_crit); 964 result_ssl = np_net_ssl_check_certificate(cert, config.days_till_exp_warn,
965 config.days_till_exp_crit);
869 if (!config.continue_after_check_cert) { 966 if (!config.continue_after_check_cert) {
870 return result_ssl; 967 return result_ssl;
871 } 968 }
872# else /* USE_OPENSSL */ 969# else /* USE_OPENSSL */
873 /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal, 970 /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our
874 * so we use the libcurl CURLINFO data 971 * disposal, so we use the libcurl CURLINFO data
875 */ 972 */
876 result_ssl = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit); 973 result_ssl = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn,
974 days_till_exp_crit);
877 if (!continue_after_check_cert) { 975 if (!continue_after_check_cert) {
878 return result_ssl; 976 return result_ssl;
879 } 977 }
880# endif /* USE_OPENSSL */ 978# endif /* USE_OPENSSL */
881 } else { 979 } else {
882 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Cannot retrieve certificates - cURL returned %d - %s"), res, 980 snprintf(msg, DEFAULT_BUFFER_SIZE,
981 _("Cannot retrieve certificates - cURL returned %d - %s"), res,
883 curl_easy_strerror(res)); 982 curl_easy_strerror(res));
884 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); 983 die(STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg);
885 } 984 }
@@ -892,28 +991,40 @@ mp_state_enum check_http(check_curl_config config) {
892 * performance data to the answer always 991 * performance data to the answer always
893 */ 992 */
894 double total_time; 993 double total_time;
895 handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time), "CURLINFO_TOTAL_TIME"); 994 handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_TOTAL_TIME, &total_time),
995 "CURLINFO_TOTAL_TIME");
896 int page_len = get_content_length(&header_buf, &body_buf); 996 int page_len = get_content_length(&header_buf, &body_buf);
897 char perfstring[DEFAULT_BUFFER_SIZE]; 997 char perfstring[DEFAULT_BUFFER_SIZE];
898 if (config.show_extended_perfdata) { 998 if (config.show_extended_perfdata) {
899 double time_connect; 999 double time_connect;
900 handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &time_connect), "CURLINFO_CONNECT_TIME"); 1000 handle_curl_option_return_code(
1001 curl_easy_getinfo(curl, CURLINFO_CONNECT_TIME, &time_connect), "CURLINFO_CONNECT_TIME");
901 double time_appconnect; 1002 double time_appconnect;
902 handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_APPCONNECT_TIME, &time_appconnect), "CURLINFO_APPCONNECT_TIME"); 1003 handle_curl_option_return_code(
1004 curl_easy_getinfo(curl, CURLINFO_APPCONNECT_TIME, &time_appconnect),
1005 "CURLINFO_APPCONNECT_TIME");
903 double time_headers; 1006 double time_headers;
904 handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME, &time_headers), "CURLINFO_PRETRANSFER_TIME"); 1007 handle_curl_option_return_code(
1008 curl_easy_getinfo(curl, CURLINFO_PRETRANSFER_TIME, &time_headers),
1009 "CURLINFO_PRETRANSFER_TIME");
905 double time_firstbyte; 1010 double time_firstbyte;
906 handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME, &time_firstbyte), 1011 handle_curl_option_return_code(
907 "CURLINFO_STARTTRANSFER_TIME"); 1012 curl_easy_getinfo(curl, CURLINFO_STARTTRANSFER_TIME, &time_firstbyte),
908 1013 "CURLINFO_STARTTRANSFER_TIME");
909 snprintf(perfstring, DEFAULT_BUFFER_SIZE, "%s %s %s %s %s %s %s", perfd_time(total_time, config.thlds, config.socket_timeout), 1014
910 perfd_size(page_len, config.min_page_len), perfd_time_connect(time_connect, config.socket_timeout), 1015 snprintf(perfstring, DEFAULT_BUFFER_SIZE, "%s %s %s %s %s %s %s",
911 config.use_ssl ? perfd_time_ssl(time_appconnect - time_connect, config.socket_timeout) : "", 1016 perfd_time(total_time, config.thlds, config.socket_timeout),
1017 perfd_size(page_len, config.min_page_len),
1018 perfd_time_connect(time_connect, config.socket_timeout),
1019 config.use_ssl
1020 ? perfd_time_ssl(time_appconnect - time_connect, config.socket_timeout)
1021 : "",
912 perfd_time_headers(time_headers - time_appconnect, config.socket_timeout), 1022 perfd_time_headers(time_headers - time_appconnect, config.socket_timeout),
913 perfd_time_firstbyte(time_firstbyte - time_headers, config.socket_timeout), 1023 perfd_time_firstbyte(time_firstbyte - time_headers, config.socket_timeout),
914 perfd_time_transfer(total_time - time_firstbyte, config.socket_timeout)); 1024 perfd_time_transfer(total_time - time_firstbyte, config.socket_timeout));
915 } else { 1025 } else {
916 snprintf(perfstring, DEFAULT_BUFFER_SIZE, "%s %s", perfd_time(total_time, config.thlds, config.socket_timeout), 1026 snprintf(perfstring, DEFAULT_BUFFER_SIZE, "%s %s",
1027 perfd_time(total_time, config.thlds, config.socket_timeout),
917 perfd_size(page_len, config.min_page_len)); 1028 perfd_size(page_len, config.min_page_len));
918 } 1029 }
919 1030
@@ -924,37 +1035,45 @@ mp_state_enum check_http(check_curl_config config) {
924 1035
925 /* get status line of answer, check sanity of HTTP code */ 1036 /* get status line of answer, check sanity of HTTP code */
926 if (curlhelp_parse_statusline(header_buf.buf, &status_line) < 0) { 1037 if (curlhelp_parse_statusline(header_buf.buf, &status_line) < 0) {
927 snprintf(msg, DEFAULT_BUFFER_SIZE, "Unparsable status line in %.3g seconds response time|%s\n", total_time, perfstring); 1038 snprintf(msg, DEFAULT_BUFFER_SIZE,
1039 "Unparsable status line in %.3g seconds response time|%s\n", total_time,
1040 perfstring);
928 /* we cannot know the major/minor version here for sure as we cannot parse the first line */ 1041 /* we cannot know the major/minor version here for sure as we cannot parse the first line */
929 die(STATE_CRITICAL, "HTTP CRITICAL HTTP/x.x %ld unknown - %s", code, msg); 1042 die(STATE_CRITICAL, "HTTP CRITICAL HTTP/x.x %ld unknown - %s", code, msg);
930 } 1043 }
931 status_line_initialized = true; 1044 status_line_initialized = true;
932 1045
933 /* get result code from cURL */ 1046 /* get result code from cURL */
934 handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code), "CURLINFO_RESPONSE_CODE"); 1047 handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &code),
1048 "CURLINFO_RESPONSE_CODE");
935 if (verbose >= 2) { 1049 if (verbose >= 2) {
936 printf("* curl CURLINFO_RESPONSE_CODE is %ld\n", code); 1050 printf("* curl CURLINFO_RESPONSE_CODE is %ld\n", code);
937 } 1051 }
938 1052
939 /* print status line, header, body if verbose */ 1053 /* print status line, header, body if verbose */
940 if (verbose >= 2) { 1054 if (verbose >= 2) {
941 printf("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header_buf.buf, (config.no_body ? " [[ skipped ]]" : body_buf.buf)); 1055 printf("**** HEADER ****\n%s\n**** CONTENT ****\n%s\n", header_buf.buf,
1056 (config.no_body ? " [[ skipped ]]" : body_buf.buf));
942 } 1057 }
943 1058
944 /* make sure the status line matches the response we are looking for */ 1059 /* make sure the status line matches the response we are looking for */
945 if (!expected_statuscode(status_line.first_line, config.server_expect)) { 1060 if (!expected_statuscode(status_line.first_line, config.server_expect)) {
946 if (config.server_port == HTTP_PORT) { 1061 if (config.server_port == HTTP_PORT) {
947 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host: %s\n"), status_line.first_line); 1062 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host: %s\n"),
948 } else {
949 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Invalid HTTP response received from host on port %d: %s\n"), config.server_port,
950 status_line.first_line); 1063 status_line.first_line);
1064 } else {
1065 snprintf(msg, DEFAULT_BUFFER_SIZE,
1066 _("Invalid HTTP response received from host on port %d: %s\n"),
1067 config.server_port, status_line.first_line);
951 } 1068 }
952 die(STATE_CRITICAL, "HTTP CRITICAL - %s%s%s", msg, config.show_body ? "\n" : "", config.show_body ? body_buf.buf : ""); 1069 die(STATE_CRITICAL, "HTTP CRITICAL - %s%s%s", msg, config.show_body ? "\n" : "",
1070 config.show_body ? body_buf.buf : "");
953 } 1071 }
954 1072
955 int result = STATE_OK; 1073 int result = STATE_OK;
956 if (config.server_expect_yn) { 1074 if (config.server_expect_yn) {
957 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Status line output matched \"%s\" - "), config.server_expect); 1075 snprintf(msg, DEFAULT_BUFFER_SIZE, _("Status line output matched \"%s\" - "),
1076 config.server_expect);
958 if (verbose) { 1077 if (verbose) {
959 printf("%s\n", msg); 1078 printf("%s\n", msg);
960 } 1079 }
@@ -962,7 +1081,8 @@ mp_state_enum check_http(check_curl_config config) {
962 } else { 1081 } else {
963 /* illegal return codes result in a critical state */ 1082 /* illegal return codes result in a critical state */
964 if (code >= 600 || code < 100) { 1083 if (code >= 600 || code < 100) {
965 die(STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%d, %.40s)\n"), status_line.http_code, status_line.msg); 1084 die(STATE_CRITICAL, _("HTTP CRITICAL: Invalid Status (%d, %.40s)\n"),
1085 status_line.http_code, status_line.msg);
966 /* server errors result in a critical state */ 1086 /* server errors result in a critical state */
967 } else if (code >= 500) { 1087 } else if (code >= 500) {
968 result = STATE_CRITICAL; 1088 result = STATE_CRITICAL;
@@ -995,12 +1115,15 @@ mp_state_enum check_http(check_curl_config config) {
995 1115
996 /* libcurl redirection internally, handle error states here */ 1116 /* libcurl redirection internally, handle error states here */
997 if (config.followmethod == FOLLOW_LIBCURL) { 1117 if (config.followmethod == FOLLOW_LIBCURL) {
998 handle_curl_option_return_code(curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &redir_depth), "CURLINFO_REDIRECT_COUNT"); 1118 handle_curl_option_return_code(
1119 curl_easy_getinfo(curl, CURLINFO_REDIRECT_COUNT, &redir_depth),
1120 "CURLINFO_REDIRECT_COUNT");
999 if (verbose >= 2) { 1121 if (verbose >= 2) {
1000 printf(_("* curl LIBINFO_REDIRECT_COUNT is %d\n"), redir_depth); 1122 printf(_("* curl LIBINFO_REDIRECT_COUNT is %d\n"), redir_depth);
1001 } 1123 }
1002 if (redir_depth > config.max_depth) { 1124 if (redir_depth > config.max_depth) {
1003 snprintf(msg, DEFAULT_BUFFER_SIZE, "maximum redirection depth %d exceeded in libcurl", config.max_depth); 1125 snprintf(msg, DEFAULT_BUFFER_SIZE, "maximum redirection depth %d exceeded in libcurl",
1126 config.max_depth);
1004 die(STATE_WARNING, "HTTP WARNING - %s", msg); 1127 die(STATE_WARNING, "HTTP WARNING - %s", msg);
1005 } 1128 }
1006 } 1129 }
@@ -1008,7 +1131,8 @@ mp_state_enum check_http(check_curl_config config) {
1008 /* check status codes, set exit status accordingly */ 1131 /* check status codes, set exit status accordingly */
1009 if (status_line.http_code != code) { 1132 if (status_line.http_code != code) {
1010 die(STATE_CRITICAL, _("HTTP CRITICAL %s %d %s - different HTTP codes (cUrl has %ld)\n"), 1133 die(STATE_CRITICAL, _("HTTP CRITICAL %s %d %s - different HTTP codes (cUrl has %ld)\n"),
1011 string_statuscode(status_line.http_major, status_line.http_minor), status_line.http_code, status_line.msg, code); 1134 string_statuscode(status_line.http_major, status_line.http_minor),
1135 status_line.http_code, status_line.msg, code);
1012 } 1136 }
1013 1137
1014 if (config.maximum_age >= 0) { 1138 if (config.maximum_age >= 0) {
@@ -1029,9 +1153,10 @@ mp_state_enum check_http(check_curl_config config) {
1029 1153
1030 char tmp[DEFAULT_BUFFER_SIZE]; 1154 char tmp[DEFAULT_BUFFER_SIZE];
1031 1155
1032 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sheader '%s' not found on '%s://%s:%d%s', "), msg, output_header_search, 1156 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sheader '%s' not found on '%s://%s:%d%s', "),
1033 config.use_ssl ? "https" : "http", config.host_name ? config.host_name : config.server_address, config.server_port, 1157 msg, output_header_search, config.use_ssl ? "https" : "http",
1034 config.server_url); 1158 config.host_name ? config.host_name : config.server_address,
1159 config.server_port, config.server_url);
1035 1160
1036 strcpy(msg, tmp); 1161 strcpy(msg, tmp);
1037 1162
@@ -1051,9 +1176,10 @@ mp_state_enum check_http(check_curl_config config) {
1051 1176
1052 char tmp[DEFAULT_BUFFER_SIZE]; 1177 char tmp[DEFAULT_BUFFER_SIZE];
1053 1178
1054 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sstring '%s' not found on '%s://%s:%d%s', "), msg, output_string_search, 1179 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sstring '%s' not found on '%s://%s:%d%s', "),
1055 config.use_ssl ? "https" : "http", config.host_name ? config.host_name : config.server_address, config.server_port, 1180 msg, output_string_search, config.use_ssl ? "https" : "http",
1056 config.server_url); 1181 config.host_name ? config.host_name : config.server_address,
1182 config.server_port, config.server_url);
1057 1183
1058 strcpy(msg, tmp); 1184 strcpy(msg, tmp);
1059 1185
@@ -1065,10 +1191,12 @@ mp_state_enum check_http(check_curl_config config) {
1065 regex_t preg; 1191 regex_t preg;
1066 regmatch_t pmatch[REGS]; 1192 regmatch_t pmatch[REGS];
1067 int errcode = regexec(&preg, body_buf.buf, REGS, pmatch, 0); 1193 int errcode = regexec(&preg, body_buf.buf, REGS, pmatch, 0);
1068 if ((errcode == 0 && !config.invert_regex) || (errcode == REG_NOMATCH && config.invert_regex)) { 1194 if ((errcode == 0 && !config.invert_regex) ||
1195 (errcode == REG_NOMATCH && config.invert_regex)) {
1069 /* OK - No-op to avoid changing the logic around it */ 1196 /* OK - No-op to avoid changing the logic around it */
1070 result = max_state_alt(STATE_OK, result); 1197 result = max_state_alt(STATE_OK, result);
1071 } else if ((errcode == REG_NOMATCH && !config.invert_regex) || (errcode == 0 && config.invert_regex)) { 1198 } else if ((errcode == REG_NOMATCH && !config.invert_regex) ||
1199 (errcode == 0 && config.invert_regex)) {
1072 if (!config.invert_regex) { 1200 if (!config.invert_regex) {
1073 char tmp[DEFAULT_BUFFER_SIZE]; 1201 char tmp[DEFAULT_BUFFER_SIZE];
1074 1202
@@ -1123,10 +1251,13 @@ mp_state_enum check_http(check_curl_config config) {
1123 } 1251 }
1124 } 1252 }
1125 1253
1126 /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */ 1254 /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result),
1127 die(max_state_alt(result, result_ssl), "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s", state_text(result), 1255 * msg); */
1128 string_statuscode(status_line.http_major, status_line.http_minor), status_line.http_code, status_line.msg, 1256 die(max_state_alt(result, result_ssl),
1129 strlen(msg) > 0 ? " - " : "", msg, page_len, total_time, (config.display_html ? "</A>" : ""), perfstring, 1257 "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s",
1258 state_text(result), string_statuscode(status_line.http_major, status_line.http_minor),
1259 status_line.http_code, status_line.msg, strlen(msg) > 0 ? " - " : "", msg, page_len,
1260 total_time, (config.display_html ? "</A>" : ""), perfstring,
1130 (config.show_body ? body_buf.buf : ""), (config.show_body ? "\n" : "")); 1261 (config.show_body ? body_buf.buf : ""), (config.show_body ? "\n" : ""));
1131 1262
1132 return max_state_alt(result, result_ssl); 1263 return max_state_alt(result, result_ssl);
@@ -1157,8 +1288,9 @@ void redir(curlhelp_write_curlbuf *header_buf, check_curl_config config) {
1157 struct phr_header headers[255]; 1288 struct phr_header headers[255];
1158 size_t msglen; 1289 size_t msglen;
1159 size_t nof_headers = 255; 1290 size_t nof_headers = 255;
1160 int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major, &status_line.http_minor, 1291 int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major,
1161 &status_line.http_code, &status_line.msg, &msglen, headers, &nof_headers, 0); 1292 &status_line.http_minor, &status_line.http_code, &status_line.msg,
1293 &msglen, headers, &nof_headers, 0);
1162 1294
1163 if (res == -1) { 1295 if (res == -1) {
1164 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); 1296 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n"));
@@ -1171,8 +1303,8 @@ void redir(curlhelp_write_curlbuf *header_buf, check_curl_config config) {
1171 } 1303 }
1172 1304
1173 if (++redir_depth > config.max_depth) { 1305 if (++redir_depth > config.max_depth) {
1174 die(STATE_WARNING, _("HTTP WARNING - maximum redirection depth %d exceeded - %s%s\n"), config.max_depth, location, 1306 die(STATE_WARNING, _("HTTP WARNING - maximum redirection depth %d exceeded - %s%s\n"),
1175 (config.display_html ? "</A>" : "")); 1307 config.max_depth, location, (config.display_html ? "</A>" : ""));
1176 } 1308 }
1177 1309
1178 UriParserStateA state; 1310 UriParserStateA state;
@@ -1180,8 +1312,8 @@ void redir(curlhelp_write_curlbuf *header_buf, check_curl_config config) {
1180 state.uri = &uri; 1312 state.uri = &uri;
1181 if (uriParseUriA(&state, location) != URI_SUCCESS) { 1313 if (uriParseUriA(&state, location) != URI_SUCCESS) {
1182 if (state.errorCode == URI_ERROR_SYNTAX) { 1314 if (state.errorCode == URI_ERROR_SYNTAX) {
1183 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not parse redirect location '%s'%s\n"), location, 1315 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not parse redirect location '%s'%s\n"),
1184 (config.display_html ? "</A>" : "")); 1316 location, (config.display_html ? "</A>" : ""));
1185 } else if (state.errorCode == URI_ERROR_MALLOC) { 1317 } else if (state.errorCode == URI_ERROR_MALLOC) {
1186 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n")); 1318 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Could not allocate URL\n"));
1187 } 1319 }
@@ -1234,8 +1366,8 @@ void redir(curlhelp_write_curlbuf *header_buf, check_curl_config config) {
1234 } 1366 }
1235 } 1367 }
1236 if (new_port > MAX_PORT) { 1368 if (new_port > MAX_PORT) {
1237 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Redirection to port above %d - %s%s\n"), MAX_PORT, location, 1369 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Redirection to port above %d - %s%s\n"), MAX_PORT,
1238 config.display_html ? "</A>" : ""); 1370 location, config.display_html ? "</A>" : "");
1239 } 1371 }
1240 1372
1241 /* by RFC 7231 relative URLs in Location should be taken relative to 1373 /* by RFC 7231 relative URLs in Location should be taken relative to
@@ -1259,14 +1391,19 @@ void redir(curlhelp_write_curlbuf *header_buf, check_curl_config config) {
1259 const UriPathSegmentA *p = uri.pathHead; 1391 const UriPathSegmentA *p = uri.pathHead;
1260 for (; p; p = p->next) { 1392 for (; p; p = p->next) {
1261 strncat(new_url, "/", DEFAULT_BUFFER_SIZE); 1393 strncat(new_url, "/", DEFAULT_BUFFER_SIZE);
1262 strncat(new_url, uri_string(p->text, buf, DEFAULT_BUFFER_SIZE), DEFAULT_BUFFER_SIZE - 1); 1394 strncat(new_url, uri_string(p->text, buf, DEFAULT_BUFFER_SIZE),
1395 DEFAULT_BUFFER_SIZE - 1);
1263 } 1396 }
1264 } 1397 }
1265 1398
1266 if (config.server_port == new_port && !strncmp(config.server_address, new_host, MAX_IPV4_HOSTLENGTH) && 1399 if (config.server_port == new_port &&
1267 (config.host_name && !strncmp(config.host_name, new_host, MAX_IPV4_HOSTLENGTH)) && !strcmp(config.server_url, new_url)) { 1400 !strncmp(config.server_address, new_host, MAX_IPV4_HOSTLENGTH) &&
1268 die(STATE_CRITICAL, _("HTTP CRITICAL - redirection creates an infinite loop - %s://%s:%d%s%s\n"), config.use_ssl ? "https" : "http", 1401 (config.host_name && !strncmp(config.host_name, new_host, MAX_IPV4_HOSTLENGTH)) &&
1269 new_host, new_port, new_url, (config.display_html ? "</A>" : "")); 1402 !strcmp(config.server_url, new_url)) {
1403 die(STATE_CRITICAL,
1404 _("HTTP CRITICAL - redirection creates an infinite loop - %s://%s:%d%s%s\n"),
1405 config.use_ssl ? "https" : "http", new_host, new_port, new_url,
1406 (config.display_html ? "</A>" : ""));
1270 } 1407 }
1271 1408
1272 /* set new values for redirected request */ 1409 /* set new values for redirected request */
@@ -1293,7 +1430,8 @@ void redir(curlhelp_write_curlbuf *header_buf, check_curl_config config) {
1293 1430
1294 if (verbose) { 1431 if (verbose) {
1295 printf(_("Redirection to %s://%s:%d%s\n"), config.use_ssl ? "https" : "http", 1432 printf(_("Redirection to %s://%s:%d%s\n"), config.use_ssl ? "https" : "http",
1296 config.host_name ? config.host_name : config.server_address, config.server_port, config.server_url); 1433 config.host_name ? config.host_name : config.server_address, config.server_port,
1434 config.server_url);
1297 } 1435 }
1298 1436
1299 /* TODO: the hash component MUST be taken from the original URL and 1437 /* TODO: the hash component MUST be taken from the original URL and
@@ -1326,50 +1464,51 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1326 STATE_REGEX 1464 STATE_REGEX
1327 }; 1465 };
1328 1466
1329 static struct option longopts[] = {STD_LONG_OPTS, 1467 static struct option longopts[] = {
1330 {"link", no_argument, 0, 'L'}, 1468 STD_LONG_OPTS,
1331 {"nohtml", no_argument, 0, 'n'}, 1469 {"link", no_argument, 0, 'L'},
1332 {"ssl", optional_argument, 0, 'S'}, 1470 {"nohtml", no_argument, 0, 'n'},
1333 {"sni", no_argument, 0, SNI_OPTION}, 1471 {"ssl", optional_argument, 0, 'S'},
1334 {"post", required_argument, 0, 'P'}, 1472 {"sni", no_argument, 0, SNI_OPTION},
1335 {"method", required_argument, 0, 'j'}, 1473 {"post", required_argument, 0, 'P'},
1336 {"IP-address", required_argument, 0, 'I'}, 1474 {"method", required_argument, 0, 'j'},
1337 {"url", required_argument, 0, 'u'}, 1475 {"IP-address", required_argument, 0, 'I'},
1338 {"port", required_argument, 0, 'p'}, 1476 {"url", required_argument, 0, 'u'},
1339 {"authorization", required_argument, 0, 'a'}, 1477 {"port", required_argument, 0, 'p'},
1340 {"proxy-authorization", required_argument, 0, 'b'}, 1478 {"authorization", required_argument, 0, 'a'},
1341 {"header-string", required_argument, 0, 'd'}, 1479 {"proxy-authorization", required_argument, 0, 'b'},
1342 {"string", required_argument, 0, 's'}, 1480 {"header-string", required_argument, 0, 'd'},
1343 {"expect", required_argument, 0, 'e'}, 1481 {"string", required_argument, 0, 's'},
1344 {"regex", required_argument, 0, 'r'}, 1482 {"expect", required_argument, 0, 'e'},
1345 {"ereg", required_argument, 0, 'r'}, 1483 {"regex", required_argument, 0, 'r'},
1346 {"eregi", required_argument, 0, 'R'}, 1484 {"ereg", required_argument, 0, 'r'},
1347 {"linespan", no_argument, 0, 'l'}, 1485 {"eregi", required_argument, 0, 'R'},
1348 {"onredirect", required_argument, 0, 'f'}, 1486 {"linespan", no_argument, 0, 'l'},
1349 {"certificate", required_argument, 0, 'C'}, 1487 {"onredirect", required_argument, 0, 'f'},
1350 {"client-cert", required_argument, 0, 'J'}, 1488 {"certificate", required_argument, 0, 'C'},
1351 {"private-key", required_argument, 0, 'K'}, 1489 {"client-cert", required_argument, 0, 'J'},
1352 {"ca-cert", required_argument, 0, CA_CERT_OPTION}, 1490 {"private-key", required_argument, 0, 'K'},
1353 {"verify-cert", no_argument, 0, 'D'}, 1491 {"ca-cert", required_argument, 0, CA_CERT_OPTION},
1354 {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT}, 1492 {"verify-cert", no_argument, 0, 'D'},
1355 {"useragent", required_argument, 0, 'A'}, 1493 {"continue-after-certificate", no_argument, 0, CONTINUE_AFTER_CHECK_CERT},
1356 {"header", required_argument, 0, 'k'}, 1494 {"useragent", required_argument, 0, 'A'},
1357 {"no-body", no_argument, 0, 'N'}, 1495 {"header", required_argument, 0, 'k'},
1358 {"max-age", required_argument, 0, 'M'}, 1496 {"no-body", no_argument, 0, 'N'},
1359 {"content-type", required_argument, 0, 'T'}, 1497 {"max-age", required_argument, 0, 'M'},
1360 {"pagesize", required_argument, 0, 'm'}, 1498 {"content-type", required_argument, 0, 'T'},
1361 {"invert-regex", no_argument, NULL, INVERT_REGEX}, 1499 {"pagesize", required_argument, 0, 'm'},
1362 {"state-regex", required_argument, 0, STATE_REGEX}, 1500 {"invert-regex", no_argument, NULL, INVERT_REGEX},
1363 {"use-ipv4", no_argument, 0, '4'}, 1501 {"state-regex", required_argument, 0, STATE_REGEX},
1364 {"use-ipv6", no_argument, 0, '6'}, 1502 {"use-ipv4", no_argument, 0, '4'},
1365 {"extended-perfdata", no_argument, 0, 'E'}, 1503 {"use-ipv6", no_argument, 0, '6'},
1366 {"show-body", no_argument, 0, 'B'}, 1504 {"extended-perfdata", no_argument, 0, 'E'},
1367 {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION}, 1505 {"show-body", no_argument, 0, 'B'},
1368 {"http-version", required_argument, 0, HTTP_VERSION_OPTION}, 1506 {"max-redirs", required_argument, 0, MAX_REDIRS_OPTION},
1369 {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION}, 1507 {"http-version", required_argument, 0, HTTP_VERSION_OPTION},
1370 {"cookie-jar", required_argument, 0, COOKIE_JAR}, 1508 {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION},
1371 {"haproxy-protocol", no_argument, 0, HAPROXY_PROTOCOL}, 1509 {"cookie-jar", required_argument, 0, COOKIE_JAR},
1372 {0, 0, 0, 0}}; 1510 {"haproxy-protocol", no_argument, 0, HAPROXY_PROTOCOL},
1511 {0, 0, 0, 0}};
1373 1512
1374 check_curl_config_wrapper result = { 1513 check_curl_config_wrapper result = {
1375 .errorcode = OK, 1514 .errorcode = OK,
@@ -1407,7 +1546,9 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1407 bool specify_port = false; 1546 bool specify_port = false;
1408 1547
1409 while (true) { 1548 while (true) {
1410 int option_index = 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); 1549 int option_index = getopt_long(
1550 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",
1551 longopts, &option);
1411 if (option_index == -1 || option_index == EOF || option_index == 1) { 1552 if (option_index == -1 || option_index == EOF || option_index == 1) {
1412 break; 1553 break;
1413 } 1554 }
@@ -1450,7 +1591,8 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1450 free(result.config.host_name); 1591 free(result.config.host_name);
1451 result.config.host_name = strndup(optarg, host_name_length); 1592 result.config.host_name = strndup(optarg, host_name_length);
1452 } 1593 }
1453 } else if ((p = strchr(result.config.host_name, ':')) != NULL && strchr(++p, ':') == NULL) { /* IPv4:port or host:port */ 1594 } else if ((p = strchr(result.config.host_name, ':')) != NULL &&
1595 strchr(++p, ':') == NULL) { /* IPv4:port or host:port */
1454 result.config.virtual_port = atoi(p); 1596 result.config.virtual_port = atoi(p);
1455 /* cut off the port */ 1597 /* cut off the port */
1456 host_name_length = strlen(result.config.host_name) - strlen(p) - 1; 1598 host_name_length = strlen(result.config.host_name) - strlen(p) - 1;
@@ -1503,10 +1645,12 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1503 break; 1645 break;
1504 case 'k': /* Additional headers */ 1646 case 'k': /* Additional headers */
1505 if (result.config.http_opt_headers_count == 0) { 1647 if (result.config.http_opt_headers_count == 0) {
1506 result.config.http_opt_headers = malloc(sizeof(char *) * (++result.config.http_opt_headers_count)); 1648 result.config.http_opt_headers =
1649 malloc(sizeof(char *) * (++result.config.http_opt_headers_count));
1507 } else { 1650 } else {
1508 result.config.http_opt_headers = 1651 result.config.http_opt_headers =
1509 realloc(result.config.http_opt_headers, sizeof(char *) * (++result.config.http_opt_headers_count)); 1652 realloc(result.config.http_opt_headers,
1653 sizeof(char *) * (++result.config.http_opt_headers_count));
1510 } 1654 }
1511 result.config.http_opt_headers[result.config.http_opt_headers_count - 1] = optarg; 1655 result.config.http_opt_headers[result.config.http_opt_headers_count - 1] = optarg;
1512 break; 1656 break;
@@ -1615,7 +1759,8 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1615 result.config.ssl_version = CURL_SSLVERSION_DEFAULT; 1759 result.config.ssl_version = CURL_SSLVERSION_DEFAULT;
1616# endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0) */ 1760# endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 52, 0) */
1617 else { 1761 else {
1618 usage4(_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2, 1.3 (with optional '+' suffix)")); 1762 usage4(_("Invalid option - Valid SSL/TLS versions: 2, 3, 1, 1.1, 1.2, 1.3 "
1763 "(with optional '+' suffix)"));
1619 } 1764 }
1620 } 1765 }
1621# if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0) 1766# if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 54, 0)
@@ -1681,21 +1826,26 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1681 } else if (!strcmp(optarg, "follow")) { 1826 } else if (!strcmp(optarg, "follow")) {
1682 result.config.onredirect = STATE_DEPENDENT; 1827 result.config.onredirect = STATE_DEPENDENT;
1683 } else if (!strcmp(optarg, "stickyport")) { 1828 } else if (!strcmp(optarg, "stickyport")) {
1684 result.config.onredirect = STATE_DEPENDENT, result.config.followmethod = FOLLOW_HTTP_CURL, 1829 result.config.onredirect = STATE_DEPENDENT,
1830 result.config.followmethod = FOLLOW_HTTP_CURL,
1685 result.config.followsticky = STICKY_HOST | STICKY_PORT; 1831 result.config.followsticky = STICKY_HOST | STICKY_PORT;
1686 } else if (!strcmp(optarg, "sticky")) { 1832 } else if (!strcmp(optarg, "sticky")) {
1687 result.config.onredirect = STATE_DEPENDENT, result.config.followmethod = FOLLOW_HTTP_CURL, 1833 result.config.onredirect = STATE_DEPENDENT,
1834 result.config.followmethod = FOLLOW_HTTP_CURL,
1688 result.config.followsticky = STICKY_HOST; 1835 result.config.followsticky = STICKY_HOST;
1689 } else if (!strcmp(optarg, "follow")) { 1836 } else if (!strcmp(optarg, "follow")) {
1690 result.config.onredirect = STATE_DEPENDENT, result.config.followmethod = FOLLOW_HTTP_CURL, 1837 result.config.onredirect = STATE_DEPENDENT,
1838 result.config.followmethod = FOLLOW_HTTP_CURL,
1691 result.config.followsticky = STICKY_NONE; 1839 result.config.followsticky = STICKY_NONE;
1692 } else if (!strcmp(optarg, "curl")) { 1840 } else if (!strcmp(optarg, "curl")) {
1693 result.config.onredirect = STATE_DEPENDENT, result.config.followmethod = FOLLOW_LIBCURL; 1841 result.config.onredirect = STATE_DEPENDENT,
1842 result.config.followmethod = FOLLOW_LIBCURL;
1694 } else { 1843 } else {
1695 usage2(_("Invalid onredirect option"), optarg); 1844 usage2(_("Invalid onredirect option"), optarg);
1696 } 1845 }
1697 if (verbose >= 2) { 1846 if (verbose >= 2) {
1698 printf(_("* Following redirects set to %s\n"), state_text(result.config.onredirect)); 1847 printf(_("* Following redirects set to %s\n"),
1848 state_text(result.config.onredirect));
1699 } 1849 }
1700 break; 1850 break;
1701 case 'd': /* string or substring */ 1851 case 'd': /* string or substring */
@@ -1791,7 +1941,8 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1791 result.config.maximum_age = atoi(optarg) * 60 * 60; 1941 result.config.maximum_age = atoi(optarg) * 60 * 60;
1792 } else if (option_length && optarg[option_length - 1] == 'd') { 1942 } else if (option_length && optarg[option_length - 1] == 'd') {
1793 result.config.maximum_age = atoi(optarg) * 60 * 60 * 24; 1943 result.config.maximum_age = atoi(optarg) * 60 * 60 * 24;
1794 } else if (option_length && (optarg[option_length - 1] == 's' || isdigit(optarg[option_length - 1]))) { 1944 } else if (option_length &&
1945 (optarg[option_length - 1] == 's' || isdigit(optarg[option_length - 1]))) {
1795 result.config.maximum_age = atoi(optarg); 1946 result.config.maximum_age = atoi(optarg);
1796 } else { 1947 } else {
1797 fprintf(stderr, "unparsable max-age: %s\n", optarg); 1948 fprintf(stderr, "unparsable max-age: %s\n", optarg);
@@ -1860,7 +2011,8 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1860 2011
1861 set_thresholds(&result.config.thlds, warning_thresholds, critical_thresholds); 2012 set_thresholds(&result.config.thlds, warning_thresholds, critical_thresholds);
1862 2013
1863 if (critical_thresholds && result.config.thlds->critical->end > (double)result.config.socket_timeout) { 2014 if (critical_thresholds &&
2015 result.config.thlds->critical->end > (double)result.config.socket_timeout) {
1864 result.config.socket_timeout = (int)result.config.thlds->critical->end + 1; 2016 result.config.socket_timeout = (int)result.config.thlds->critical->end + 1;
1865 } 2017 }
1866 if (verbose >= 2) { 2018 if (verbose >= 2) {
@@ -1890,32 +2042,39 @@ check_curl_config_wrapper process_arguments(int argc, char **argv) {
1890} 2042}
1891 2043
1892char *perfd_time(double elapsed_time, thresholds *thlds, long socket_timeout) { 2044char *perfd_time(double elapsed_time, thresholds *thlds, long socket_timeout) {
1893 return fperfdata("time", elapsed_time, "s", thlds->warning, thlds->warning ? thlds->warning->end : 0, thlds->critical, 2045 return fperfdata("time", elapsed_time, "s", thlds->warning,
2046 thlds->warning ? thlds->warning->end : 0, thlds->critical,
1894 thlds->critical ? thlds->critical->end : 0, true, 0, true, socket_timeout); 2047 thlds->critical ? thlds->critical->end : 0, true, 0, true, socket_timeout);
1895} 2048}
1896 2049
1897char *perfd_time_connect(double elapsed_time_connect, long socket_timeout) { 2050char *perfd_time_connect(double elapsed_time_connect, long socket_timeout) {
1898 return fperfdata("time_connect", elapsed_time_connect, "s", false, 0, false, 0, false, 0, true, socket_timeout); 2051 return fperfdata("time_connect", elapsed_time_connect, "s", false, 0, false, 0, false, 0, true,
2052 socket_timeout);
1899} 2053}
1900 2054
1901char *perfd_time_ssl(double elapsed_time_ssl, long socket_timeout) { 2055char *perfd_time_ssl(double elapsed_time_ssl, long socket_timeout) {
1902 return fperfdata("time_ssl", elapsed_time_ssl, "s", false, 0, false, 0, false, 0, true, socket_timeout); 2056 return fperfdata("time_ssl", elapsed_time_ssl, "s", false, 0, false, 0, false, 0, true,
2057 socket_timeout);
1903} 2058}
1904 2059
1905char *perfd_time_headers(double elapsed_time_headers, long socket_timeout) { 2060char *perfd_time_headers(double elapsed_time_headers, long socket_timeout) {
1906 return fperfdata("time_headers", elapsed_time_headers, "s", false, 0, false, 0, false, 0, true, socket_timeout); 2061 return fperfdata("time_headers", elapsed_time_headers, "s", false, 0, false, 0, false, 0, true,
2062 socket_timeout);
1907} 2063}
1908 2064
1909char *perfd_time_firstbyte(double elapsed_time_firstbyte, long socket_timeout) { 2065char *perfd_time_firstbyte(double elapsed_time_firstbyte, long socket_timeout) {
1910 return fperfdata("time_firstbyte", elapsed_time_firstbyte, "s", false, 0, false, 0, false, 0, true, socket_timeout); 2066 return fperfdata("time_firstbyte", elapsed_time_firstbyte, "s", false, 0, false, 0, false, 0,
2067 true, socket_timeout);
1911} 2068}
1912 2069
1913char *perfd_time_transfer(double elapsed_time_transfer, long socket_timeout) { 2070char *perfd_time_transfer(double elapsed_time_transfer, long socket_timeout) {
1914 return fperfdata("time_transfer", elapsed_time_transfer, "s", false, 0, false, 0, false, 0, true, socket_timeout); 2071 return fperfdata("time_transfer", elapsed_time_transfer, "s", false, 0, false, 0, false, 0,
2072 true, socket_timeout);
1915} 2073}
1916 2074
1917char *perfd_size(int page_len, int min_page_len) { 2075char *perfd_size(int page_len, int min_page_len) {
1918 return perfdata("size", page_len, "B", (min_page_len > 0), min_page_len, (min_page_len > 0), 0, true, 0, false, 0); 2076 return perfdata("size", page_len, "B", (min_page_len > 0), min_page_len, (min_page_len > 0), 0,
2077 true, 0, false, 0);
1919} 2078}
1920 2079
1921void print_help(void) { 2080void print_help(void) {
@@ -1929,7 +2088,8 @@ void print_help(void) {
1929 printf("%s\n", _("strings and regular expressions, check connection times, and report on")); 2088 printf("%s\n", _("strings and regular expressions, check connection times, and report on"));
1930 printf("%s\n", _("certificate expiration times.")); 2089 printf("%s\n", _("certificate expiration times."));
1931 printf("\n"); 2090 printf("\n");
1932 printf("%s\n", _("It makes use of libcurl to do so. It tries to be as compatible to check_http")); 2091 printf("%s\n",
2092 _("It makes use of libcurl to do so. It tries to be as compatible to check_http"));
1933 printf("%s\n", _("as possible.")); 2093 printf("%s\n", _("as possible."));
1934 2094
1935 printf("\n\n"); 2095 printf("\n\n");
@@ -1947,7 +2107,8 @@ void print_help(void) {
1947 printf(" %s\n", _("Host name argument for servers using host headers (virtual host)")); 2107 printf(" %s\n", _("Host name argument for servers using host headers (virtual host)"));
1948 printf(" %s\n", _("Append a port to include it in the header (eg: example.com:5000)")); 2108 printf(" %s\n", _("Append a port to include it in the header (eg: example.com:5000)"));
1949 printf(" %s\n", "-I, --IP-address=ADDRESS"); 2109 printf(" %s\n", "-I, --IP-address=ADDRESS");
1950 printf(" %s\n", _("IP address or name (use numeric address if possible to bypass DNS lookup).")); 2110 printf(" %s\n",
2111 _("IP address or name (use numeric address if possible to bypass DNS lookup)."));
1951 printf(" %s\n", "-p, --port=INTEGER"); 2112 printf(" %s\n", "-p, --port=INTEGER");
1952 printf(" %s", _("Port number (default: ")); 2113 printf(" %s", _("Port number (default: "));
1953 printf("%d)\n", HTTP_PORT); 2114 printf("%d)\n", HTTP_PORT);
@@ -1956,27 +2117,37 @@ void print_help(void) {
1956 2117
1957#ifdef LIBCURL_FEATURE_SSL 2118#ifdef LIBCURL_FEATURE_SSL
1958 printf(" %s\n", "-S, --ssl=VERSION[+]"); 2119 printf(" %s\n", "-S, --ssl=VERSION[+]");
1959 printf(" %s\n", _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents")); 2120 printf(" %s\n",
2121 _("Connect via SSL. Port defaults to 443. VERSION is optional, and prevents"));
1960 printf(" %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,")); 2122 printf(" %s\n", _("auto-negotiation (2 = SSLv2, 3 = SSLv3, 1 = TLSv1, 1.1 = TLSv1.1,"));
1961 printf(" %s\n", _("1.2 = TLSv1.2, 1.3 = TLSv1.3). With a '+' suffix, newer versions are also accepted.")); 2123 printf(
1962 printf(" %s\n", _("Note: SSLv2, SSLv3, TLSv1.0 and TLSv1.1 are deprecated and are usually disabled in libcurl")); 2124 " %s\n",
2125 _("1.2 = TLSv1.2, 1.3 = TLSv1.3). With a '+' suffix, newer versions are also accepted."));
2126 printf(" %s\n", _("Note: SSLv2, SSLv3, TLSv1.0 and TLSv1.1 are deprecated and are usually "
2127 "disabled in libcurl"));
1963 printf(" %s\n", "--sni"); 2128 printf(" %s\n", "--sni");
1964 printf(" %s\n", _("Enable SSL/TLS hostname extension support (SNI)")); 2129 printf(" %s\n", _("Enable SSL/TLS hostname extension support (SNI)"));
1965# if LIBCURL_VERSION_NUM >= 0x071801 2130# if LIBCURL_VERSION_NUM >= 0x071801
1966 printf(" %s\n", _("Note: --sni is the default in libcurl as SSLv2 and SSLV3 are deprecated and")); 2131 printf(" %s\n",
2132 _("Note: --sni is the default in libcurl as SSLv2 and SSLV3 are deprecated and"));
1967 printf(" %s\n", _(" SNI only really works since TLSv1.0")); 2133 printf(" %s\n", _(" SNI only really works since TLSv1.0"));
1968# else 2134# else
1969 printf(" %s\n", _("Note: SNI is not supported in libcurl before 7.18.1")); 2135 printf(" %s\n", _("Note: SNI is not supported in libcurl before 7.18.1"));
1970# endif 2136# endif
1971 printf(" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); 2137 printf(" %s\n", "-C, --certificate=INTEGER[,INTEGER]");
1972 printf(" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443.")); 2138 printf(" %s\n",
1973 printf(" %s\n", _("A STATE_WARNING is returned if the certificate has a validity less than the")); 2139 _("Minimum number of days a certificate has to be valid. Port defaults to 443."));
1974 printf(" %s\n", _("first agument's value. If there is a second argument and the certificate's")); 2140 printf(" %s\n",
2141 _("A STATE_WARNING is returned if the certificate has a validity less than the"));
2142 printf(" %s\n",
2143 _("first agument's value. If there is a second argument and the certificate's"));
1975 printf(" %s\n", _("validity is less than its value, a STATE_CRITICAL is returned.")); 2144 printf(" %s\n", _("validity is less than its value, a STATE_CRITICAL is returned."));
1976 printf(" %s\n", _("(When this option is used the URL is not checked by default. You can use")); 2145 printf(" %s\n",
2146 _("(When this option is used the URL is not checked by default. You can use"));
1977 printf(" %s\n", _(" --continue-after-certificate to override this behavior)")); 2147 printf(" %s\n", _(" --continue-after-certificate to override this behavior)"));
1978 printf(" %s\n", "--continue-after-certificate"); 2148 printf(" %s\n", "--continue-after-certificate");
1979 printf(" %s\n", _("Allows the HTTP check to continue after performing the certificate check.")); 2149 printf(" %s\n",
2150 _("Allows the HTTP check to continue after performing the certificate check."));
1980 printf(" %s\n", _("Does nothing unless -C is used.")); 2151 printf(" %s\n", _("Does nothing unless -C is used."));
1981 printf(" %s\n", "-J, --client-cert=FILE"); 2152 printf(" %s\n", "-J, --client-cert=FILE");
1982 printf(" %s\n", _("Name of file that contains the client certificate (PEM format)")); 2153 printf(" %s\n", _("Name of file that contains the client certificate (PEM format)"));
@@ -1994,7 +2165,8 @@ void print_help(void) {
1994 printf(" %s\n", _("Comma-delimited list of strings, at least one of them is expected in")); 2165 printf(" %s\n", _("Comma-delimited list of strings, at least one of them is expected in"));
1995 printf(" %s", _("the first (status) line of the server response (default: ")); 2166 printf(" %s", _("the first (status) line of the server response (default: "));
1996 printf("%s)\n", HTTP_EXPECT); 2167 printf("%s)\n", HTTP_EXPECT);
1997 printf(" %s\n", _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)")); 2168 printf(" %s\n",
2169 _("If specified skips all other status line logic (ex: 3xx, 4xx, 5xx processing)"));
1998 printf(" %s\n", "-d, --header-string=STRING"); 2170 printf(" %s\n", "-d, --header-string=STRING");
1999 printf(" %s\n", _("String to expect in the response headers")); 2171 printf(" %s\n", _("String to expect in the response headers"));
2000 printf(" %s\n", "-s, --string=STRING"); 2172 printf(" %s\n", "-s, --string=STRING");
@@ -2003,7 +2175,8 @@ void print_help(void) {
2003 printf(" %s\n", _("URL to GET or POST (default: /)")); 2175 printf(" %s\n", _("URL to GET or POST (default: /)"));
2004 printf(" %s\n", "-P, --post=STRING"); 2176 printf(" %s\n", "-P, --post=STRING");
2005 printf(" %s\n", _("URL decoded http POST data")); 2177 printf(" %s\n", _("URL decoded http POST data"));
2006 printf(" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)"); 2178 printf(" %s\n",
2179 "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)");
2007 printf(" %s\n", _("Set HTTP method.")); 2180 printf(" %s\n", _("Set HTTP method."));
2008 printf(" %s\n", "-N, --no-body"); 2181 printf(" %s\n", "-N, --no-body");
2009 printf(" %s\n", _("Don't wait for document body: stop reading after headers.")); 2182 printf(" %s\n", _("Don't wait for document body: stop reading after headers."));
@@ -2023,7 +2196,8 @@ void print_help(void) {
2023 printf(" %s\n", _("Return STATE if found, OK if not (STATE is CRITICAL, per default)")); 2196 printf(" %s\n", _("Return STATE if found, OK if not (STATE is CRITICAL, per default)"));
2024 printf(" %s\n", _("can be changed with --state--regex)")); 2197 printf(" %s\n", _("can be changed with --state--regex)"));
2025 printf(" %s\n", "--state-regex=STATE"); 2198 printf(" %s\n", "--state-regex=STATE");
2026 printf(" %s\n", _("Return STATE if regex is found, OK if not. STATE can be one of \"critical\",\"warning\"")); 2199 printf(" %s\n", _("Return STATE if regex is found, OK if not. STATE can be one of "
2200 "\"critical\",\"warning\""));
2027 printf(" %s\n", "-a, --authorization=AUTH_PAIR"); 2201 printf(" %s\n", "-a, --authorization=AUTH_PAIR");
2028 printf(" %s\n", _("Username:password on sites with basic authentication")); 2202 printf(" %s\n", _("Username:password on sites with basic authentication"));
2029 printf(" %s\n", "-b, --proxy-authorization=AUTH_PAIR"); 2203 printf(" %s\n", "-b, --proxy-authorization=AUTH_PAIR");
@@ -2031,7 +2205,9 @@ void print_help(void) {
2031 printf(" %s\n", "-A, --useragent=STRING"); 2205 printf(" %s\n", "-A, --useragent=STRING");
2032 printf(" %s\n", _("String to be sent in http header as \"User Agent\"")); 2206 printf(" %s\n", _("String to be sent in http header as \"User Agent\""));
2033 printf(" %s\n", "-k, --header=STRING"); 2207 printf(" %s\n", "-k, --header=STRING");
2034 printf(" %s\n", _("Any other tags to be sent in http header. Use multiple times for additional headers")); 2208 printf(
2209 " %s\n",
2210 _("Any other tags to be sent in http header. Use multiple times for additional headers"));
2035 printf(" %s\n", "-E, --extended-perfdata"); 2211 printf(" %s\n", "-E, --extended-perfdata");
2036 printf(" %s\n", _("Print additional performance data")); 2212 printf(" %s\n", _("Print additional performance data"));
2037 printf(" %s\n", "-B, --show-body"); 2213 printf(" %s\n", "-B, --show-body");
@@ -2047,20 +2223,25 @@ void print_help(void) {
2047 printf(" %s", _("Maximal number of redirects (default: ")); 2223 printf(" %s", _("Maximal number of redirects (default: "));
2048 printf("%d)\n", DEFAULT_MAX_REDIRS); 2224 printf("%d)\n", DEFAULT_MAX_REDIRS);
2049 printf(" %s\n", "-m, --pagesize=INTEGER<:INTEGER>"); 2225 printf(" %s\n", "-m, --pagesize=INTEGER<:INTEGER>");
2050 printf(" %s\n", _("Minimum page size required (bytes) : Maximum page size required (bytes)")); 2226 printf(" %s\n",
2227 _("Minimum page size required (bytes) : Maximum page size required (bytes)"));
2051 printf("\n"); 2228 printf("\n");
2052 printf(" %s\n", "--http-version=VERSION"); 2229 printf(" %s\n", "--http-version=VERSION");
2053 printf(" %s\n", _("Connect via specific HTTP protocol.")); 2230 printf(" %s\n", _("Connect via specific HTTP protocol."));
2054 printf(" %s\n", _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)")); 2231 printf(" %s\n",
2232 _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)"));
2055 printf(" %s\n", "--enable-automatic-decompression"); 2233 printf(" %s\n", "--enable-automatic-decompression");
2056 printf(" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING).")); 2234 printf(" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING)."));
2057 printf(" %s\n", "--haproxy-protocol"); 2235 printf(" %s\n", "--haproxy-protocol");
2058 printf(" %s\n", _("Send HAProxy proxy protocol v1 header (CURLOPT_HAPROXYPROTOCOL).")); 2236 printf(" %s\n", _("Send HAProxy proxy protocol v1 header (CURLOPT_HAPROXYPROTOCOL)."));
2059 printf(" %s\n", "--cookie-jar=FILE"); 2237 printf(" %s\n", "--cookie-jar=FILE");
2060 printf(" %s\n", _("Store cookies in the cookie jar and send them out when requested.")); 2238 printf(" %s\n", _("Store cookies in the cookie jar and send them out when requested."));
2061 printf(" %s\n", _("Specify an empty string as FILE to enable curl's cookie engine without saving")); 2239 printf(" %s\n",
2062 printf(" %s\n", _("the cookies to disk. Only enabling the engine without saving to disk requires")); 2240 _("Specify an empty string as FILE to enable curl's cookie engine without saving"));
2063 printf(" %s\n", _("handling multiple requests internally to curl, so use it with --onredirect=curl")); 2241 printf(" %s\n",
2242 _("the cookies to disk. Only enabling the engine without saving to disk requires"));
2243 printf(" %s\n",
2244 _("handling multiple requests internally to curl, so use it with --onredirect=curl"));
2064 printf("\n"); 2245 printf("\n");
2065 2246
2066 printf(UT_WARN_CRIT); 2247 printf(UT_WARN_CRIT);
@@ -2072,10 +2253,13 @@ void print_help(void) {
2072 printf("\n"); 2253 printf("\n");
2073 printf("%s\n", _("Notes:")); 2254 printf("%s\n", _("Notes:"));
2074 printf(" %s\n", _("This plugin will attempt to open an HTTP connection with the host.")); 2255 printf(" %s\n", _("This plugin will attempt to open an HTTP connection with the host."));
2075 printf(" %s\n", _("Successful connects return STATE_OK, refusals and timeouts return STATE_CRITICAL")); 2256 printf(" %s\n",
2076 printf(" %s\n", _("other errors return STATE_UNKNOWN. Successful connects, but incorrect response")); 2257 _("Successful connects return STATE_OK, refusals and timeouts return STATE_CRITICAL"));
2258 printf(" %s\n",
2259 _("other errors return STATE_UNKNOWN. Successful connects, but incorrect response"));
2077 printf(" %s\n", _("messages from the host result in STATE_WARNING return values. If you are")); 2260 printf(" %s\n", _("messages from the host result in STATE_WARNING return values. If you are"));
2078 printf(" %s\n", _("checking a virtual server that uses 'host headers' you must supply the FQDN")); 2261 printf(" %s\n",
2262 _("checking a virtual server that uses 'host headers' you must supply the FQDN"));
2079 printf(" %s\n", _("(fully qualified domain name) as the [host_name] argument.")); 2263 printf(" %s\n", _("(fully qualified domain name) as the [host_name] argument."));
2080 2264
2081#ifdef LIBCURL_FEATURE_SSL 2265#ifdef LIBCURL_FEATURE_SSL
@@ -2091,38 +2275,53 @@ void print_help(void) {
2091 printf("%s\n", _("Examples:")); 2275 printf("%s\n", _("Examples:"));
2092 printf(" %s\n\n", "CHECK CONTENT: check_curl -w 5 -c 10 --ssl -H www.verisign.com"); 2276 printf(" %s\n\n", "CHECK CONTENT: check_curl -w 5 -c 10 --ssl -H www.verisign.com");
2093 printf(" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,")); 2277 printf(" %s\n", _("When the 'www.verisign.com' server returns its content within 5 seconds,"));
2094 printf(" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds")); 2278 printf(" %s\n",
2095 printf(" %s\n", _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); 2279 _("a STATE_OK will be returned. When the server returns its content but exceeds"));
2280 printf(" %s\n",
2281 _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,"));
2096 printf(" %s\n", _("a STATE_CRITICAL will be returned.")); 2282 printf(" %s\n", _("a STATE_CRITICAL will be returned."));
2097 printf("\n"); 2283 printf("\n");
2098 printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 14"); 2284 printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 14");
2099 printf(" %s\n", _("When the certificate of 'www.verisign.com' is valid for more than 14 days,")); 2285 printf(" %s\n",
2100 printf(" %s\n", _("a STATE_OK is returned. When the certificate is still valid, but for less than")); 2286 _("When the certificate of 'www.verisign.com' is valid for more than 14 days,"));
2101 printf(" %s\n", _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when")); 2287 printf(" %s\n",
2288 _("a STATE_OK is returned. When the certificate is still valid, but for less than"));
2289 printf(" %s\n",
2290 _("14 days, a STATE_WARNING is returned. A STATE_CRITICAL will be returned when"));
2102 printf(" %s\n\n", _("the certificate is expired.")); 2291 printf(" %s\n\n", _("the certificate is expired."));
2103 printf("\n"); 2292 printf("\n");
2104 printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 30,14"); 2293 printf(" %s\n\n", "CHECK CERTIFICATE: check_curl -H www.verisign.com -C 30,14");
2105 printf(" %s\n", _("When the certificate of 'www.verisign.com' is valid for more than 30 days,")); 2294 printf(" %s\n",
2106 printf(" %s\n", _("a STATE_OK is returned. When the certificate is still valid, but for less than")); 2295 _("When the certificate of 'www.verisign.com' is valid for more than 30 days,"));
2296 printf(" %s\n",
2297 _("a STATE_OK is returned. When the certificate is still valid, but for less than"));
2107 printf(" %s\n", _("30 days, but more than 14 days, a STATE_WARNING is returned.")); 2298 printf(" %s\n", _("30 days, but more than 14 days, a STATE_WARNING is returned."));
2108 printf(" %s\n", _("A STATE_CRITICAL will be returned when certificate expires in less than 14 days")); 2299 printf(" %s\n",
2300 _("A STATE_CRITICAL will be returned when certificate expires in less than 14 days"));
2109#endif 2301#endif
2110 2302
2111 printf("\n %s\n", "CHECK WEBSERVER CONTENT VIA PROXY:"); 2303 printf("\n %s\n", "CHECK WEBSERVER CONTENT VIA PROXY:");
2112 printf(" %s\n", _("It is recommended to use an environment proxy like:")); 2304 printf(" %s\n", _("It is recommended to use an environment proxy like:"));
2113 printf(" %s\n", _("http_proxy=http://192.168.100.35:3128 ./check_curl -H www.monitoring-plugins.org")); 2305 printf(" %s\n",
2306 _("http_proxy=http://192.168.100.35:3128 ./check_curl -H www.monitoring-plugins.org"));
2114 printf(" %s\n", _("legacy proxy requests in check_http style still work:")); 2307 printf(" %s\n", _("legacy proxy requests in check_http style still work:"));
2115 printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u http://www.monitoring-plugins.org/ -H www.monitoring-plugins.org")); 2308 printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u http://www.monitoring-plugins.org/ "
2309 "-H www.monitoring-plugins.org"));
2116 2310
2117#ifdef LIBCURL_FEATURE_SSL 2311#ifdef LIBCURL_FEATURE_SSL
2118 printf("\n %s\n", "CHECK SSL WEBSERVER CONTENT VIA PROXY USING HTTP 1.1 CONNECT: "); 2312 printf("\n %s\n", "CHECK SSL WEBSERVER CONTENT VIA PROXY USING HTTP 1.1 CONNECT: ");
2119 printf(" %s\n", _("It is recommended to use an environment proxy like:")); 2313 printf(" %s\n", _("It is recommended to use an environment proxy like:"));
2120 printf(" %s\n", _("https_proxy=http://192.168.100.35:3128 ./check_curl -H www.verisign.com -S")); 2314 printf(" %s\n",
2315 _("https_proxy=http://192.168.100.35:3128 ./check_curl -H www.verisign.com -S"));
2121 printf(" %s\n", _("legacy proxy requests in check_http style still work:")); 2316 printf(" %s\n", _("legacy proxy requests in check_http style still work:"));
2122 printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u https://www.verisign.com/ -S -j CONNECT -H www.verisign.com ")); 2317 printf(" %s\n", _("check_curl -I 192.168.100.35 -p 3128 -u https://www.verisign.com/ -S -j "
2123 printf(" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> -S(sl) -j CONNECT -H <webserver>")); 2318 "CONNECT -H www.verisign.com "));
2124 printf(" %s\n", _("a STATE_OK will be returned. When the server returns its content but exceeds")); 2319 printf(" %s\n", _("all these options are needed: -I <proxy> -p <proxy-port> -u <check-url> "
2125 printf(" %s\n", _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,")); 2320 "-S(sl) -j CONNECT -H <webserver>"));
2321 printf(" %s\n",
2322 _("a STATE_OK will be returned. When the server returns its content but exceeds"));
2323 printf(" %s\n",
2324 _("the 5-second threshold, a STATE_WARNING will be returned. When an error occurs,"));
2126 printf(" %s\n", _("a STATE_CRITICAL will be returned.")); 2325 printf(" %s\n", _("a STATE_CRITICAL will be returned."));
2127 2326
2128#endif 2327#endif
@@ -2133,10 +2332,12 @@ void print_help(void) {
2133void print_usage(void) { 2332void print_usage(void) {
2134 printf("%s\n", _("Usage:")); 2333 printf("%s\n", _("Usage:"));
2135 printf(" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n", progname); 2334 printf(" %s -H <vhost> | -I <IP-address> [-u <uri>] [-p <port>]\n", progname);
2136 printf(" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate file>] [-D]\n"); 2335 printf(" [-J <client certificate file>] [-K <private key>] [--ca-cert <CA certificate "
2336 "file>] [-D]\n");
2137 printf(" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n"); 2337 printf(" [-w <warn time>] [-c <critical time>] [-t <timeout>] [-L] [-E] [-a auth]\n");
2138 printf(" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport|curl>]\n"); 2338 printf(" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport|curl>]\n");
2139 printf(" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); 2339 printf(" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive "
2340 "regex>]\n");
2140 printf(" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); 2341 printf(" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n");
2141 printf(" [-A string] [-k string] [-S <version>] [--sni] [--haproxy-protocol]\n"); 2342 printf(" [-A string] [-k string] [-S <version>] [--sni] [--haproxy-protocol]\n");
2142 printf(" [-T <content-type>] [-j method]\n"); 2343 printf(" [-T <content-type>] [-j method]\n");
@@ -2356,22 +2557,26 @@ int curlhelp_parse_statusline(const char *buf, curlhelp_statusline *status_line)
2356 2557
2357void curlhelp_free_statusline(curlhelp_statusline *status_line) { free(status_line->first_line); } 2558void curlhelp_free_statusline(curlhelp_statusline *status_line) { free(status_line->first_line); }
2358 2559
2359char *get_header_value(const struct phr_header *headers, const size_t nof_headers, const char *header) { 2560char *get_header_value(const struct phr_header *headers, const size_t nof_headers,
2561 const char *header) {
2360 for (size_t i = 0; i < nof_headers; i++) { 2562 for (size_t i = 0; i < nof_headers; i++) {
2361 if (headers[i].name != NULL && strncasecmp(header, headers[i].name, max(headers[i].name_len, 4)) == 0) { 2563 if (headers[i].name != NULL &&
2564 strncasecmp(header, headers[i].name, max(headers[i].name_len, 4)) == 0) {
2362 return strndup(headers[i].value, headers[i].value_len); 2565 return strndup(headers[i].value, headers[i].value_len);
2363 } 2566 }
2364 } 2567 }
2365 return NULL; 2568 return NULL;
2366} 2569}
2367 2570
2368int check_document_dates(const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFAULT_BUFFER_SIZE], int maximum_age) { 2571int check_document_dates(const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFAULT_BUFFER_SIZE],
2572 int maximum_age) {
2369 struct phr_header headers[255]; 2573 struct phr_header headers[255];
2370 size_t nof_headers = 255; 2574 size_t nof_headers = 255;
2371 curlhelp_statusline status_line; 2575 curlhelp_statusline status_line;
2372 size_t msglen; 2576 size_t msglen;
2373 int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major, &status_line.http_minor, 2577 int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major,
2374 &status_line.http_code, &status_line.msg, &msglen, headers, &nof_headers, 0); 2578 &status_line.http_minor, &status_line.http_code, &status_line.msg,
2579 &msglen, headers, &nof_headers, 0);
2375 2580
2376 if (res == -1) { 2581 if (res == -1) {
2377 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); 2582 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n"));
@@ -2401,26 +2606,30 @@ int check_document_dates(const curlhelp_write_curlbuf *header_buf, char (*msg)[D
2401 time_t srv_data = curl_getdate(server_date, NULL); 2606 time_t srv_data = curl_getdate(server_date, NULL);
2402 time_t doc_data = curl_getdate(document_date, NULL); 2607 time_t doc_data = curl_getdate(document_date, NULL);
2403 if (verbose >= 2) { 2608 if (verbose >= 2) {
2404 printf("* server date: '%s' (%d), doc_date: '%s' (%d)\n", server_date, (int)srv_data, document_date, (int)doc_data); 2609 printf("* server date: '%s' (%d), doc_date: '%s' (%d)\n", server_date, (int)srv_data,
2610 document_date, (int)doc_data);
2405 } 2611 }
2406 if (srv_data <= 0) { 2612 if (srv_data <= 0) {
2407 char tmp[DEFAULT_BUFFER_SIZE]; 2613 char tmp[DEFAULT_BUFFER_SIZE];
2408 2614
2409 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sServer date \"%100s\" unparsable, "), *msg, server_date); 2615 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sServer date \"%100s\" unparsable, "), *msg,
2616 server_date);
2410 strcpy(*msg, tmp); 2617 strcpy(*msg, tmp);
2411 2618
2412 date_result = max_state_alt(STATE_CRITICAL, date_result); 2619 date_result = max_state_alt(STATE_CRITICAL, date_result);
2413 } else if (doc_data <= 0) { 2620 } else if (doc_data <= 0) {
2414 char tmp[DEFAULT_BUFFER_SIZE]; 2621 char tmp[DEFAULT_BUFFER_SIZE];
2415 2622
2416 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sDocument date \"%100s\" unparsable, "), *msg, document_date); 2623 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sDocument date \"%100s\" unparsable, "), *msg,
2624 document_date);
2417 strcpy(*msg, tmp); 2625 strcpy(*msg, tmp);
2418 2626
2419 date_result = max_state_alt(STATE_CRITICAL, date_result); 2627 date_result = max_state_alt(STATE_CRITICAL, date_result);
2420 } else if (doc_data > srv_data + 30) { 2628 } else if (doc_data > srv_data + 30) {
2421 char tmp[DEFAULT_BUFFER_SIZE]; 2629 char tmp[DEFAULT_BUFFER_SIZE];
2422 2630
2423 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sDocument is %d seconds in the future, "), *msg, (int)doc_data - (int)srv_data); 2631 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sDocument is %d seconds in the future, "), *msg,
2632 (int)doc_data - (int)srv_data);
2424 strcpy(*msg, tmp); 2633 strcpy(*msg, tmp);
2425 2634
2426 date_result = max_state_alt(STATE_CRITICAL, date_result); 2635 date_result = max_state_alt(STATE_CRITICAL, date_result);
@@ -2429,14 +2638,16 @@ int check_document_dates(const curlhelp_write_curlbuf *header_buf, char (*msg)[D
2429 if (n > (60 * 60 * 24 * 2)) { 2638 if (n > (60 * 60 * 24 * 2)) {
2430 char tmp[DEFAULT_BUFFER_SIZE]; 2639 char tmp[DEFAULT_BUFFER_SIZE];
2431 2640
2432 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sLast modified %.1f days ago, "), *msg, ((float)n) / (60 * 60 * 24)); 2641 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sLast modified %.1f days ago, "), *msg,
2642 ((float)n) / (60 * 60 * 24));
2433 strcpy(*msg, tmp); 2643 strcpy(*msg, tmp);
2434 2644
2435 date_result = max_state_alt(STATE_CRITICAL, date_result); 2645 date_result = max_state_alt(STATE_CRITICAL, date_result);
2436 } else { 2646 } else {
2437 char tmp[DEFAULT_BUFFER_SIZE]; 2647 char tmp[DEFAULT_BUFFER_SIZE];
2438 2648
2439 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sLast modified %d:%02d:%02d ago, "), *msg, n / (60 * 60), (n / 60) % 60, n % 60); 2649 snprintf(tmp, DEFAULT_BUFFER_SIZE, _("%sLast modified %d:%02d:%02d ago, "), *msg,
2650 n / (60 * 60), (n / 60) % 60, n % 60);
2440 strcpy(*msg, tmp); 2651 strcpy(*msg, tmp);
2441 2652
2442 date_result = max_state_alt(STATE_CRITICAL, date_result); 2653 date_result = max_state_alt(STATE_CRITICAL, date_result);
@@ -2454,13 +2665,15 @@ int check_document_dates(const curlhelp_write_curlbuf *header_buf, char (*msg)[D
2454 return date_result; 2665 return date_result;
2455} 2666}
2456 2667
2457int get_content_length(const curlhelp_write_curlbuf *header_buf, const curlhelp_write_curlbuf *body_buf) { 2668int get_content_length(const curlhelp_write_curlbuf *header_buf,
2669 const curlhelp_write_curlbuf *body_buf) {
2458 struct phr_header headers[255]; 2670 struct phr_header headers[255];
2459 size_t nof_headers = 255; 2671 size_t nof_headers = 255;
2460 size_t msglen; 2672 size_t msglen;
2461 curlhelp_statusline status_line; 2673 curlhelp_statusline status_line;
2462 int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major, &status_line.http_minor, 2674 int res = phr_parse_response(header_buf->buf, header_buf->buflen, &status_line.http_major,
2463 &status_line.http_code, &status_line.msg, &msglen, headers, &nof_headers, 0); 2675 &status_line.http_minor, &status_line.http_code, &status_line.msg,
2676 &msglen, headers, &nof_headers, 0);
2464 2677
2465 if (res == -1) { 2678 if (res == -1) {
2466 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); 2679 die(STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n"));
@@ -2514,7 +2727,8 @@ curlhelp_ssl_library curlhelp_get_ssl_library(void) {
2514 } 2727 }
2515 2728
2516 if (verbose >= 2) { 2729 if (verbose >= 2) {
2517 printf("* SSL library string is : %s %s (%d)\n", version_data->ssl_version, library, ssl_library); 2730 printf("* SSL library string is : %s %s (%d)\n", version_data->ssl_version, library,
2731 ssl_library);
2518 } 2732 }
2519 2733
2520 free(ssl_version); 2734 free(ssl_version);
@@ -2560,7 +2774,8 @@ time_t parse_cert_date(const char *s) {
2560/* TODO: this needs cleanup in the sslutils.c, maybe we the #else case to 2774/* TODO: this needs cleanup in the sslutils.c, maybe we the #else case to
2561 * OpenSSL could be this function 2775 * OpenSSL could be this function
2562 */ 2776 */
2563int net_noopenssl_check_certificate(cert_ptr_union *cert_ptr, int days_till_exp_warn, int days_till_exp_crit) { 2777int net_noopenssl_check_certificate(cert_ptr_union *cert_ptr, int days_till_exp_warn,
2778 int days_till_exp_crit) {
2564 struct curl_slist *slist; 2779 struct curl_slist *slist;
2565 int cname_found = 0; 2780 int cname_found = 0;
2566 char *start_date_str = NULL; 2781 char *start_date_str = NULL;
@@ -2622,14 +2837,16 @@ HAVE_FIRST_CERT:
2622 2837
2623 start_date = parse_cert_date(start_date_str); 2838 start_date = parse_cert_date(start_date_str);
2624 if (start_date <= 0) { 2839 if (start_date <= 0) {
2625 snprintf(msg, DEFAULT_BUFFER_SIZE, _("WARNING - Unparsable 'Start Date' in certificate: '%s'"), start_date_str); 2840 snprintf(msg, DEFAULT_BUFFER_SIZE,
2841 _("WARNING - Unparsable 'Start Date' in certificate: '%s'"), start_date_str);
2626 puts(msg); 2842 puts(msg);
2627 return STATE_WARNING; 2843 return STATE_WARNING;
2628 } 2844 }
2629 2845
2630 end_date = parse_cert_date(end_date_str); 2846 end_date = parse_cert_date(end_date_str);
2631 if (end_date <= 0) { 2847 if (end_date <= 0) {
2632 snprintf(msg, DEFAULT_BUFFER_SIZE, _("WARNING - Unparsable 'Expire Date' in certificate: '%s'"), start_date_str); 2848 snprintf(msg, DEFAULT_BUFFER_SIZE,
2849 _("WARNING - Unparsable 'Expire Date' in certificate: '%s'"), start_date_str);
2633 puts(msg); 2850 puts(msg);
2634 return STATE_WARNING; 2851 return STATE_WARNING;
2635 } 2852 }
@@ -2648,8 +2865,9 @@ HAVE_FIRST_CERT:
2648 tzset(); 2865 tzset();
2649 2866
2650 if (days_left > 0 && days_left <= days_till_exp_warn) { 2867 if (days_left > 0 && days_left <= days_till_exp_warn) {
2651 printf(_("%s - Certificate '%s' expires in %d day(s) (%s).\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", 2868 printf(_("%s - Certificate '%s' expires in %d day(s) (%s).\n"),
2652 host_name, days_left, timestamp); 2869 (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", host_name, days_left,
2870 timestamp);
2653 if (days_left > days_till_exp_crit) { 2871 if (days_left > days_till_exp_crit) {
2654 status = STATE_WARNING; 2872 status = STATE_WARNING;
2655 } else { 2873 } else {
@@ -2662,8 +2880,9 @@ HAVE_FIRST_CERT:
2662 time_remaining = (int)time_left / 60; 2880 time_remaining = (int)time_left / 60;
2663 } 2881 }
2664 2882
2665 printf(_("%s - Certificate '%s' expires in %u %s (%s)\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", host_name, 2883 printf(_("%s - Certificate '%s' expires in %u %s (%s)\n"),
2666 time_remaining, time_left >= 3600 ? "hours" : "minutes", timestamp); 2884 (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", host_name, time_remaining,
2885 time_left >= 3600 ? "hours" : "minutes", timestamp);
2667 2886
2668 if (days_left > days_till_exp_crit) { 2887 if (days_left > days_till_exp_crit) {
2669 status = STATE_WARNING; 2888 status = STATE_WARNING;
@@ -2674,8 +2893,8 @@ HAVE_FIRST_CERT:
2674 printf(_("CRITICAL - Certificate '%s' expired on %s.\n"), host_name, timestamp); 2893 printf(_("CRITICAL - Certificate '%s' expired on %s.\n"), host_name, timestamp);
2675 status = STATE_CRITICAL; 2894 status = STATE_CRITICAL;
2676 } else if (days_left == 0) { 2895 } else if (days_left == 0) {
2677 printf(_("%s - Certificate '%s' just expired (%s).\n"), (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", host_name, 2896 printf(_("%s - Certificate '%s' just expired (%s).\n"),
2678 timestamp); 2897 (days_left > days_till_exp_crit) ? "WARNING" : "CRITICAL", host_name, timestamp);
2679 if (days_left > days_till_exp_crit) { 2898 if (days_left > days_till_exp_crit) {
2680 status = STATE_WARNING; 2899 status = STATE_WARNING;
2681 } else { 2900 } else {