Skip to content

Commit 38878d4

Browse files
committed
http: report errors when curl_easy_setopt fails
improve macro usage and debug/error printouts Signed-off-by: Hans Zandbelt <[email protected]>
1 parent 6b9e982 commit 38878d4

File tree

2 files changed

+73
-73
lines changed

2 files changed

+73
-73
lines changed

ChangeLog

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
1+
12/16/2024
2+
- http: report errors when curl_easy_setopt fails and improve macro usage
3+
14
12/15/2024
25
- add Coverity Github action
3-
- http: report errors when curl_easy_setopt fails for CURLOPT_SSL_OPTIONS
46

57
12/13/2024
68
- address warnings from static code analysis tool Coverity

src/http.c

Lines changed: 70 additions & 72 deletions
Original file line numberDiff line numberDiff line change
@@ -605,69 +605,66 @@ char *oidc_http_form_encoded_data(request_rec *r, const apr_table_t *params) {
605605
return data;
606606
}
607607

608+
/*
609+
* call curl_easy_setopt with error checking and reporting
610+
*/
611+
#define OIDC_HTTP_CURL_SETOPT_PARMS(r, curl, code, option, ...) \
612+
code = curl_easy_setopt(curl, option, __VA_ARGS__); \
613+
if (code != CURLE_OK) \
614+
oidc_error(r, "curl_easy_setopt(%s) failed with: %s", #option, curl_easy_strerror(code))
615+
616+
#define OIDC_HTTP_CURL_SETOPT(...) OIDC_HTTP_CURL_SETOPT_PARMS(r, curl, code, __VA_ARGS__)
617+
608618
/*
609619
* set libcurl SSL options
610620
*/
611621

612-
#define OIDC_CURLOPT_SSL_OPTIONS "CURLOPT_SSL_OPTIONS"
622+
#define OIDC_CURLOPT_SSL_OPTIONS_ENV_VAR_NAME "CURLOPT_SSL_OPTIONS"
613623

614-
#define OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, option, key, val) \
615-
if (_oidc_strstr(env_var_value, option) != NULL) { \
616-
oidc_debug(r, "curl_easy_setopt (%d) %s (%d)", key, option, val); \
617-
code = curl_easy_setopt(curl, key, val); \
618-
if (code != CURLE_OK) \
619-
oidc_error(r, "curl_easy_setopt for '%s' failed with: %s", option, curl_easy_strerror(code)); \
624+
#define OIDC_HTTP_CURL_SETOPT_SSL(option, value) \
625+
if (_oidc_strstr(env_var_value, #value) != NULL) { \
626+
oidc_debug(r, "curl_easy_setopt(%s): %s (%d)", #option, #value, value); \
627+
OIDC_HTTP_CURL_SETOPT(option, value); \
620628
}
621629

622630
static void oidc_http_set_curl_ssl_options(request_rec *r, CURL *curl) {
631+
// NB: the variable names r, curl, code and env_var_value are used in the OIDC_HTTP_CURL_SETOPT_SSL macro
623632
const char *env_var_value = NULL;
624633
CURLcode code = CURLE_OK;
625634
if (r->subprocess_env != NULL)
626-
env_var_value = apr_table_get(r->subprocess_env, OIDC_CURLOPT_SSL_OPTIONS);
635+
env_var_value = apr_table_get(r->subprocess_env, OIDC_CURLOPT_SSL_OPTIONS_ENV_VAR_NAME);
627636
if (env_var_value == NULL)
628637
return;
629-
oidc_debug(r, "SSL options environment variable %s=%s found", OIDC_CURLOPT_SSL_OPTIONS, env_var_value);
638+
oidc_debug(r, "SSL options environment variable %s=%s found", OIDC_CURLOPT_SSL_OPTIONS_ENV_VAR_NAME,
639+
env_var_value);
630640
#if LIBCURL_VERSION_NUM >= 0x071900
631-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURLSSLOPT_ALLOW_BEAST", CURLOPT_SSL_OPTIONS,
632-
CURLSSLOPT_ALLOW_BEAST)
641+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSL_OPTIONS, CURLSSLOPT_ALLOW_BEAST);
633642
#endif
634643
#if LIBCURL_VERSION_NUM >= 0x072c00
635-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURLSSLOPT_NO_REVOKE", CURLOPT_SSL_OPTIONS,
636-
CURLSSLOPT_NO_REVOKE)
644+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_REVOKE)
637645
#endif
638646
#if LIBCURL_VERSION_NUM >= 0x074400
639-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURLSSLOPT_NO_PARTIALCHAIN", CURLOPT_SSL_OPTIONS,
640-
CURLSSLOPT_NO_PARTIALCHAIN)
647+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NO_PARTIALCHAIN)
641648
#endif
642649
#if LIBCURL_VERSION_NUM >= 0x074600
643-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURLSSLOPT_REVOKE_BEST_EFFORT", CURLOPT_SSL_OPTIONS,
644-
CURLSSLOPT_REVOKE_BEST_EFFORT)
650+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSL_OPTIONS, CURLSSLOPT_REVOKE_BEST_EFFORT)
645651
#endif
646652
#if LIBCURL_VERSION_NUM >= 0x074700
647-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURLSSLOPT_NATIVE_CA", CURLOPT_SSL_OPTIONS,
648-
CURLSSLOPT_NATIVE_CA)
653+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSL_OPTIONS, CURLSSLOPT_NATIVE_CA)
649654
#endif
650655
#if LIBCURL_VERSION_NUM >= 0x072200
651-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURL_SSLVERSION_TLSv1_0", CURLOPT_SSLVERSION,
652-
CURL_SSLVERSION_TLSv1_0)
653-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURL_SSLVERSION_TLSv1_1", CURLOPT_SSLVERSION,
654-
CURL_SSLVERSION_TLSv1_1)
655-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURL_SSLVERSION_TLSv1_2", CURLOPT_SSLVERSION,
656-
CURL_SSLVERSION_TLSv1_2)
656+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_0)
657+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_1)
658+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_2)
657659
#endif
658660
#if LIBCURL_VERSION_NUM >= 0x073400
659-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURL_SSLVERSION_TLSv1_3", CURLOPT_SSLVERSION,
660-
CURL_SSLVERSION_TLSv1_3)
661+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSLVERSION, CURL_SSLVERSION_TLSv1_3)
661662
#endif
662663
#if LIBCURL_VERSION_NUM >= 0x073600
663-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURL_SSLVERSION_MAX_TLSv1_0", CURLOPT_SSLVERSION,
664-
CURL_SSLVERSION_MAX_TLSv1_0)
665-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURL_SSLVERSION_MAX_TLSv1_1", CURLOPT_SSLVERSION,
666-
CURL_SSLVERSION_MAX_TLSv1_1)
667-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURL_SSLVERSION_MAX_TLSv1_2", CURLOPT_SSLVERSION,
668-
CURL_SSLVERSION_MAX_TLSv1_2)
669-
OIDC_HTTP_SET_CURL_OPTION(r, curl, code, env_var_value, "CURL_SSLVERSION_MAX_TLSv1_3", CURLOPT_SSLVERSION,
670-
CURL_SSLVERSION_MAX_TLSv1_3)
664+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSLVERSION, CURL_SSLVERSION_MAX_TLSv1_0)
665+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSLVERSION, CURL_SSLVERSION_MAX_TLSv1_1)
666+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSLVERSION, CURL_SSLVERSION_MAX_TLSv1_2)
667+
OIDC_HTTP_CURL_SETOPT_SSL(CURLOPT_SSLVERSION, CURL_SSLVERSION_MAX_TLSv1_3)
671668
#endif
672669
}
673670

