diff options
author | Sven Nierlein <sven@consol.de> | 2024-10-09 07:50:39 (GMT) |
---|---|---|
committer | Sven Nierlein <sven@nierlein.org> | 2024-10-10 13:54:28 (GMT) |
commit | 3b960442485b965d853205bddeaa7f6a6b03253e (patch) | |
tree | 9479c52cce02ca7928fa43c0113d46e7d5e9a2b3 | |
parent | 114e504403d1e06eccac08e7b8d99e0614581515 (diff) | |
download | monitoring-plugins-3b960442485b965d853205bddeaa7f6a6b03253e.tar.gz |
fix check_curl: OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0
using check_curl on a probably embedded device responding as 'Server: GoAhead-Webs'
%> check_curl -H ... -S -vvv
> GET / HTTP/1.1
Host: ...
User-Agent: check_curl/v2.4.0 (monitoring-plugins 2.4.0, libcurl/7.76.1 OpenSSL/3.0.7 zlib/1.2.11 brotli/1.0.9 libidn2/2.3.0 libpsl/0.21.1 (+libidn2/2.3.0) libssh/0.10.4/openssl/zlib nghttp2/1.43.0)
Accept: */*
Connection: close
* Mark bundle as not supporting multiuse
* HTTP 1.0, assume close after body
< HTTP/1.0 302 Redirect
< Server: GoAhead-Webs
< Date: Tue Mar 26 17:57:16 2019
< Cache-Control: no-cache, no-store, must-revalidate,private
< Pragma: no-cache
< Expires: 0
< Content-Type: text/html
< X-Frame-Options: sameorigin
< X-XSS-Protection: 1; mode=block
< X-Content-Type-Options: nosniff
< Location: https://...
<
* OpenSSL SSL_read: error:0A000126:SSL routines::unexpected eof while reading, errno 0
* Closing connection 0
reading the discussion on https://github.com/openssl/openssl/discussions/22690 suggest to set the option SSL_OP_IGNORE_UNEXPECTED_EOF
which makes check_curl behave like check_http at this point.
Since this is a rather new flag, fencing it in ifdefs.
And since there can only be one ssl ctx function, we need to move both tasks into one function.
-rw-r--r-- | plugins/check_curl.c | 29 |
1 files changed, 22 insertions, 7 deletions
diff --git a/plugins/check_curl.c b/plugins/check_curl.c index 7f45b5a..d3bddac 100644 --- a/plugins/check_curl.c +++ b/plugins/check_curl.c | |||
@@ -214,6 +214,7 @@ char *client_privkey = NULL; | |||
214 | char *ca_cert = NULL; | 214 | char *ca_cert = NULL; |
215 | bool verify_peer_and_host = false; | 215 | bool verify_peer_and_host = false; |
216 | bool is_openssl_callback = false; | 216 | bool is_openssl_callback = false; |
217 | bool add_sslctx_verify_fun = false; | ||
217 | #if defined(HAVE_SSL) && defined(USE_OPENSSL) | 218 | #if defined(HAVE_SSL) && defined(USE_OPENSSL) |
218 | X509 *cert = NULL; | 219 | X509 *cert = NULL; |
219 | #endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ | 220 | #endif /* defined(HAVE_SSL) && defined(USE_OPENSSL) */ |
@@ -299,7 +300,7 @@ main (int argc, char **argv) | |||
299 | 300 | ||
300 | int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) | 301 | int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) |
301 | { | 302 | { |
302 | (void) preverify_ok; | 303 | (void) preverify_ok; |
303 | /* TODO: we get all certificates of the chain, so which ones | 304 | /* TODO: we get all certificates of the chain, so which ones |
304 | * should we test? | 305 | * should we test? |
305 | * TODO: is the last certificate always the server certificate? | 306 | * TODO: is the last certificate always the server certificate? |
@@ -324,9 +325,18 @@ int verify_callback(int preverify_ok, X509_STORE_CTX *x509_ctx) | |||
324 | 325 | ||
325 | CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) | 326 | CURLcode sslctxfun(CURL *curl, SSL_CTX *sslctx, void *parm) |
326 | { | 327 | { |
327 | (void) curl; // ignore unused parameter | 328 | (void) curl; // ignore unused parameter |
328 | (void) parm; // ignore unused parameter | 329 | (void) parm; // ignore unused parameter |
329 | 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 | ||
330 | 340 | ||
331 | return CURLE_OK; | 341 | return CURLE_OK; |
332 | } | 342 | } |
@@ -678,9 +688,8 @@ check_http (void) | |||
678 | * OpenSSL-style libraries only!) */ | 688 | * OpenSSL-style libraries only!) */ |
679 | #ifdef USE_OPENSSL | 689 | #ifdef USE_OPENSSL |
680 | /* libcurl and monitoring plugins built with OpenSSL, good */ | 690 | /* libcurl and monitoring plugins built with OpenSSL, good */ |
681 | handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION"); | 691 | add_sslctx_verify_fun = true; |
682 | is_openssl_callback = true; | 692 | is_openssl_callback = true; |
683 | #else /* USE_OPENSSL */ | ||
684 | #endif /* USE_OPENSSL */ | 693 | #endif /* USE_OPENSSL */ |
685 | /* libcurl is built with OpenSSL, monitoring plugins, so falling | 694 | /* libcurl is built with OpenSSL, monitoring plugins, so falling |
686 | * back to manually extracting certificate information */ | 695 | * back to manually extracting certificate information */ |
@@ -713,12 +722,18 @@ check_http (void) | |||
713 | #else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ | 722 | #else /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ |
714 | /* 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 */ |
715 | 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) |
716 | handle_curl_option_return_code (curl_easy_setopt(curl, CURLOPT_SSL_CTX_FUNCTION, sslctxfun), "CURLOPT_SSL_CTX_FUNCTION"); | 725 | add_sslctx_verify_fun = true; |
717 | else | 726 | else |
718 | 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"); |
719 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ | 728 | #endif /* LIBCURL_VERSION_NUM >= MAKE_LIBCURL_VERSION(7, 19, 1) */ |
720 | } | 729 | } |
721 | 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 | |||
722 | #endif /* LIBCURL_FEATURE_SSL */ | 737 | #endif /* LIBCURL_FEATURE_SSL */ |
723 | 738 | ||
724 | /* set default or user-given user agent identification */ | 739 | /* set default or user-given user agent identification */ |