diff options
Diffstat (limited to 'plugins/check_curl.c')
-rw-r--r-- | plugins/check_curl.c | 155 |
1 files changed, 105 insertions, 50 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index d0871c48..d3bddacd 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
@@ -134,6 +134,7 @@ char regexp[MAX_RE_SIZE]; | |||
134 | int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; | 134 | int cflags = REG_NOSUB | REG_EXTENDED | REG_NEWLINE; |
135 | int errcode; | 135 | int errcode; |
136 | bool invert_regex = false; | 136 | bool invert_regex = false; |
137 | int state_regex = STATE_CRITICAL; | ||
137 | 138 | ||
138 | char *server_address = NULL; | 139 | char *server_address = NULL; |
139 | char *host_name = NULL; | 140 | char *host_name = NULL; |
@@ -213,6 +214,7 @@ char *client_privkey = NULL; | |||
213 | char *ca_cert = NULL; | 214 | char *ca_cert = NULL; |
214 | bool verify_peer_and_host = false; | 215 | bool verify_peer_and_host = false; |
215 | bool is_openssl_callback = false; | 216 | bool is_openssl_callback = false; |
217 | bool add_sslctx_verify_fun = false; | ||
216 | #if defined(HAVE_SSL) && defined(USE_OPENSSL) | 218 | #if defined(HAVE_SSL) && defined(USE_OPENSSL) |
217 | X509 *cert = NULL; | 219 | X509 *cert = NULL; |
218 | #endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ | 220 | #endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ |
@@ -223,6 +225,7 @@ curlhelp_ssl_library ssl_library = CURLHELP_SSL_LIBRARY_UNKNOWN; | |||
223 | int curl_http_version = CURL_HTTP_VERSION_NONE; | 225 | int curl_http_version = CURL_HTTP_VERSION_NONE; |
224 | bool automatic_decompression = false; | 226 | bool automatic_decompression = false; |
225 | char *cookie_jar_file = NULL; | 227 | char *cookie_jar_file = NULL; |
228 | bool haproxy_protocol = false; | ||
226 | 229 | ||
227 | bool process_arguments (int, char**); | 230 | bool process_arguments (int, char**); |
228 | void handle_curl_option_return_code (CURLcode res, const char* option); | 231 | void handle_curl_option_return_code (CURLcode res, const char* option); |
@@ -239,10 +242,10 @@ void print_help (void); | |||
239 | void print_usage (void); | 242 | void print_usage (void); |
240 | void print_curl_version (void); | 243 | void print_curl_version (void); |
241 | int curlhelp_initwritebuffer (curlhelp_write_curlbuf*); | 244 | int curlhelp_initwritebuffer (curlhelp_write_curlbuf*); |
242 | int curlhelp_buffer_write_callback (void*, size_t , size_t , void*); | 245 | size_t curlhelp_buffer_write_callback(void*, size_t , size_t , void*); |
243 | void curlhelp_freewritebuffer (curlhelp_write_curlbuf*); | 246 | void curlhelp_freewritebuffer (curlhelp_write_curlbuf*); |
244 | int curlhelp_initreadbuffer (curlhelp_read_curlbuf *, const char *, size_t); | 247 | int curlhelp_initreadbuffer (curlhelp_read_curlbuf *, const char *, size_t); |
245 | int curlhelp_buffer_read_callback (void *, size_t , size_t , void *); | 248 | size_t curlhelp_buffer_read_callback(void *, size_t , size_t , void *); |
246 | void curlhelp_freereadbuffer (curlhelp_read_curlbuf *); | 249 | void curlhelp_freereadbuffer (curlhelp_read_curlbuf *); |
247 | curlhelp_ssl_library curlhelp_get_ssl_library (); | 250 | curlhelp_ssl_library curlhelp_get_ssl_library (); |
248 | const char* curlhelp_get_ssl_library_string (curlhelp_ssl_library); | 251 | const char* curlhelp_get_ssl_library_string (curlhelp_ssl_library); |
@@ -297,7 +300,7 @@ main (int argc, char **argv) | |||
297 | 300 | ||
298 | int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) | 301 | int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) |
299 | { | 302 | { |
300 | (void) preverify_ok; | 303 | (void) preverify_ok; |
301 | /* TODO: we get all certificates of the chain, so which ones | 304 | /* TODO: we get all certificates of the chain, so which ones |
302 | * should we test? | 305 | * should we test? |
303 | * TODO: is the last certificate always the server certificate? | 306 | * TODO: is the last certificate always the server certificate? |
@@ -322,9 +325,18 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) | |||
322 | 325 | ||
323 | CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) | 326 | CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) |
324 | { | 327 | { |
325 | (void) curl; // ignore unused parameter | 328 | (void) curl; // ignore unused parameter |
326 | (void) parm; // ignore unused parameter | 329 | (void) parm; // ignore unused parameter |
327 | SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, verify_callback); | 330 | if(add_sslctx_verify_fun) { |
331 | SSL_CTX_set_verify(sslctx, SSL_VERIFY_PEER, verify_callback); | ||
332 | } | ||
333 | |||
334 | // workaround for issue: | ||
335 | // OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0 | ||
336 | // see discussion https://github.com/openssl/openssl/discussions/22690 | ||
337 | #ifdef SSL_OP_IGNORE_UNEXPECTED_EOF | ||
338 | SSL_CTX_set_options(sslctx, SSL_OP_IGNORE_UNEXPECTED_EOF); | ||
339 | #endif | ||
328 | 340 | ||
329 | return CURLE_OK; | 341 | return CURLE_OK; |
330 | } | 342 | } |
@@ -395,7 +407,7 @@ lookup_host (const char *host, char *buf, size_t buflen) | |||
395 | char addrstr[100]; | 407 | char addrstr[100]; |
396 | size_t addrstr_len; | 408 | size_t addrstr_len; |
397 | int errcode; | 409 | int errcode; |
398 | void *ptr; | 410 | void *ptr = { 0 }; |
399 | size_t buflen_remaining = buflen - 1; | 411 | size_t buflen_remaining = buflen - 1; |
400 | 412 | ||
401 | memset (&hints, 0, sizeof (hints)); | 413 | memset (&hints, 0, sizeof (hints)); |
@@ -466,6 +478,7 @@ int | |||
466 | check_http (void) | 478 | check_http (void) |
467 | { | 479 | { |
468 | int result = STATE_OK; | 480 | int result = STATE_OK; |
481 | int result_ssl = STATE_OK; | ||
469 | int page_len = 0; | 482 | int page_len = 0; |
470 | int i; | 483 | int i; |
471 | char *force_host_header = NULL; | 484 | char *force_host_header = NULL; |
@@ -485,7 +498,7 @@ check_http (void) | |||
485 | 498 | ||
486 | /* register cleanup function to shut down libcurl properly */ | 499 | /* register cleanup function to shut down libcurl properly */ |
487 | atexit (cleanup); | 500 | atexit (cleanup); |
488 | 501 | ||
489 | if (verbose >= 1) | 502 | if (verbose >= 1) |
490 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_VERBOSE, 1), "CURLOPT_VERBOSE"); | 503 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_VERBOSE, 1), "CURLOPT_VERBOSE"); |
491 | 504 | ||
@@ -520,6 +533,11 @@ check_http (void) | |||
520 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, socket_timeout), "CURLOPT_CONNECTTIMEOUT"); | 533 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_CONNECTTIMEOUT, socket_timeout), "CURLOPT_CONNECTTIMEOUT"); |
521 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_TIMEOUT, socket_timeout), "CURLOPT_TIMEOUT"); | 534 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_TIMEOUT, socket_timeout), "CURLOPT_TIMEOUT"); |
522 | 535 | ||
536 | /* enable haproxy protocol */ | ||
537 | if (haproxy_protocol) { | ||
538 | handle_curl_option_return_code(curl_easy_setopt(curl, CURLOPT_HAPROXYPROTOCOL, 1L), "CURLOPT_HAPROXYPROTOCOL"); | ||
539 | } | ||
540 | |||
523 | // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy | 541 | // fill dns resolve cache to make curl connect to the given server_address instead of the host_name, only required for ssl, because we use the host_name later on to make SNI happy |
524 | if(use_ssl && host_name != NULL) { | 542 | if(use_ssl && host_name != NULL) { |
525 | if ( (res=lookup_host (server_address, addrstr, DEFAULT_BUFFER_SIZE/2)) != 0) { | 543 | if ( (res=lookup_host (server_address, addrstr, DEFAULT_BUFFER_SIZE/2)) != 0) { |
@@ -670,9 +688,8 @@ check_http (void) | |||
670 | * OpenSSL-style libraries only!) */ | 688 | * OpenSSL-style libraries only!) */ |
671 | #ifdef USE_OPENSSL | 689 | #ifdef USE_OPENSSL |
672 | /* libcurl and monitoring plugins built with OpenSSL, good */ | 690 | /* libcurl and monitoring plugins built with OpenSSL, good */ |
673 | handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION"); | 691 | add_sslctx_verify_fun = true; |
674 | is_openssl_callback = true; | 692 | is_openssl_callback = true; |
675 | #else /* USE_OPENSSL */ | ||
676 | #endif /* USE_OPENSSL */ | 693 | #endif /* USE_OPENSSL */ |
677 | /* libcurl is built with OpenSSL, monitoring plugins, so falling | 694 | /* libcurl is built with OpenSSL, monitoring plugins, so falling |
678 | * back to manually extracting certificate information */ | 695 | * back to manually extracting certificate information */ |
@@ -705,12 +722,18 @@ check_http (void) | |||
705 | #else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ | 722 | #else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ |
706 | /* old libcurl, our only hope is OpenSSL, otherwise we are out of luck */ | 723 | /* old libcurl, our only hope is OpenSSL, otherwise we are out of luck */ |
707 | if (ssl_library == CURLHELP_SSL_LIBRARY_OPENSSL || ssl_library == CURLHELP_SSL_LIBRARY_LIBRESSL) | 724 | if (ssl_library == CURLHELP_SSL_LIBRARY_OPENSSL || ssl_library == CURLHELP_SSL_LIBRARY_LIBRESSL) |
708 | handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION"); | 725 | add_sslctx_verify_fun = true; |
709 | else | 726 | else |
710 | die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (no CURLOPT_SSL_CTX_FUNCTION, no OpenSSL library or libcurl too old and has no CURLOPT_CERTINFO)\n"); | 727 | die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates (no CURLOPT_SSL_CTX_FUNCTION, no OpenSSL library or libcurl too old and has no CURLOPT_CERTINFO)\n"); |
711 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ | 728 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ |
712 | } | 729 | } |
713 | 730 | ||
731 | #if LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 10, 6) /* required for CURLOPT_SSL_CTX_FUNCTION */ | ||
732 | // ssl ctx function is not available with all ssl backends | ||
733 | if (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, NULL) != CURLE_UNKNOWN_OPTION) | ||
734 | handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION"); | ||
735 | #endif | ||
736 | |||
714 | #endif /* LIBCURL_FEATURE_SSL */ | 737 | #endif /* LIBCURL_FEATURE_SSL */ |
715 | 738 | ||
716 | /* set default or user-given user agent identification */ | 739 | /* set default or user-given user agent identification */ |
@@ -805,7 +828,7 @@ check_http (void) | |||
805 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_INFILESIZE, (curl_off_t)strlen (http_post_data)), "CURLOPT_INFILESIZE"); | 828 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_INFILESIZE, (curl_off_t)strlen (http_post_data)), "CURLOPT_INFILESIZE"); |
806 | } | 829 | } |
807 | } | 830 | } |
808 | 831 | ||
809 | /* cookie handling */ | 832 | /* cookie handling */ |
810 | if (cookie_jar_file != NULL) { | 833 | if (cookie_jar_file != NULL) { |
811 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_COOKIEJAR, cookie_jar_file), "CURLOPT_COOKIEJAR"); | 834 | handle_curl_option_return_code (curl_easy_setopt (curl, CURLOPT_COOKIEJAR, cookie_jar_file), "CURLOPT_COOKIEJAR"); |
@@ -845,9 +868,9 @@ check_http (void) | |||
845 | /* check certificate with OpenSSL functions, curl has been built against OpenSSL | 868 | /* check certificate with OpenSSL functions, curl has been built against OpenSSL |
846 | * and we actually have OpenSSL in the monitoring tools | 869 | * and we actually have OpenSSL in the monitoring tools |
847 | */ | 870 | */ |
848 | result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); | 871 | result_ssl = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); |
849 | if (!continue_after_check_cert) { | 872 | if (!continue_after_check_cert) { |
850 | return result; | 873 | return result_ssl; |
851 | } | 874 | } |
852 | #else /* USE_OPENSSL */ | 875 | #else /* USE_OPENSSL */ |
853 | die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n"); | 876 | die (STATE_CRITICAL, "HTTP CRITICAL - Cannot retrieve certificates - OpenSSL callback used and not linked against OpenSSL\n"); |
@@ -891,17 +914,17 @@ GOT_FIRST_CERT: | |||
891 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); | 914 | die (STATE_CRITICAL, "HTTP CRITICAL - %s\n", msg); |
892 | } | 915 | } |
893 | BIO_free (cert_BIO); | 916 | BIO_free (cert_BIO); |
894 | result = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); | 917 | result_ssl = np_net_ssl_check_certificate(cert, days_till_exp_warn, days_till_exp_crit); |
895 | if (!continue_after_check_cert) { | 918 | if (!continue_after_check_cert) { |
896 | return result; | 919 | return result_ssl; |
897 | } | 920 | } |
898 | #else /* USE_OPENSSL */ | 921 | #else /* USE_OPENSSL */ |
899 | /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal, | 922 | /* We assume we don't have OpenSSL and np_net_ssl_check_certificate at our disposal, |
900 | * so we use the libcurl CURLINFO data | 923 | * so we use the libcurl CURLINFO data |
901 | */ | 924 | */ |
902 | result = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit); | 925 | result_ssl = net_noopenssl_check_certificate(&cert_ptr, days_till_exp_warn, days_till_exp_crit); |
903 | if (!continue_after_check_cert) { | 926 | if (!continue_after_check_cert) { |
904 | return result; | 927 | return result_ssl; |
905 | } | 928 | } |
906 | #endif /* USE_OPENSSL */ | 929 | #endif /* USE_OPENSSL */ |
907 | } else { | 930 | } else { |
@@ -1127,7 +1150,7 @@ GOT_FIRST_CERT: | |||
1127 | strcpy(msg, tmp); | 1150 | strcpy(msg, tmp); |
1128 | 1151 | ||
1129 | } | 1152 | } |
1130 | result = STATE_CRITICAL; | 1153 | result = state_regex; |
1131 | } else { | 1154 | } else { |
1132 | regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); | 1155 | regerror (errcode, &preg, errbuf, MAX_INPUT_BUFFER); |
1133 | 1156 | ||
@@ -1167,9 +1190,9 @@ GOT_FIRST_CERT: | |||
1167 | else | 1190 | else |
1168 | msg[strlen(msg)-3] = '\0'; | 1191 | msg[strlen(msg)-3] = '\0'; |
1169 | } | 1192 | } |
1170 | 1193 | ||
1171 | /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */ | 1194 | /* TODO: separate _() msg and status code: die (result, "HTTP %s: %s\n", state_text(result), msg); */ |
1172 | die (result, "HTTP %s: %s %d %s%s%s - %d bytes in %.3f second response time %s|%s\n%s%s", | 1195 | 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", |
1173 | state_text(result), string_statuscode (status_line.http_major, status_line.http_minor), | 1196 | state_text(result), string_statuscode (status_line.http_major, status_line.http_minor), |
1174 | status_line.http_code, status_line.msg, | 1197 | status_line.http_code, status_line.msg, |
1175 | strlen(msg) > 0 ? " - " : "", | 1198 | strlen(msg) > 0 ? " - " : "", |
@@ -1179,23 +1202,23 @@ GOT_FIRST_CERT: | |||
1179 | (show_body ? body_buf.buf : ""), | 1202 | (show_body ? body_buf.buf : ""), |
1180 | (show_body ? "\n" : "") ); | 1203 | (show_body ? "\n" : "") ); |
1181 | 1204 | ||
1182 | return result; | 1205 | return max_state_alt(result, result_ssl); |
1183 | } | 1206 | } |
1184 | 1207 | ||
1185 | int | 1208 | int |
1186 | uri_strcmp (const UriTextRangeA range, const char* s) | 1209 | uri_strcmp (const UriTextRangeA range, const char* s) |
1187 | { | 1210 | { |
1188 | if (!range.first) return -1; | 1211 | if (!range.first) return -1; |
1189 | if (range.afterLast - range.first < strlen (s)) return -1; | 1212 | if ( (size_t)(range.afterLast - range.first) < strlen (s) ) return -1; |
1190 | return strncmp (s, range.first, min( range.afterLast - range.first, strlen (s))); | 1213 | return strncmp (s, range.first, min( (size_t)(range.afterLast - range.first), strlen (s))); |
1191 | } | 1214 | } |
1192 | 1215 | ||
1193 | char* | 1216 | char* |
1194 | uri_string (const UriTextRangeA range, char* buf, size_t buflen) | 1217 | uri_string (const UriTextRangeA range, char* buf, size_t buflen) |
1195 | { | 1218 | { |
1196 | if (!range.first) return "(null)"; | 1219 | if (!range.first) return "(null)"; |
1197 | strncpy (buf, range.first, max (buflen-1, range.afterLast - range.first)); | 1220 | strncpy (buf, range.first, max (buflen-1, (size_t)(range.afterLast - range.first))); |
1198 | buf[max (buflen-1, range.afterLast - range.first)] = '\0'; | 1221 | buf[max (buflen-1, (size_t)(range.afterLast - range.first))] = '\0'; |
1199 | buf[range.afterLast - range.first] = '\0'; | 1222 | buf[range.afterLast - range.first] = '\0'; |
1200 | return buf; | 1223 | return buf; |
1201 | } | 1224 | } |
@@ -1218,6 +1241,10 @@ redir (curlhelp_write_curlbuf* header_buf) | |||
1218 | &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, | 1241 | &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, |
1219 | headers, &nof_headers, 0); | 1242 | headers, &nof_headers, 0); |
1220 | 1243 | ||
1244 | if (res == -1) { | ||
1245 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); | ||
1246 | } | ||
1247 | |||
1221 | location = get_header_value (headers, nof_headers, "location"); | 1248 | location = get_header_value (headers, nof_headers, "location"); |
1222 | 1249 | ||
1223 | if (verbose >= 2) | 1250 | if (verbose >= 2) |
@@ -1274,10 +1301,12 @@ redir (curlhelp_write_curlbuf* header_buf) | |||
1274 | } | 1301 | } |
1275 | } | 1302 | } |
1276 | 1303 | ||
1277 | if (!uri_strcmp (uri.scheme, "https")) | 1304 | if (uri.scheme.first) { |
1278 | use_ssl = true; | 1305 | if (!uri_strcmp (uri.scheme, "https")) |
1279 | else | 1306 | use_ssl = true; |
1280 | use_ssl = false; | 1307 | else |
1308 | use_ssl = false; | ||
1309 | } | ||
1281 | 1310 | ||
1282 | /* we do a sloppy test here only, because uriparser would have failed | 1311 | /* we do a sloppy test here only, because uriparser would have failed |
1283 | * above, if the port would be invalid, we just check for MAX_PORT | 1312 | * above, if the port would be invalid, we just check for MAX_PORT |
@@ -1295,10 +1324,13 @@ redir (curlhelp_write_curlbuf* header_buf) | |||
1295 | MAX_PORT, location, display_html ? "</A>" : ""); | 1324 | MAX_PORT, location, display_html ? "</A>" : ""); |
1296 | 1325 | ||
1297 | /* by RFC 7231 relative URLs in Location should be taken relative to | 1326 | /* by RFC 7231 relative URLs in Location should be taken relative to |
1298 | * the original URL, so wy try to form a new absolute URL here | 1327 | * the original URL, so we try to form a new absolute URL here |
1299 | */ | 1328 | */ |
1300 | if (!uri.scheme.first && !uri.hostText.first) { | 1329 | if (!uri.scheme.first && !uri.hostText.first) { |
1301 | new_host = strdup (host_name ? host_name : server_address); | 1330 | new_host = strdup (host_name ? host_name : server_address); |
1331 | new_port = server_port; | ||
1332 | if(use_ssl) | ||
1333 | uri_string (uri.scheme, "https", DEFAULT_BUFFER_SIZE); | ||
1302 | } else { | 1334 | } else { |
1303 | new_host = strdup (uri_string (uri.hostText, buf, DEFAULT_BUFFER_SIZE)); | 1335 | new_host = strdup (uri_string (uri.hostText, buf, DEFAULT_BUFFER_SIZE)); |
1304 | } | 1336 | } |
@@ -1380,7 +1412,9 @@ process_arguments (int argc, char **argv) | |||
1380 | CA_CERT_OPTION, | 1412 | CA_CERT_OPTION, |
1381 | HTTP_VERSION_OPTION, | 1413 | HTTP_VERSION_OPTION, |
1382 | AUTOMATIC_DECOMPRESSION, | 1414 | AUTOMATIC_DECOMPRESSION, |
1383 | COOKIE_JAR | 1415 | COOKIE_JAR, |
1416 | HAPROXY_PROTOCOL, | ||
1417 | STATE_REGEX | ||
1384 | }; | 1418 | }; |
1385 | 1419 | ||
1386 | int option = 0; | 1420 | int option = 0; |
@@ -1419,6 +1453,7 @@ process_arguments (int argc, char **argv) | |||
1419 | {"content-type", required_argument, 0, 'T'}, | 1453 | {"content-type", required_argument, 0, 'T'}, |
1420 | {"pagesize", required_argument, 0, 'm'}, | 1454 | {"pagesize", required_argument, 0, 'm'}, |
1421 | {"invert-regex", no_argument, NULL, INVERT_REGEX}, | 1455 | {"invert-regex", no_argument, NULL, INVERT_REGEX}, |
1456 | {"state-regex", required_argument, 0, STATE_REGEX}, | ||
1422 | {"use-ipv4", no_argument, 0, '4'}, | 1457 | {"use-ipv4", no_argument, 0, '4'}, |
1423 | {"use-ipv6", no_argument, 0, '6'}, | 1458 | {"use-ipv6", no_argument, 0, '6'}, |
1424 | {"extended-perfdata", no_argument, 0, 'E'}, | 1459 | {"extended-perfdata", no_argument, 0, 'E'}, |
@@ -1427,6 +1462,7 @@ process_arguments (int argc, char **argv) | |||
1427 | {"http-version", required_argument, 0, HTTP_VERSION_OPTION}, | 1462 | {"http-version", required_argument, 0, HTTP_VERSION_OPTION}, |
1428 | {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION}, | 1463 | {"enable-automatic-decompression", no_argument, 0, AUTOMATIC_DECOMPRESSION}, |
1429 | {"cookie-jar", required_argument, 0, COOKIE_JAR}, | 1464 | {"cookie-jar", required_argument, 0, COOKIE_JAR}, |
1465 | {"haproxy-protocol", no_argument, 0, HAPROXY_PROTOCOL}, | ||
1430 | {0, 0, 0, 0} | 1466 | {0, 0, 0, 0} |
1431 | }; | 1467 | }; |
1432 | 1468 | ||
@@ -1694,7 +1730,7 @@ process_arguments (int argc, char **argv) | |||
1694 | else { | 1730 | else { |
1695 | max_depth = atoi (optarg); | 1731 | max_depth = atoi (optarg); |
1696 | } | 1732 | } |
1697 | break; | 1733 | break; |
1698 | case 'f': /* onredirect */ | 1734 | case 'f': /* onredirect */ |
1699 | if (!strcmp (optarg, "ok")) | 1735 | if (!strcmp (optarg, "ok")) |
1700 | onredirect = STATE_OK; | 1736 | onredirect = STATE_OK; |
@@ -1753,6 +1789,13 @@ process_arguments (int argc, char **argv) | |||
1753 | case INVERT_REGEX: | 1789 | case INVERT_REGEX: |
1754 | invert_regex = true; | 1790 | invert_regex = true; |
1755 | break; | 1791 | break; |
1792 | case STATE_REGEX: | ||
1793 | if (!strcasecmp (optarg, "critical")) | ||
1794 | state_regex = STATE_CRITICAL; | ||
1795 | else if (!strcasecmp (optarg, "warning")) | ||
1796 | state_regex = STATE_WARNING; | ||
1797 | else usage2 (_("Invalid state-regex option"), optarg); | ||
1798 | break; | ||
1756 | case '4': | 1799 | case '4': |
1757 | address_family = AF_INET; | 1800 | address_family = AF_INET; |
1758 | break; | 1801 | break; |
@@ -1837,6 +1880,9 @@ process_arguments (int argc, char **argv) | |||
1837 | case COOKIE_JAR: | 1880 | case COOKIE_JAR: |
1838 | cookie_jar_file = optarg; | 1881 | cookie_jar_file = optarg; |
1839 | break; | 1882 | break; |
1883 | case HAPROXY_PROTOCOL: | ||
1884 | haproxy_protocol = true; | ||
1885 | break; | ||
1840 | case '?': | 1886 | case '?': |
1841 | /* print short usage statement if args not parsable */ | 1887 | /* print short usage statement if args not parsable */ |
1842 | usage5 (); | 1888 | usage5 (); |
@@ -1977,8 +2023,11 @@ print_help (void) | |||
1977 | printf (" %s\n", _("Note: SNI is not supported in libcurl before 7.18.1")); | 2023 | printf (" %s\n", _("Note: SNI is not supported in libcurl before 7.18.1")); |
1978 | #endif | 2024 | #endif |
1979 | printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); | 2025 | printf (" %s\n", "-C, --certificate=INTEGER[,INTEGER]"); |
1980 | printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443")); | 2026 | printf (" %s\n", _("Minimum number of days a certificate has to be valid. Port defaults to 443.")); |
1981 | printf (" %s\n", _("(when this option is used the URL is not checked by default. You can use")); | 2027 | printf (" %s\n", _("A STATE_WARNING is returned if the certificate has a validity less than the")); |
2028 | printf (" %s\n", _("first agument's value. If there is a second argument and the certificate's")); | ||
2029 | printf (" %s\n", _("validity is less than its value, a STATE_CRITICAL is returned.")); | ||
2030 | printf (" %s\n", _("(When this option is used the URL is not checked by default. You can use")); | ||
1982 | printf (" %s\n", _(" --continue-after-certificate to override this behavior)")); | 2031 | printf (" %s\n", _(" --continue-after-certificate to override this behavior)")); |
1983 | printf (" %s\n", "--continue-after-certificate"); | 2032 | printf (" %s\n", "--continue-after-certificate"); |
1984 | printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check.")); | 2033 | printf (" %s\n", _("Allows the HTTP check to continue after performing the certificate check.")); |
@@ -2007,7 +2056,7 @@ print_help (void) | |||
2007 | printf (" %s\n", "-u, --url=PATH"); | 2056 | printf (" %s\n", "-u, --url=PATH"); |
2008 | printf (" %s\n", _("URL to GET or POST (default: /)")); | 2057 | printf (" %s\n", _("URL to GET or POST (default: /)")); |
2009 | printf (" %s\n", "-P, --post=STRING"); | 2058 | printf (" %s\n", "-P, --post=STRING"); |
2010 | printf (" %s\n", _("URL encoded http POST data")); | 2059 | printf (" %s\n", _("URL decoded http POST data")); |
2011 | printf (" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)"); | 2060 | printf (" %s\n", "-j, --method=STRING (for example: HEAD, OPTIONS, TRACE, PUT, DELETE, CONNECT)"); |
2012 | printf (" %s\n", _("Set HTTP method.")); | 2061 | printf (" %s\n", _("Set HTTP method.")); |
2013 | printf (" %s\n", "-N, --no-body"); | 2062 | printf (" %s\n", "-N, --no-body"); |
@@ -2025,7 +2074,10 @@ print_help (void) | |||
2025 | printf (" %s\n", "-R, --eregi=STRING"); | 2074 | printf (" %s\n", "-R, --eregi=STRING"); |
2026 | printf (" %s\n", _("Search page for case-insensitive regex STRING")); | 2075 | printf (" %s\n", _("Search page for case-insensitive regex STRING")); |
2027 | printf (" %s\n", "--invert-regex"); | 2076 | printf (" %s\n", "--invert-regex"); |
2028 | printf (" %s\n", _("Return CRITICAL if found, OK if not\n")); | 2077 | printf (" %s\n", _("Return STATE if found, OK if not (STATE is CRITICAL, per default)")); |
2078 | printf (" %s\n", _("can be changed with --state--regex)")); | ||
2079 | printf (" %s\n", "--state-regex=STATE"); | ||
2080 | printf (" %s\n", _("Return STATE if regex is found, OK if not. STATE can be one of \"critical\",\"warning\"")); | ||
2029 | printf (" %s\n", "-a, --authorization=AUTH_PAIR"); | 2081 | printf (" %s\n", "-a, --authorization=AUTH_PAIR"); |
2030 | printf (" %s\n", _("Username:password on sites with basic authentication")); | 2082 | printf (" %s\n", _("Username:password on sites with basic authentication")); |
2031 | printf (" %s\n", "-b, --proxy-authorization=AUTH_PAIR"); | 2083 | printf (" %s\n", "-b, --proxy-authorization=AUTH_PAIR"); |
@@ -2056,7 +2108,9 @@ print_help (void) | |||
2056 | printf (" %s\n", _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)")); | 2108 | printf (" %s\n", _("1.0 = HTTP/1.0, 1.1 = HTTP/1.1, 2.0 = HTTP/2 (HTTP/2 will fail without -S)")); |
2057 | printf (" %s\n", "--enable-automatic-decompression"); | 2109 | printf (" %s\n", "--enable-automatic-decompression"); |
2058 | printf (" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING).")); | 2110 | printf (" %s\n", _("Enable automatic decompression of body (CURLOPT_ACCEPT_ENCODING).")); |
2059 | printf (" %s\n", "---cookie-jar=FILE"); | 2111 | printf(" %s\n", "--haproxy-protocol"); |
2112 | printf(" %s\n", _("Send HAProxy proxy protocol v1 header (CURLOPT_HAPROXYPROTOCOL).")); | ||
2113 | printf (" %s\n", "--cookie-jar=FILE"); | ||
2060 | printf (" %s\n", _("Store cookies in the cookie jar and send them out when requested.")); | 2114 | printf (" %s\n", _("Store cookies in the cookie jar and send them out when requested.")); |
2061 | printf ("\n"); | 2115 | printf ("\n"); |
2062 | 2116 | ||
@@ -2140,7 +2194,7 @@ print_usage (void) | |||
2140 | printf (" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport|curl>]\n"); | 2194 | printf (" [-b proxy_auth] [-f <ok|warning|critical|follow|sticky|stickyport|curl>]\n"); |
2141 | printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); | 2195 | printf (" [-e <expect>] [-d string] [-s string] [-l] [-r <regex> | -R <case-insensitive regex>]\n"); |
2142 | printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); | 2196 | printf (" [-P string] [-m <min_pg_size>:<max_pg_size>] [-4|-6] [-N] [-M <age>]\n"); |
2143 | printf (" [-A string] [-k string] [-S <version>] [--sni]\n"); | 2197 | printf (" [-A string] [-k string] [-S <version>] [--sni] [--haproxy-protocol]\n"); |
2144 | printf (" [-T <content-type>] [-j method]\n"); | 2198 | printf (" [-T <content-type>] [-j method]\n"); |
2145 | printf (" [--http-version=<version>] [--enable-automatic-decompression]\n"); | 2199 | printf (" [--http-version=<version>] [--enable-automatic-decompression]\n"); |
2146 | printf (" [--cookie-jar=<cookie jar file>\n"); | 2200 | printf (" [--cookie-jar=<cookie jar file>\n"); |
@@ -2151,8 +2205,6 @@ print_usage (void) | |||
2151 | printf ("%s\n", _("In the first form, make an HTTP request.")); | 2205 | printf ("%s\n", _("In the first form, make an HTTP request.")); |
2152 | printf ("%s\n\n", _("In the second form, connect to the server and check the TLS certificate.")); | 2206 | printf ("%s\n\n", _("In the second form, connect to the server and check the TLS certificate.")); |
2153 | #endif | 2207 | #endif |
2154 | printf ("%s\n", _("WARNING: check_curl is experimental. Please use")); | ||
2155 | printf ("%s\n\n", _("check_http if you need a stable version.")); | ||
2156 | } | 2208 | } |
2157 | 2209 | ||
2158 | void | 2210 | void |
@@ -2171,8 +2223,7 @@ curlhelp_initwritebuffer (curlhelp_write_curlbuf *buf) | |||
2171 | return 0; | 2223 | return 0; |
2172 | } | 2224 | } |
2173 | 2225 | ||
2174 | int | 2226 | size_t curlhelp_buffer_write_callback (void *buffer, size_t size, size_t nmemb, void *stream) |
2175 | curlhelp_buffer_write_callback (void *buffer, size_t size, size_t nmemb, void *stream) | ||
2176 | { | 2227 | { |
2177 | curlhelp_write_curlbuf *buf = (curlhelp_write_curlbuf *)stream; | 2228 | curlhelp_write_curlbuf *buf = (curlhelp_write_curlbuf *)stream; |
2178 | 2229 | ||
@@ -2192,8 +2243,7 @@ curlhelp_buffer_write_callback (void *buffer, size_t size, size_t nmemb, void *s | |||
2192 | return (int)(size * nmemb); | 2243 | return (int)(size * nmemb); |
2193 | } | 2244 | } |
2194 | 2245 | ||
2195 | int | 2246 | size_t curlhelp_buffer_read_callback(void *buffer, size_t size, size_t nmemb, void *stream) |
2196 | curlhelp_buffer_read_callback (void *buffer, size_t size, size_t nmemb, void *stream) | ||
2197 | { | 2247 | { |
2198 | curlhelp_read_curlbuf *buf = (curlhelp_read_curlbuf *)stream; | 2248 | curlhelp_read_curlbuf *buf = (curlhelp_read_curlbuf *)stream; |
2199 | 2249 | ||
@@ -2366,8 +2416,7 @@ remove_newlines (char *s) | |||
2366 | char * | 2416 | char * |
2367 | get_header_value (const struct phr_header* headers, const size_t nof_headers, const char* header) | 2417 | get_header_value (const struct phr_header* headers, const size_t nof_headers, const char* header) |
2368 | { | 2418 | { |
2369 | int i; | 2419 | for(size_t i = 0; i < nof_headers; i++ ) { |
2370 | for( i = 0; i < nof_headers; i++ ) { | ||
2371 | if(headers[i].name != NULL && strncasecmp( header, headers[i].name, max( headers[i].name_len, 4 ) ) == 0 ) { | 2420 | if(headers[i].name != NULL && strncasecmp( header, headers[i].name, max( headers[i].name_len, 4 ) ) == 0 ) { |
2372 | return strndup( headers[i].value, headers[i].value_len ); | 2421 | return strndup( headers[i].value, headers[i].value_len ); |
2373 | } | 2422 | } |
@@ -2390,6 +2439,10 @@ check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFA | |||
2390 | &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, | 2439 | &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, |
2391 | headers, &nof_headers, 0); | 2440 | headers, &nof_headers, 0); |
2392 | 2441 | ||
2442 | if (res == -1) { | ||
2443 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); | ||
2444 | } | ||
2445 | |||
2393 | server_date = get_header_value (headers, nof_headers, "date"); | 2446 | server_date = get_header_value (headers, nof_headers, "date"); |
2394 | document_date = get_header_value (headers, nof_headers, "last-modified"); | 2447 | document_date = get_header_value (headers, nof_headers, "last-modified"); |
2395 | 2448 | ||
@@ -2465,9 +2518,7 @@ check_document_dates (const curlhelp_write_curlbuf *header_buf, char (*msg)[DEFA | |||
2465 | int | 2518 | int |
2466 | get_content_length (const curlhelp_write_curlbuf* header_buf, const curlhelp_write_curlbuf* body_buf) | 2519 | get_content_length (const curlhelp_write_curlbuf* header_buf, const curlhelp_write_curlbuf* body_buf) |
2467 | { | 2520 | { |
2468 | const char *s; | 2521 | size_t content_length = 0; |
2469 | int content_length = 0; | ||
2470 | char *copy; | ||
2471 | struct phr_header headers[255]; | 2522 | struct phr_header headers[255]; |
2472 | size_t nof_headers = 255; | 2523 | size_t nof_headers = 255; |
2473 | size_t msglen; | 2524 | size_t msglen; |
@@ -2478,6 +2529,10 @@ get_content_length (const curlhelp_write_curlbuf* header_buf, const curlhelp_wri | |||
2478 | &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, | 2529 | &status_line.http_major, &status_line.http_minor, &status_line.http_code, &status_line.msg, &msglen, |
2479 | headers, &nof_headers, 0); | 2530 | headers, &nof_headers, 0); |
2480 | 2531 | ||
2532 | if (res == -1) { | ||
2533 | die (STATE_UNKNOWN, _("HTTP UNKNOWN - Failed to parse Response\n")); | ||
2534 | } | ||
2535 | |||
2481 | content_length_s = get_header_value (headers, nof_headers, "content-length"); | 2536 | content_length_s = get_header_value (headers, nof_headers, "content-length"); |
2482 | if (!content_length_s) { | 2537 | if (!content_length_s) { |
2483 | return header_buf->buflen + body_buf->buflen; | 2538 | return header_buf->buflen + body_buf->buflen; |