@@ -707,10 +704,12 @@ static apr_byte_t oidc_http_request(request_rec *r, const char *url, const char
707704
const apr_array_header_t *pass_cookies, const char *ssl_cert, const char *ssl_key,
708705
const char *ssl_key_pwd) {
709706

707+
// NB: the variable names r, curl, and code are used in the OIDC_HTTP_CURL_SETOPT macro
708+
CURL *curl = NULL;
709+
CURLcode code = CURLE_OK;
710710
char curl_err[CURL_ERROR_SIZE];
711711
oidc_curl_resp_data_ctx_t d_buf = {r, NULL, 0};
712712
oidc_curl_resp_hdr_ctx_t h_buf = {r, response_hdrs};
713-
CURL *curl = NULL;
714713
struct curl_slist *h_list = NULL;
715714
int i = 0;
716715
CURLcode res = CURLE_OK;
@@ -739,43 +738,43 @@ static apr_byte_t oidc_http_request(request_rec *r, const char *url, const char
739738
curl_err[0] = 0;
740739

741740
/* some of these are not really required */
742-
curl_easy_setopt(curl, CURLOPT_HEADER, 0L);
743-
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 1L);
744-
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
745-
curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, curl_err);
746-
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
747-
curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5L);
741+
OIDC_HTTP_CURL_SETOPT(CURLOPT_HEADER, 0L);
742+
OIDC_HTTP_CURL_SETOPT(CURLOPT_NOPROGRESS, 1L);
743+
OIDC_HTTP_CURL_SETOPT(CURLOPT_NOSIGNAL, 1L);
744+
OIDC_HTTP_CURL_SETOPT(CURLOPT_ERRORBUFFER, curl_err);
745+
OIDC_HTTP_CURL_SETOPT(CURLOPT_FOLLOWLOCATION, 1L);
746+
OIDC_HTTP_CURL_SETOPT(CURLOPT_MAXREDIRS, 5L);
748747

749748
/* set the timeouts */
750-
curl_easy_setopt(curl, CURLOPT_TIMEOUT, http_timeout->request_timeout);
751-
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, http_timeout->connect_timeout);
749+
OIDC_HTTP_CURL_SETOPT(CURLOPT_TIMEOUT, http_timeout->request_timeout);
750+
OIDC_HTTP_CURL_SETOPT(CURLOPT_CONNECTTIMEOUT, http_timeout->connect_timeout);
752751

753752
/* setup the buffer where the response data will be written to */
754-
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, oidc_http_response_data);
755-
curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void *)&d_buf);
753+
OIDC_HTTP_CURL_SETOPT(CURLOPT_WRITEFUNCTION, oidc_http_response_data);
754+
OIDC_HTTP_CURL_SETOPT(CURLOPT_WRITEDATA, (void *)&d_buf);
756755

757756
/* setup the buffer where the response headers will be written to */
758-
curl_easy_setopt(curl, CURLOPT_HEADERFUNCTION, oidc_http_response_header);
759-
curl_easy_setopt(curl, CURLOPT_HEADERDATA, (void *)&h_buf);
757+
OIDC_HTTP_CURL_SETOPT(CURLOPT_HEADERFUNCTION, oidc_http_response_header);
758+
OIDC_HTTP_CURL_SETOPT(CURLOPT_HEADERDATA, (void *)&h_buf);
760759

761760
#ifndef LIBCURL_NO_CURLPROTO
762761
#if LIBCURL_VERSION_NUM >= 0x075500
763-
curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https");
764-
curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, "http,https");
762+
OIDC_HTTP_CURL_SETOPT(CURLOPT_REDIR_PROTOCOLS_STR, "http,https");
763+
OIDC_HTTP_CURL_SETOPT(CURLOPT_PROTOCOLS_STR, "http,https");
765764
#else
766-
curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
767-
curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
765+
OIDC_HTTP_CURL_SETOPT(CURLOPT_REDIR_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
766+
OIDC_HTTP_CURL_SETOPT(CURLOPT_PROTOCOLS, CURLPROTO_HTTP | CURLPROTO_HTTPS);
768767
#endif
769768
#endif
770769

771770
/* set the options for validating the SSL server certificate that the remote site presents */
772-
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, (ssl_validate_server != FALSE ? 1L : 0L));
773-
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, (ssl_validate_server != FALSE ? 2L : 0L));
771+
OIDC_HTTP_CURL_SETOPT(CURLOPT_SSL_VERIFYPEER, (ssl_validate_server != FALSE ? 1L : 0L));
772+
OIDC_HTTP_CURL_SETOPT(CURLOPT_SSL_VERIFYHOST, (ssl_validate_server != FALSE ? 2L : 0L));
774773

775774
oidc_http_set_curl_ssl_options(r, curl);
776775

777776
if (oidc_cfg_ca_bundle_path_get(c) != NULL)
778-
curl_easy_setopt(curl, CURLOPT_CAINFO, oidc_cfg_ca_bundle_path_get(c));
777+
OIDC_HTTP_CURL_SETOPT(CURLOPT_CAINFO, oidc_cfg_ca_bundle_path_get(c));
779778

780779
#ifdef WIN32
781780
else {
@@ -785,7 +784,7 @@ static apr_byte_t oidc_http_request(request_rec *r, const char *url, const char
785784
retval[0] = '\0';
786785
buflen = SearchPath(NULL, "curl-ca-bundle.crt", NULL, MAX_PATH + 1, retval, &ptr);
787786
if (buflen > 0)
788-
curl_easy_setopt(curl, CURLOPT_CAINFO, retval);
787+
OIDC_HTTP_CURL_SETOPT(CURLOPT_CAINFO, retval);
789788
else
790789
oidc_warn(r, "no curl-ca-bundle.crt file found in path");
791790
free(retval);
@@ -796,16 +795,15 @@ static apr_byte_t oidc_http_request(request_rec *r, const char *url, const char
796795
const char *s_useragent = oidc_http_user_agent(r);
797796
if ((s_useragent != NULL) && (_oidc_strcmp(s_useragent, "") != 0)) {
798797
oidc_debug(r, "set HTTP request header User-Agent to: %s", s_useragent);
799-
curl_easy_setopt(curl, CURLOPT_USERAGENT, s_useragent);
798+
OIDC_HTTP_CURL_SETOPT(CURLOPT_USERAGENT, s_useragent);
800799
}
801800

802801
/* set the local interface if defined */
803802
const char *s_interface = oidc_http_interface(r);
804803
if ((s_interface != NULL) && (_oidc_strcmp(s_interface, "") != 0)) {
805804
#if LIBCURL_VERSION_NUM >= 0x073000
806805
oidc_debug(r, "set local interface to: %s", s_interface);
807-
if (curl_easy_setopt(curl, CURLOPT_INTERFACE, s_interface) != CURLE_OK)
808-
oidc_warn(r, "could not set local interface to: %s", s_interface);
806+
OIDC_HTTP_CURL_SETOPT(CURLOPT_INTERFACE, s_interface);
809807
#else
810808
oidc_warn(
811809
r, "local interface is configured to %s, but the cURL version in use does not support setting this",
@@ -815,11 +813,11 @@ static apr_byte_t oidc_http_request(request_rec *r, const char *url, const char
815813

816814
/* set optional outgoing proxy for the local network */
817815
if (outgoing_proxy->host_port) {
818-
curl_easy_setopt(curl, CURLOPT_PROXY, outgoing_proxy->host_port);
816+
OIDC_HTTP_CURL_SETOPT(CURLOPT_PROXY, outgoing_proxy->host_port);
819817
if (outgoing_proxy->username_password)
820-
curl_easy_setopt(curl, CURLOPT_PROXYUSERPWD, outgoing_proxy->username_password);
818+
OIDC_HTTP_CURL_SETOPT(CURLOPT_PROXYUSERPWD, outgoing_proxy->username_password);
821819
if (outgoing_proxy->auth_type != OIDC_CONFIG_POS_INT_UNSET)
822-
curl_easy_setopt(curl, CURLOPT_PROXYAUTH, outgoing_proxy->auth_type);
820+
OIDC_HTTP_CURL_SETOPT(CURLOPT_PROXYAUTH, outgoing_proxy->auth_type);
823821
}
824822

825823
/* see if we need to add token in the Bearer/DPoP Authorization header */
@@ -830,22 +828,22 @@ static apr_byte_t oidc_http_request(request_rec *r, const char *url, const char
830828

831829
/* see if we need to perform HTTP basic authentication to the remote site */
832830
if (basic_auth != NULL) {
833-
curl_easy_setopt(curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
834-
curl_easy_setopt(curl, CURLOPT_USERPWD, basic_auth);
831+
OIDC_HTTP_CURL_SETOPT(CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
832+
OIDC_HTTP_CURL_SETOPT(CURLOPT_USERPWD, basic_auth);
835833
}
836834

837835
if (ssl_cert != NULL)
838-
curl_easy_setopt(curl, CURLOPT_SSLCERT, ssl_cert);
836+
OIDC_HTTP_CURL_SETOPT(CURLOPT_SSLCERT, ssl_cert);
839837
if (ssl_key != NULL)
840-
curl_easy_setopt(curl, CURLOPT_SSLKEY, ssl_key);
838+
OIDC_HTTP_CURL_SETOPT(CURLOPT_SSLKEY, ssl_key);
841839
if (ssl_key_pwd != NULL)
842-
curl_easy_setopt(curl, CURLOPT_KEYPASSWD, ssl_key_pwd);
840+
OIDC_HTTP_CURL_SETOPT(CURLOPT_KEYPASSWD, ssl_key_pwd);
843841

844842
if (data != NULL) {
845843
/* set POST data */
846-
curl_easy_setopt(curl, CURLOPT_POSTFIELDS, data);
844+
OIDC_HTTP_CURL_SETOPT(CURLOPT_POSTFIELDS, data);
847845
/* set HTTP method to POST */
848-
curl_easy_setopt(curl, CURLOPT_POST, 1);
846+
OIDC_HTTP_CURL_SETOPT(CURLOPT_POST, 1);
849847
}
850848

851849
if (content_type != NULL) {
@@ -868,7 +866,7 @@ static apr_byte_t oidc_http_request(request_rec *r, const char *url, const char
868866

869867
/* see if we need to add any custom headers */
870868
if (h_list != NULL)
871-
curl_easy_setopt(curl, CURLOPT_HTTPHEADER, h_list);
869+
OIDC_HTTP_CURL_SETOPT(CURLOPT_HTTPHEADER, h_list);
872870

873871
if (pass_cookies != NULL) {
874872
/* gather cookies that we need to pass on from the incoming request */
@@ -887,12 +885,12 @@ static apr_byte_t oidc_http_request(request_rec *r, const char *url, const char
887885
/* see if we need to pass any cookies */
888886
if (cookie_string != NULL) {
889887
oidc_debug(r, "passing browser cookies on backend call: %s", cookie_string);
890-
curl_easy_setopt(curl, CURLOPT_COOKIE, cookie_string);
888+
OIDC_HTTP_CURL_SETOPT(CURLOPT_COOKIE, cookie_string);
891889
}
892890
}
893891

894892
/* set the target URL */
895-
curl_easy_setopt(curl, CURLOPT_URL, url);
893+
OIDC_HTTP_CURL_SETOPT(CURLOPT_URL, url);
896894

897895
/* call it and record the result */
898896
for (i = 0; i <= http_timeout->retries; i++) {

0 commit comments

Comments
 (0)