From 8c8ee134454f75cc0d0ab25ee7df2b0d45a1b9c3 Mon Sep 17 00:00:00 2001 From: Hans Zandbelt Date: Mon, 30 Oct 2023 15:46:24 +0100 Subject: [PATCH] retry failed outgoing HTTP requests and add options to configure it in OIDCHTTPTimeoutLong/OIDCHTTPTimeoutShort; bump to 2.4.15rc0 Signed-off-by: Hans Zandbelt --- ChangeLog | 3 +- auth_openidc.conf | 22 ++- configure.ac | 2 +- src/config.c | 241 ++++++++++++++++++--------- src/metadata.c | 23 +-- src/mod_auth_openidc.c | 61 ++++--- src/mod_auth_openidc.h | 17 +- src/oauth.c | 15 +- src/proto.c | 28 ++-- src/util.c | 366 +++++++++++++++++++++++------------------ 10 files changed, 475 insertions(+), 303 deletions(-) diff --git a/ChangeLog b/ChangeLog index 516bfaff..1de11a11 100644 --- a/ChangeLog +++ b/ChangeLog @@ -4,7 +4,8 @@ - restore backwards compatibility wrt. allowing parallel refresh token requests by default, and add an option to prevent that (i.e. in case of rolling refresh tokens) using envvar OIDC_PARALLEL_REFRESH_NOT_ALLOWED - return HTTP 500 on token refresh errors instead of HTTP 401 -- bump to 2.4.14.5rc1 +- retry failed outgoing HTTP requests and add options to configure it in OIDCHTTPTimeoutLong/OIDCHTTPTimeoutShort +- bump to 2.4.15rc0 10/12/2023 - release 2.4.14.4 diff --git a/auth_openidc.conf b/auth_openidc.conf index 1af5a47a..66a96515 100644 --- a/auth_openidc.conf +++ b/auth_openidc.conf @@ -874,13 +874,21 @@ # a server-wide or directory level. #OIDCAuthNHeader -# Timeout in seconds for long duration HTTP calls. This is used for most requests to remote endpoints/servers. -# When not defined the default of 60 seconds is used. -#OIDCHTTPTimeoutLong - -# Timeout in seconds for short duration HTTP calls; used for Client Registration and OP Discovery requests. -# When not defined the default of 5 seconds is used. -#OIDCHTTPTimeoutShort +# Timeout in seconds for long duration HTTP calls. This defines the maximum duration that a request make take to +# to complete and is used for most requests to remote endpoints/servers. +# The optional parameter specifies the connect timeout in seconds, as part of the overall request timeout. +# The optional parameter specifies the number of retry attempts in case of connectivity errors. +# When not defined the default of 30 seconds is used, with a 10 second connect timeout, using 1 retry after +# an interval of 500ms. +#OIDCHTTPTimeoutLong [] [[:]] + +# Timeout in seconds for short duration HTTP calls. This defines the maximum duration that a request may take to +# to complete and is used for Client Registration and OP Discovery requests. +# The optional parameter specifies the connect timeout in seconds, as part of the overall request timeout. +# The optional parameter specifies the number of retry attempts in case of connectivity errors. +# When not defined the default of 5 seconds is used, with a 2 second connect timeout, using 1 retry with +# an interval of 500ms. +#OIDCHTTPTimeoutShort [] [[:]] # Time to live in seconds for state parameter i.e. the interval in which the authorization request # and the corresponding response need to be processed. When not defined the default of 300 seconds is used. diff --git a/configure.ac b/configure.ac index 5a4cca8a..8c6cb876 100644 --- a/configure.ac +++ b/configure.ac @@ -1,4 +1,4 @@ -AC_INIT([mod_auth_openidc],[2.4.14.5rc1],[hans.zandbelt@openidc.com]) +AC_INIT([mod_auth_openidc],[2.4.15rc0],[hans.zandbelt@openidc.com]) AC_SUBST(NAMEVER, AC_PACKAGE_TARNAME()-AC_PACKAGE_VERSION()) diff --git a/src/config.c b/src/config.c index 72886f21..adc0a8d7 100644 --- a/src/config.c +++ b/src/config.c @@ -74,10 +74,22 @@ #define OIDC_DEFAULT_AUTHN_HEADER NULL /* default client_name the client uses for dynamic client registration */ #define OIDC_DEFAULT_CLIENT_NAME "OpenID Connect Apache Module (mod_auth_openidc)" -/* timeouts in seconds for HTTP calls that may take a long time */ -#define OIDC_DEFAULT_HTTP_TIMEOUT_LONG 60 +/* request timeout in seconds for HTTP calls that may take a long time */ +#define OIDC_DEFAULT_HTTP_REQUEST_TIMEOUT_LONG 30 +/* connect timeout in seconds for HTTP calls that may take a long time */ +#define OIDC_DEFAULT_HTTP_CONNECT_TIMEOUT_LONG 10 +/* nr of retries for HTTP calls that may take a long time */ +#define OIDC_DEFAULT_HTTP_RETRIES_LONG 1 +/* retry interval in milliseconds for HTTP calls that may take a long time */ +#define OIDC_DEFAULT_HTTP_RETRY_INTERVAL_LONG 500 /* timeouts in seconds for HTTP calls that should take a short time (registry/discovery related) */ -#define OIDC_DEFAULT_HTTP_TIMEOUT_SHORT 5 +#define OIDC_DEFAULT_HTTP_REQUEST_TIMEOUT_SHORT 5 +/* connect timeout in seconds for HTTP calls that may take a long time */ +#define OIDC_DEFAULT_HTTP_CONNECT_TIMEOUT_SHORT 2 +/* nr of retries for HTTP calls that should take a short time */ +#define OIDC_DEFAULT_HTTP_RETRIES_SHORT 1 +/* retry interval in milliseconds for HTTP calls that should take a short time */ +#define OIDC_DEFAULT_HTTP_RETRY_INTERVAL_SHORT 500 /* default session storage type */ #define OIDC_DEFAULT_SESSION_TYPE OIDC_SESSION_TYPE_SERVER_CACHE /* default client-cookie chunking size */ @@ -350,6 +362,32 @@ static const char* oidc_set_int_slot(cmd_parms *cmd, void *struct_ptr, return ap_set_int_slot(cmd, cfg, arg); } +static const char* oidc_set_http_timeout_slot(cmd_parms *cmd, void *struct_ptr, + const char *arg1, const char *arg2, const char *arg3) { + oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config, + &auth_openidc_module); + char *s = NULL, *p = NULL; + int offset = (int) (long) cmd->info; + oidc_http_timeout_t *http_timeout = (oidc_http_timeout_t*) ((char*) cfg + + offset); + if (arg1) + http_timeout->request_timeout = _oidc_str_to_int(arg1); + if (arg2) + http_timeout->connect_timeout = _oidc_str_to_int(arg2); + if (arg3) { + s = apr_pstrdup(cmd->pool, arg3); + p = strstr(s, ":"); + if (p) { + *p = '\0'; + p++; + http_timeout->retry_interval = apr_time_from_msec( + _oidc_str_to_int(p)); + } + http_timeout->retries = _oidc_str_to_int(s); + } + return NULL; +} + /* * set an apr_uint32_t value in the server config */ @@ -359,7 +397,7 @@ static const char* oidc_set_uint32_slot(cmd_parms *cmd, void *struct_ptr, apr_int64_t value; oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config, &auth_openidc_module); - apr_uintptr_t offset = (apr_uintptr_t)cmd->info; + apr_uintptr_t offset = (apr_uintptr_t) cmd->info; value = apr_strtoi64(arg, &endptr, 10); if (errno != 0 || *endptr != '\0') { @@ -368,7 +406,7 @@ static const char* oidc_set_uint32_slot(cmd_parms *cmd, void *struct_ptr, if (value > APR_UINT32_MAX || value < 0) { return OIDC_CONFIG_DIR_RV(cmd, "Value out of range"); } - *(apr_uint32_t *)((char *)cfg + offset) = (apr_uint32_t)value; + *(apr_uint32_t*) ((char*) cfg + offset) = (apr_uint32_t) value; return NULL; } @@ -386,7 +424,7 @@ static const char* oidc_set_timeout_slot(cmd_parms *cmd, void *struct_ptr, #endif oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config, &auth_openidc_module); - apr_uintptr_t offset = (apr_uintptr_t)cmd->info; + apr_uintptr_t offset = (apr_uintptr_t) cmd->info; #if AP_MODULE_MAGIC_AT_LEAST(20080920, 2) rv = ap_timeout_parameter_parse(arg, &timeout, "s"); @@ -403,10 +441,10 @@ static const char* oidc_set_timeout_slot(cmd_parms *cmd, void *struct_ptr, } timeout = apr_time_from_sec(timeout); #endif - if (timeout > APR_UINT32_MAX) { + if (timeout > APR_UINT32_MAX) { return OIDC_CONFIG_DIR_RV(cmd, "Value out of range"); } - *(apr_uint32_t *)((char *)cfg + offset) = (apr_uint32_t)timeout; + *(apr_uint32_t*) ((char*) cfg + offset) = (apr_uint32_t) timeout; return NULL; } @@ -500,45 +538,45 @@ static const char* oidc_set_path_slot(cmd_parms *cmd, void *ptr, #if !(HAVE_APACHE_24) static char * ap_get_exec_line(apr_pool_t *p, - const char *cmd, - const char * const * argv) + const char *cmd, + const char * const * argv) { - char buf[MAX_STRING_LEN]; - apr_procattr_t *procattr; - apr_proc_t *proc; - apr_file_t *fp; - apr_size_t nbytes = 1; - char c; - int k; - - if (apr_procattr_create(&procattr, p) != APR_SUCCESS) - return NULL; - if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK, - APR_FULL_BLOCK) != APR_SUCCESS) - return NULL; - if (apr_procattr_dir_set(procattr, - ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS) - return NULL; - if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS) - return NULL; - proc = apr_pcalloc(p, sizeof(apr_proc_t)); - if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS) - return NULL; - fp = proc->out; - - if (fp == NULL) - return NULL; - /* XXX: we are reading 1 byte at a time here */ - for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS - && nbytes == 1 && (k < MAX_STRING_LEN-1) ; ) { - if (c == '\n' || c == '\r') - break; - buf[k++] = c; - } - buf[k] = '\0'; - apr_file_close(fp); - - return apr_pstrndup(p, buf, k); + char buf[MAX_STRING_LEN]; + apr_procattr_t *procattr; + apr_proc_t *proc; + apr_file_t *fp; + apr_size_t nbytes = 1; + char c; + int k; + + if (apr_procattr_create(&procattr, p) != APR_SUCCESS) + return NULL; + if (apr_procattr_io_set(procattr, APR_FULL_BLOCK, APR_FULL_BLOCK, + APR_FULL_BLOCK) != APR_SUCCESS) + return NULL; + if (apr_procattr_dir_set(procattr, + ap_make_dirstr_parent(p, cmd)) != APR_SUCCESS) + return NULL; + if (apr_procattr_cmdtype_set(procattr, APR_PROGRAM) != APR_SUCCESS) + return NULL; + proc = apr_pcalloc(p, sizeof(apr_proc_t)); + if (apr_proc_create(proc, cmd, argv, NULL, procattr, p) != APR_SUCCESS) + return NULL; + fp = proc->out; + + if (fp == NULL) + return NULL; + /* XXX: we are reading 1 byte at a time here */ + for (k = 0; apr_file_read(fp, &c, &nbytes) == APR_SUCCESS + && nbytes == 1 && (k < MAX_STRING_LEN-1) ; ) { + if (c == '\n' || c == '\r') + break; + buf[k++] = c; + } + buf[k] = '\0'; + apr_file_close(fp); + + return apr_pstrndup(p, buf, k); } #endif @@ -586,7 +624,8 @@ static const char* oidc_set_passphrase_slot(cmd_parms *cmd, void *struct_ptr, "Unable to get passphrase from exec of ", arg + 5, NULL); } if (_oidc_strlen(result) == 0) - return apr_pstrdup(cmd->pool, "the output of the crypto passphrase generation command is empty (perhaps you need to pass it to bash -c \"\"?)"); + return apr_pstrdup(cmd->pool, + "the output of the crypto passphrase generation command is empty (perhaps you need to pass it to bash -c \"\"?)"); passphrase = result; } else { passphrase = arg; @@ -1086,10 +1125,12 @@ static const char* oidc_set_pass_claims_as(cmd_parms *cmd, void *m, if (_oidc_strcmp(arg2, "base64url") == 0) { dir_cfg->pass_info_as = OIDC_PASS_APP_INFO_AS_BASE64URL; } else if (_oidc_strcmp(arg2, "latin1") == 0) { - dir_cfg->pass_info_as = OIDC_PASS_APP_INFO_AS_LATIN1; + dir_cfg->pass_info_as = OIDC_PASS_APP_INFO_AS_LATIN1; } else { rv = apr_pstrcat(cmd->temp_pool, "unknown encoding option \"", - arg2, "\", only \"base64url\" or \"latin1\" is supported", NULL); + arg2, + "\", only \"base64url\" or \"latin1\" is supported", + NULL); } } } @@ -1359,30 +1400,42 @@ static const char* oidc_set_state_input_headers_as(cmd_parms *cmd, void *m, return OIDC_CONFIG_DIR_RV(cmd, rv); } -static const char* oidc_set_x_forwarded_headers(cmd_parms *cmd, void *m, const char *arg) { - oidc_cfg *cfg = - (oidc_cfg*) ap_get_module_config(cmd->server->module_config, &auth_openidc_module); - const char *rv = oidc_parse_x_forwarded_headers(cmd->pool, arg, &cfg->x_forwarded_headers); +static const char* oidc_set_x_forwarded_headers(cmd_parms *cmd, void *m, + const char *arg) { + oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config, + &auth_openidc_module); + const char *rv = oidc_parse_x_forwarded_headers(cmd->pool, arg, + &cfg->x_forwarded_headers); return OIDC_CONFIG_DIR_RV(cmd, rv); } -static void oidc_check_x_forwarded_hdr(request_rec *r, const apr_byte_t x_forwarded_headers, - const apr_byte_t hdr_type, const char *hdr_str, - const char* (hdr_func)(const request_rec *r)) { +static void oidc_check_x_forwarded_hdr(request_rec *r, + const apr_byte_t x_forwarded_headers, const apr_byte_t hdr_type, + const char *hdr_str, const char* (hdr_func)(const request_rec *r)) { if (hdr_func(r)) { if (!(x_forwarded_headers & hdr_type)) - oidc_warn(r, "header %s received but %s not configured for it", hdr_str, OIDCXForwardedHeaders); + oidc_warn(r, "header %s received but %s not configured for it", + hdr_str, OIDCXForwardedHeaders); } else { if (x_forwarded_headers & hdr_type) - oidc_warn(r, "%s configured for header %s but not found in request", OIDCXForwardedHeaders, hdr_str); + oidc_warn(r, "%s configured for header %s but not found in request", + OIDCXForwardedHeaders, hdr_str); } } -void oidc_config_check_x_forwarded(request_rec *r, const apr_byte_t x_forwarded_headers) { - oidc_check_x_forwarded_hdr(r, x_forwarded_headers, OIDC_HDR_X_FORWARDED_HOST, OIDC_HTTP_HDR_X_FORWARDED_HOST, oidc_util_hdr_in_x_forwarded_host_get); - oidc_check_x_forwarded_hdr(r, x_forwarded_headers, OIDC_HDR_X_FORWARDED_PORT, OIDC_HTTP_HDR_X_FORWARDED_PORT, oidc_util_hdr_in_x_forwarded_port_get); - oidc_check_x_forwarded_hdr(r, x_forwarded_headers, OIDC_HDR_X_FORWARDED_PROTO, OIDC_HTTP_HDR_X_FORWARDED_PROTO, oidc_util_hdr_in_x_forwarded_proto_get); - oidc_check_x_forwarded_hdr(r, x_forwarded_headers, OIDC_HDR_FORWARDED, OIDC_HTTP_HDR_FORWARDED, oidc_util_hdr_in_forwarded_get); +void oidc_config_check_x_forwarded(request_rec *r, + const apr_byte_t x_forwarded_headers) { + oidc_check_x_forwarded_hdr(r, x_forwarded_headers, + OIDC_HDR_X_FORWARDED_HOST, OIDC_HTTP_HDR_X_FORWARDED_HOST, + oidc_util_hdr_in_x_forwarded_host_get); + oidc_check_x_forwarded_hdr(r, x_forwarded_headers, + OIDC_HDR_X_FORWARDED_PORT, OIDC_HTTP_HDR_X_FORWARDED_PORT, + oidc_util_hdr_in_x_forwarded_port_get); + oidc_check_x_forwarded_hdr(r, x_forwarded_headers, + OIDC_HDR_X_FORWARDED_PROTO, OIDC_HTTP_HDR_X_FORWARDED_PROTO, + oidc_util_hdr_in_x_forwarded_proto_get); + oidc_check_x_forwarded_hdr(r, x_forwarded_headers, OIDC_HDR_FORWARDED, + OIDC_HTTP_HDR_FORWARDED, oidc_util_hdr_in_forwarded_get); } static const char* oidc_set_redirect_urls_allowed(cmd_parms *cmd, void *m, @@ -1812,8 +1865,14 @@ void* oidc_create_server_config(apr_pool_t *pool, server_rec *svr) { c->session_cookie_chunk_size = OIDC_DEFAULT_SESSION_CLIENT_COOKIE_CHUNK_SIZE; - c->http_timeout_long = OIDC_DEFAULT_HTTP_TIMEOUT_LONG; - c->http_timeout_short = OIDC_DEFAULT_HTTP_TIMEOUT_SHORT; + c->http_timeout_long.request_timeout = OIDC_DEFAULT_HTTP_REQUEST_TIMEOUT_LONG; + c->http_timeout_long.connect_timeout = OIDC_DEFAULT_HTTP_CONNECT_TIMEOUT_LONG; + c->http_timeout_long.retries = OIDC_DEFAULT_HTTP_RETRIES_LONG; + c->http_timeout_long.retry_interval = OIDC_DEFAULT_HTTP_RETRY_INTERVAL_LONG; + c->http_timeout_short.request_timeout = OIDC_DEFAULT_HTTP_REQUEST_TIMEOUT_SHORT; + c->http_timeout_short.connect_timeout = OIDC_DEFAULT_HTTP_CONNECT_TIMEOUT_SHORT; + c->http_timeout_short.retries = OIDC_DEFAULT_HTTP_RETRIES_SHORT; + c->http_timeout_long.retry_interval = OIDC_DEFAULT_HTTP_RETRY_INTERVAL_SHORT; c->state_timeout = OIDC_DEFAULT_STATE_TIMEOUT; c->max_number_of_state_cookies = OIDC_CONFIG_POS_INT_UNSET; c->delete_oldest_state_cookies = OIDC_CONFIG_POS_INT_UNSET; @@ -1994,12 +2053,38 @@ void* oidc_merge_server_config(apr_pool_t *pool, void *BASE, void *ADD) { add->oauth.access_token_binding_policy : base->oauth.access_token_binding_policy; - c->http_timeout_long = - add->http_timeout_long != OIDC_DEFAULT_HTTP_TIMEOUT_LONG ? - add->http_timeout_long : base->http_timeout_long; - c->http_timeout_short = - add->http_timeout_short != OIDC_DEFAULT_HTTP_TIMEOUT_SHORT ? - add->http_timeout_short : base->http_timeout_short; + c->http_timeout_long.request_timeout = + add->http_timeout_long.request_timeout != OIDC_DEFAULT_HTTP_REQUEST_TIMEOUT_LONG ? + add->http_timeout_long.request_timeout : + base->http_timeout_long.request_timeout; + c->http_timeout_long.connect_timeout = + add->http_timeout_long.connect_timeout != OIDC_DEFAULT_HTTP_CONNECT_TIMEOUT_LONG ? + add->http_timeout_long.connect_timeout : + base->http_timeout_long.connect_timeout; + c->http_timeout_long.retries = + add->http_timeout_long.retries != OIDC_DEFAULT_HTTP_RETRIES_LONG ? + add->http_timeout_long.retries : + base->http_timeout_long.retries; + c->http_timeout_long.retry_interval = + add->http_timeout_long.retry_interval != OIDC_DEFAULT_HTTP_RETRY_INTERVAL_LONG ? + add->http_timeout_long.retry_interval : + base->http_timeout_long.retry_interval; + c->http_timeout_short.request_timeout = + add->http_timeout_short.request_timeout != OIDC_DEFAULT_HTTP_REQUEST_TIMEOUT_SHORT ? + add->http_timeout_short.request_timeout : + base->http_timeout_short.request_timeout; + c->http_timeout_short.connect_timeout = + add->http_timeout_short.connect_timeout != OIDC_DEFAULT_HTTP_CONNECT_TIMEOUT_SHORT ? + add->http_timeout_short.connect_timeout : + base->http_timeout_short.connect_timeout; + c->http_timeout_short.retries = + add->http_timeout_short.retries != OIDC_DEFAULT_HTTP_RETRIES_SHORT ? + add->http_timeout_short.retries : + base->http_timeout_short.retries; + c->http_timeout_short.retry_interval = + add->http_timeout_short.retry_interval != OIDC_DEFAULT_HTTP_RETRY_INTERVAL_SHORT ? + add->http_timeout_short.retry_interval : + base->http_timeout_short.retry_interval; c->state_timeout = add->state_timeout != OIDC_DEFAULT_STATE_TIMEOUT ? add->state_timeout : base->state_timeout; @@ -3122,7 +3207,7 @@ void oidc_register_hooks(apr_pool_t *pool) { oidc_pre_config_init(); ap_hook_post_config(oidc_post_config, NULL, NULL, APR_HOOK_LAST); ap_hook_child_init(oidc_child_init, NULL, NULL, APR_HOOK_MIDDLE); - static const char * const proxySucc[] = {"mod_proxy.c", NULL}; + static const char *const proxySucc[] = { "mod_proxy.c", NULL }; ap_hook_handler(oidc_content_handler, NULL, proxySucc, APR_HOOK_FIRST); ap_hook_insert_filter(oidc_filter_in_insert_filter, NULL, NULL, APR_HOOK_MIDDLE); @@ -3136,8 +3221,8 @@ void oidc_register_hooks(apr_pool_t *pool) { AP_AUTH_INTERNAL_PER_CONF); #ifdef USE_LIBJQ ap_register_auth_provider(pool, AUTHZ_PROVIDER_GROUP, - OIDC_REQUIRE_CLAIMS_EXPR_NAME, "0", - &oidc_authz_claims_expr_provider, AP_AUTH_INTERNAL_PER_CONF); + OIDC_REQUIRE_CLAIMS_EXPR_NAME, "0", &oidc_authz_claims_expr_provider, + AP_AUTH_INTERNAL_PER_CONF); #endif #else static const char * const authzSucc[] = {"mod_authz_user.c", NULL}; @@ -3526,13 +3611,13 @@ const command_rec oidc_config_cmds[] = { RSRC_CONF, "The JWKs URL on which the Authorization publishes the keys used to sign its JWT access tokens."), - AP_INIT_TAKE1(OIDCHTTPTimeoutLong, - oidc_set_int_slot, + AP_INIT_TAKE123(OIDCHTTPTimeoutLong, + oidc_set_http_timeout_slot, (void*)APR_OFFSETOF(oidc_cfg, http_timeout_long), RSRC_CONF, "Timeout for long duration HTTP calls (default)."), - AP_INIT_TAKE1(OIDCHTTPTimeoutShort, - oidc_set_int_slot, + AP_INIT_TAKE123(OIDCHTTPTimeoutShort, + oidc_set_http_timeout_slot, (void*)APR_OFFSETOF(oidc_cfg, http_timeout_short), RSRC_CONF, "Timeout for short duration HTTP calls (registry/discovery)."), diff --git a/src/metadata.c b/src/metadata.c index 86022efb..1d8aef9f 100644 --- a/src/metadata.c +++ b/src/metadata.c @@ -409,8 +409,8 @@ static apr_byte_t oidc_metadata_client_is_valid(request_rec *r, /* * checks if a parsed JWKs file is a valid one, cq. contains "keys" */ -static apr_byte_t oidc_metadata_jwks_is_valid(request_rec *r, - const char *url, const json_t *j_jwks) { +static apr_byte_t oidc_metadata_jwks_is_valid(request_rec *r, const char *url, + const json_t *j_jwks) { const json_t *keys = json_object_get(j_jwks, OIDC_METADATA_KEYS); if ((keys == NULL) || (!json_is_array(keys))) { @@ -604,7 +604,7 @@ static apr_byte_t oidc_metadata_client_register(request_rec *r, oidc_cfg *cfg, /* dynamically register the client with the specified parameters */ if (oidc_util_http_post_json(r, provider->registration_endpoint_url, data, NULL, provider->registration_token, provider->ssl_validate_server, response, - cfg->http_timeout_short, &cfg->outgoing_proxy, + &cfg->http_timeout_short, &cfg->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), NULL, NULL, NULL) == FALSE) { json_decref(data); @@ -636,7 +636,7 @@ static apr_byte_t oidc_metadata_jwks_retrieve_and_cache(request_rec *r, /* get the JWKs from the specified URL with the specified parameters */ if (oidc_util_http_get(r, url, NULL, NULL, - NULL, ssl_validate_server, &response, cfg->http_timeout_long, + NULL, ssl_validate_server, &response, &cfg->http_timeout_long, &cfg->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), NULL, NULL, NULL) == FALSE) return FALSE; @@ -747,7 +747,7 @@ apr_byte_t oidc_metadata_provider_retrieve(request_rec *r, oidc_cfg *cfg, /* get provider metadata from the specified URL with the specified parameters */ if (oidc_util_http_get(r, url, NULL, NULL, NULL, cfg->provider.ssl_validate_server, response, - cfg->http_timeout_short, &cfg->outgoing_proxy, + &cfg->http_timeout_short, &cfg->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), NULL, NULL, NULL) == FALSE) return FALSE; @@ -986,8 +986,7 @@ static void oidc_metadata_parse_boolean(request_rec *r, json_t *json, const char *key, int *value, int default_value) { int int_value = 0; char *s_value = NULL; - if (oidc_json_object_get_bool(json, key, &int_value, - default_value) == FALSE) { + if (oidc_json_object_get_bool(json, key, &int_value, default_value) == FALSE) { oidc_json_object_get_string(r->pool, json, key, &s_value, NULL); if (s_value != NULL) { @@ -1189,9 +1188,9 @@ void oidc_metadata_get_valid_string(request_rec *r, json_t *json, /* * get an integer value from a JSON object and see if it is a valid value according to the specified validation function */ -void oidc_metadata_get_valid_int(request_rec *r, const json_t *json, const char *key, - oidc_valid_int_function_t valid_int_function, int *int_value, - int default_int_value) { +void oidc_metadata_get_valid_int(request_rec *r, const json_t *json, + const char *key, oidc_valid_int_function_t valid_int_function, + int *int_value, int default_int_value) { int v = 0; oidc_json_object_get_int(json, key, &v, default_int_value); const char *rv = valid_int_function(r->pool, v); @@ -1504,7 +1503,9 @@ apr_byte_t oidc_metadata_client_parse(request_rec *r, oidc_cfg *cfg, } oidc_metadata_get_valid_string(r, j_client, - OIDC_METADATA_ID_TOKEN_SIGNED_RESPONSE_ALG, oidc_valid_signed_response_alg, &provider->id_token_signed_response_alg, provider->id_token_signed_response_alg); + OIDC_METADATA_ID_TOKEN_SIGNED_RESPONSE_ALG, oidc_valid_signed_response_alg, + &provider->id_token_signed_response_alg, + provider->id_token_signed_response_alg); return TRUE; } diff --git a/src/mod_auth_openidc.c b/src/mod_auth_openidc.c index d99ff981..27624b81 100644 --- a/src/mod_auth_openidc.c +++ b/src/mod_auth_openidc.c @@ -528,7 +528,8 @@ static int oidc_request_post_preserved_restore(request_rec *r, " document.forms[0].action = \"%s\";\n" " document.forms[0].submit();\n" " }\n" - " \n", method, oidc_util_javascript_escape(r->pool, original_url)); + " \n", method, + oidc_util_javascript_escape(r->pool, original_url)); const char *body = "

Restoring...

\n" "
\n"; @@ -546,7 +547,8 @@ typedef struct oidc_state_cookies_t { static int oidc_delete_oldest_state_cookies(request_rec *r, oidc_cfg *c, int number_of_valid_state_cookies, int max_number_of_state_cookies, oidc_state_cookies_t *first) { - oidc_state_cookies_t *cur = NULL, *prev = NULL, *prev_oldest = NULL, *oldest = NULL; + oidc_state_cookies_t *cur = NULL, *prev = NULL, *prev_oldest = NULL, + *oldest = NULL; while (number_of_valid_state_cookies >= max_number_of_state_cookies) { oldest = first; prev_oldest = NULL; @@ -560,8 +562,11 @@ static int oidc_delete_oldest_state_cookies(request_rec *r, oidc_cfg *c, prev = cur; cur = cur->next; } - oidc_warn(r, "deleting oldest state cookie: %s (time until expiry %" APR_TIME_T_FMT " seconds)", oldest->name, apr_time_sec(oldest->timestamp - apr_time_now())); - oidc_util_set_cookie(r, oldest->name, "", 0, OIDC_COOKIE_EXT_SAME_SITE_NONE(c, r)); + oidc_warn(r, + "deleting oldest state cookie: %s (time until expiry %" APR_TIME_T_FMT " seconds)", + oldest->name, apr_time_sec(oldest->timestamp - apr_time_now())); + oidc_util_set_cookie(r, oldest->name, "", 0, + OIDC_COOKIE_EXT_SAME_SITE_NONE(c, r)); if (prev_oldest) prev_oldest->next = oldest->next; else @@ -599,16 +604,24 @@ static int oidc_clean_expired_state_cookies(request_rec *r, oidc_cfg *c, oidc_proto_state_t *proto_state = oidc_proto_state_from_cookie(r, c, cookie); if (proto_state != NULL) { - json_int_t ts = oidc_proto_state_get_timestamp(proto_state); + json_int_t ts = oidc_proto_state_get_timestamp( + proto_state); if (apr_time_now() > ts + apr_time_from_sec(c->state_timeout)) { - oidc_warn(r, "state (%s) has expired (original_url=%s)", cookieName, oidc_proto_state_get_original_url(proto_state)); - oidc_util_set_cookie(r, cookieName, "", 0, OIDC_COOKIE_EXT_SAME_SITE_NONE(c, r)); + oidc_warn(r, + "state (%s) has expired (original_url=%s)", + cookieName, + oidc_proto_state_get_original_url( + proto_state)); + oidc_util_set_cookie(r, cookieName, "", 0, + OIDC_COOKIE_EXT_SAME_SITE_NONE(c, r)); } else { if (first == NULL) { - first = apr_pcalloc(r->pool, sizeof(oidc_state_cookies_t)); + first = apr_pcalloc(r->pool, + sizeof(oidc_state_cookies_t)); last = first; } else { - last->next = apr_pcalloc(r->pool, sizeof(oidc_state_cookies_t)); + last->next = apr_pcalloc(r->pool, + sizeof(oidc_state_cookies_t)); last = last->next; } last->name = cookieName; @@ -618,8 +631,11 @@ static int oidc_clean_expired_state_cookies(request_rec *r, oidc_cfg *c, } oidc_proto_state_destroy(proto_state); } else { - oidc_warn(r, "state cookie could not be retrieved/decoded, deleting: %s", cookieName); - oidc_util_set_cookie(r, cookieName, "", 0, OIDC_COOKIE_EXT_SAME_SITE_NONE(c, r)); + oidc_warn(r, + "state cookie could not be retrieved/decoded, deleting: %s", + cookieName); + oidc_util_set_cookie(r, cookieName, "", 0, + OIDC_COOKIE_EXT_SAME_SITE_NONE(c, r)); } } } @@ -629,8 +645,9 @@ static int oidc_clean_expired_state_cookies(request_rec *r, oidc_cfg *c, } if (delete_oldest > 0) - number_of_valid_state_cookies = - oidc_delete_oldest_state_cookies(r, c, number_of_valid_state_cookies, c->max_number_of_state_cookies, first); + number_of_valid_state_cookies = oidc_delete_oldest_state_cookies(r, c, + number_of_valid_state_cookies, c->max_number_of_state_cookies, + first); return number_of_valid_state_cookies; } @@ -874,12 +891,12 @@ apr_byte_t oidc_is_auth_capable_request(request_rec *r) { if ((oidc_util_hdr_in_sec_fetch_mode_get(r) != NULL) && (apr_strnatcasecmp(oidc_util_hdr_in_sec_fetch_mode_get(r), - OIDC_HTTP_HDR_VAL_NAVIGATE) != 0)) + OIDC_HTTP_HDR_VAL_NAVIGATE) != 0)) return FALSE; if ((oidc_util_hdr_in_sec_fetch_dest_get(r) != NULL) && (apr_strnatcasecmp(oidc_util_hdr_in_sec_fetch_dest_get(r), - OIDC_HTTP_HDR_VAL_DOCUMENT) != 0)) + OIDC_HTTP_HDR_VAL_DOCUMENT) != 0)) return FALSE; if ((oidc_util_hdr_in_accept_contains(r, OIDC_CONTENT_TYPE_TEXT_HTML) @@ -932,7 +949,8 @@ static int oidc_handle_unauthenticated_user(request_rec *r, oidc_cfg *c) { * else: no session (regardless of whether it is main or sub-request), * and we need to authenticate the user */ - return oidc_authenticate_user(r, c, NULL, oidc_get_current_url(r, c->x_forwarded_headers), NULL, + return oidc_authenticate_user(r, c, NULL, + oidc_get_current_url(r, c->x_forwarded_headers), NULL, NULL, NULL, oidc_dir_cfg_path_auth_request_params(r), oidc_dir_cfg_path_scope(r)); } @@ -976,7 +994,8 @@ static apr_byte_t oidc_check_cookie_domain(request_rec *r, oidc_cfg *cfg, oidc_session_t *session) { const char *c_cookie_domain = cfg->cookie_domain ? - cfg->cookie_domain : oidc_get_current_url_host(r, cfg->x_forwarded_headers); + cfg->cookie_domain : + oidc_get_current_url_host(r, cfg->x_forwarded_headers); const char *s_cookie_domain = oidc_session_get_cookie_domain(r, session); if ((s_cookie_domain == NULL) || (_oidc_strcmp(c_cookie_domain, s_cookie_domain) != 0)) { @@ -1096,7 +1115,7 @@ static apr_byte_t oidc_refresh_token_grant(request_rec *r, oidc_cfg *c, if (value != NULL) { oidc_debug(r, "refresh token routine called again within %d seconds for the same refresh token: %s", - c->http_timeout_long, refresh_token); + c->http_timeout_long.request_timeout, refresh_token); *error_code = OIDC_REFRESH_ERROR_PARALLEL_REFRESH; if (apr_table_get(r->subprocess_env, OIDC_PARALLEL_REFRESH_NOT_ALLOWED_ENVVAR) != NULL) { @@ -1107,7 +1126,7 @@ static apr_byte_t oidc_refresh_token_grant(request_rec *r, oidc_cfg *c, } // "lock" the refresh token best effort; this does not work failsafe in a clustered setup... oidc_cache_set_refresh_token(r, refresh_token, refresh_token, - apr_time_now() + apr_time_from_sec(c->http_timeout_long)); + apr_time_now() + apr_time_from_sec(c->http_timeout_long.request_timeout)); oidc_debug(r, "refreshing refresh_token: %s", refresh_token); // don't unlock after this since other processes may be waiting for the lock to refresh the same refresh token @@ -3165,7 +3184,7 @@ static void oidc_revoke_tokens(request_rec *r, oidc_cfg *c, if (oidc_util_http_post_form(r, provider->revocation_endpoint_url, params, basic_auth, bearer_auth, c->oauth.ssl_validate_server, - &response, c->http_timeout_long, &c->outgoing_proxy, + &response, &c->http_timeout_long, &c->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), NULL, NULL, NULL) == FALSE) { oidc_warn(r, "revoking refresh token failed"); @@ -3182,7 +3201,7 @@ static void oidc_revoke_tokens(request_rec *r, oidc_cfg *c, if (oidc_util_http_post_form(r, provider->revocation_endpoint_url, params, basic_auth, bearer_auth, c->oauth.ssl_validate_server, - &response, c->http_timeout_long, &c->outgoing_proxy, + &response, &c->http_timeout_long, &c->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), NULL, NULL, NULL) == FALSE) { oidc_warn(r, "revoking access token failed"); diff --git a/src/mod_auth_openidc.h b/src/mod_auth_openidc.h index b8df984e..94791e7d 100644 --- a/src/mod_auth_openidc.h +++ b/src/mod_auth_openidc.h @@ -398,6 +398,13 @@ typedef struct oidc_outgoing_proxy_t { unsigned long auth_type; } oidc_outgoing_proxy_t; +typedef struct oidc_http_timeout_t { + int request_timeout; + int connect_timeout; + int retries; + apr_time_t retry_interval; +} oidc_http_timeout_t; + typedef struct oidc_cfg { /* indicates whether this is a derived config, merged from a base one */ unsigned int merged; @@ -472,8 +479,8 @@ typedef struct oidc_cfg { #endif int cache_encrypt; - int http_timeout_long; - int http_timeout_short; + oidc_http_timeout_t http_timeout_long; + oidc_http_timeout_t http_timeout_short; int state_timeout; int max_number_of_state_cookies; int delete_oldest_state_cookies; @@ -847,9 +854,9 @@ char *oidc_normalize_header_name(const request_rec *r, const char *str); apr_byte_t oidc_util_request_is_secure(request_rec *r, const oidc_cfg *c); void oidc_util_set_cookie(request_rec *r, const char *cookieName, const char *cookieValue, apr_time_t expires, const char *ext); char *oidc_util_get_cookie(request_rec *r, const char *cookieName); -apr_byte_t oidc_util_http_get(request_rec *r, const char *url, const apr_table_t *params, const char *basic_auth, const char *bearer_token, int ssl_validate_server, char **response, int timeout, const oidc_outgoing_proxy_t *outgoing_proxy, apr_array_header_t *pass_cookies, const char *ssl_cert, const char *ssl_key, const char *ssl_key_pwd); -apr_byte_t oidc_util_http_post_form(request_rec *r, const char *url, const apr_table_t *params, const char *basic_auth, const char *bearer_token, int ssl_validate_server, char **response, int timeout, const oidc_outgoing_proxy_t *outgoing_proxy, apr_array_header_t *pass_cookies, const char *ssl_cert, const char *ssl_key, const char *ssl_key_pwd); -apr_byte_t oidc_util_http_post_json(request_rec *r, const char *url, json_t *data, const char *basic_auth, const char *bearer_token, int ssl_validate_server, char **response, int timeout, const oidc_outgoing_proxy_t *outgoing_proxy, apr_array_header_t *pass_cookies, const char *ssl_cert, const char *ssl_key, const char *ssl_key_pwd); +apr_byte_t oidc_util_http_get(request_rec *r, const char *url, const apr_table_t *params, const char *basic_auth, const char *bearer_token, int ssl_validate_server, char **response, oidc_http_timeout_t *http_timeout, const oidc_outgoing_proxy_t *outgoing_proxy, apr_array_header_t *pass_cookies, const char *ssl_cert, const char *ssl_key, const char *ssl_key_pwd); +apr_byte_t oidc_util_http_post_form(request_rec *r, const char *url, const apr_table_t *params, const char *basic_auth, const char *bearer_token, int ssl_validate_server, char **response, oidc_http_timeout_t *http_timeout, const oidc_outgoing_proxy_t *outgoing_proxy, apr_array_header_t *pass_cookies, const char *ssl_cert, const char *ssl_key, const char *ssl_key_pwd); +apr_byte_t oidc_util_http_post_json(request_rec *r, const char *url, json_t *data, const char *basic_auth, const char *bearer_token, int ssl_validate_server, char **response, oidc_http_timeout_t *http_timeout, const oidc_outgoing_proxy_t *outgoing_proxy, apr_array_header_t *pass_cookies, const char *ssl_cert, const char *ssl_key, const char *ssl_key_pwd); apr_byte_t oidc_util_request_matches_url(request_rec *r, const char *url); apr_byte_t oidc_util_request_has_parameter(request_rec *r, const char* param); apr_byte_t oidc_util_get_request_parameter(request_rec *r, char *name, char **value); diff --git a/src/oauth.c b/src/oauth.c index 30f86f9d..c01df7f2 100644 --- a/src/oauth.c +++ b/src/oauth.c @@ -49,7 +49,7 @@ apr_byte_t oidc_oauth_metadata_provider_retrieve(request_rec *r, oidc_cfg *cfg, /* get provider metadata from the specified URL with the specified parameters */ if (oidc_util_http_get(r, url, NULL, NULL, NULL, - cfg->oauth.ssl_validate_server, response, cfg->http_timeout_short, + cfg->oauth.ssl_validate_server, response, &cfg->http_timeout_short, &cfg->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), NULL, NULL, NULL) == FALSE) return FALSE; @@ -162,7 +162,7 @@ static apr_byte_t oidc_oauth_validate_access_token(request_rec *r, oidc_cfg *c, OIDC_INTROSPECTION_METHOD_GET) == 0 ? oidc_util_http_get(r, c->oauth.introspection_endpoint_url, params, basic_auth, bearer_auth, c->oauth.ssl_validate_server, - response, c->http_timeout_long, &c->outgoing_proxy, + response, &c->http_timeout_long, &c->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), oidc_util_get_full_path(r->pool, c->oauth.introspection_endpoint_tls_client_cert), @@ -173,7 +173,7 @@ static apr_byte_t oidc_oauth_validate_access_token(request_rec *r, oidc_cfg *c, oidc_util_http_post_form(r, c->oauth.introspection_endpoint_url, params, basic_auth, bearer_auth, c->oauth.ssl_validate_server, response, - c->http_timeout_long, &c->outgoing_proxy, + &c->http_timeout_long, &c->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), oidc_util_get_full_path(r->pool, c->oauth.introspection_endpoint_tls_client_cert), @@ -618,9 +618,12 @@ static apr_byte_t oidc_oauth_validate_jwt_access_token(request_rec *r, // TODO: we're re-using the OIDC provider JWKs refresh interval here... oidc_jwks_uri_t jwks_uri = { c->oauth.verify_jwks_uri, c->provider.jwks_uri.refresh_interval, NULL, NULL }; - if (oidc_proto_jwt_verify(r, c, jwt, &jwks_uri, c->oauth.ssl_validate_server, oidc_util_merge_key_sets(r->pool, c->oauth.verify_shared_keys, c->oauth.verify_public_keys), NULL) - == FALSE) { - oidc_error(r, "JWT access token signature could not be validated, aborting"); + if (oidc_proto_jwt_verify(r, c, jwt, &jwks_uri, + c->oauth.ssl_validate_server, + oidc_util_merge_key_sets(r->pool, c->oauth.verify_shared_keys, + c->oauth.verify_public_keys), NULL) == FALSE) { + oidc_error(r, + "JWT access token signature could not be validated, aborting"); oidc_jwt_destroy(jwt); return FALSE; } diff --git a/src/proto.c b/src/proto.c index b76ead40..492421a6 100644 --- a/src/proto.c +++ b/src/proto.c @@ -115,8 +115,8 @@ static apr_status_t oidc_proto_generate_random_bytes(request_rec *r, /* * generate a random string value value of a specified length */ -apr_byte_t oidc_proto_generate_random_string(request_rec *r, - char **output, int len) { +apr_byte_t oidc_proto_generate_random_string(request_rec *r, char **output, + int len) { unsigned char *bytes = apr_pcalloc(r->pool, len); if (oidc_proto_generate_random_bytes(r, bytes, len) != APR_SUCCESS) { oidc_error(r, "oidc_proto_generate_random_bytes returned an error"); @@ -537,7 +537,8 @@ static void oidc_proto_add_request_param(request_rec *r, } /* ensure parameter variable to have a valid value */ - if (_oidc_strcmp(request_object_type_str, OIDC_PROTO_REQUEST_OBJECT) == 0) { + if (_oidc_strcmp(request_object_type_str, OIDC_PROTO_REQUEST_OBJECT) + == 0) { parameter = OIDC_PROTO_REQUEST_OBJECT; } else if (_oidc_strcmp(request_object_type_str, OIDC_PROTO_REQUEST_URI) != 0) { @@ -1508,13 +1509,14 @@ static apr_byte_t oidc_proto_get_key_from_jwks(request_rec *r, oidc_jwt_t *jwt, * get the keys from the (possibly cached) set of JWKs on the jwk_uri that corresponds with the key specified in the header */ apr_byte_t oidc_proto_get_keys_from_jwks_uri(request_rec *r, oidc_cfg *cfg, - oidc_jwt_t *jwt, const oidc_jwks_uri_t *jwks_uri, int ssl_validate_server, apr_hash_t *keys, - apr_byte_t *force_refresh) { + oidc_jwt_t *jwt, const oidc_jwks_uri_t *jwks_uri, + int ssl_validate_server, apr_hash_t *keys, apr_byte_t *force_refresh) { json_t *j_jwks = NULL; /* get the set of JSON Web Keys for this provider (possibly by downloading them from the specified provider->jwk_uri) */ - oidc_metadata_jwks_get(r, cfg, jwks_uri, ssl_validate_server, &j_jwks, force_refresh); + oidc_metadata_jwks_get(r, cfg, jwks_uri, ssl_validate_server, &j_jwks, + force_refresh); if (j_jwks == NULL) { oidc_error(r, "could not %s JSON Web Keys", *force_refresh ? "refresh" : "get"); @@ -1542,8 +1544,8 @@ apr_byte_t oidc_proto_get_keys_from_jwks_uri(request_rec *r, oidc_cfg *cfg, "could not find a key in the cached JSON Web Keys, doing a forced refresh in case keys were rolled over"); /* get the set of JSON Web Keys forcing a fresh download from the specified JWKs URI */ *force_refresh = TRUE; - return oidc_proto_get_keys_from_jwks_uri(r, cfg, jwt, jwks_uri, ssl_validate_server, keys, - force_refresh); + return oidc_proto_get_keys_from_jwks_uri(r, cfg, jwt, jwks_uri, + ssl_validate_server, keys, force_refresh); } oidc_debug(r, @@ -2060,7 +2062,7 @@ static apr_byte_t oidc_proto_token_endpoint_request(request_rec *r, /* send the refresh request to the token endpoint */ if (oidc_util_http_post_form(r, provider->token_endpoint_url, params, basic_auth, bearer_auth, provider->ssl_validate_server, &response, - cfg->http_timeout_long, &cfg->outgoing_proxy, + &cfg->http_timeout_long, &cfg->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), oidc_util_get_full_path(r->pool, provider->token_endpoint_tls_client_cert), @@ -2302,7 +2304,7 @@ static apr_byte_t oidc_proto_resolve_composite_claims(request_rec *r, if ((access_token != NULL) && (endpoint != NULL)) { oidc_util_http_get(r, endpoint, NULL, NULL, access_token, cfg->provider.ssl_validate_server, - &s_json, cfg->http_timeout_long, + &s_json, &cfg->http_timeout_long, &cfg->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), NULL, NULL, NULL); } @@ -2368,7 +2370,7 @@ apr_byte_t oidc_proto_resolve_userinfo(request_rec *r, oidc_cfg *cfg, if (provider->userinfo_token_method == OIDC_USER_INFO_TOKEN_METHOD_HEADER) { if (oidc_util_http_get(r, provider->userinfo_endpoint_url, NULL, NULL, access_token, provider->ssl_validate_server, response, - cfg->http_timeout_long, &cfg->outgoing_proxy, + &cfg->http_timeout_long, &cfg->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), NULL, NULL, NULL) == FALSE) return FALSE; } else if (provider->userinfo_token_method @@ -2377,7 +2379,7 @@ apr_byte_t oidc_proto_resolve_userinfo(request_rec *r, oidc_cfg *cfg, apr_table_setn(params, OIDC_PROTO_ACCESS_TOKEN, access_token); if (oidc_util_http_post_form(r, provider->userinfo_endpoint_url, params, NULL, NULL, provider->ssl_validate_server, response, - cfg->http_timeout_long, &cfg->outgoing_proxy, + &cfg->http_timeout_long, &cfg->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), NULL, NULL, NULL) == FALSE) return FALSE; } else { @@ -2442,7 +2444,7 @@ static apr_byte_t oidc_proto_webfinger_discovery(request_rec *r, oidc_cfg *cfg, char *response = NULL; if (oidc_util_http_get(r, url, params, NULL, NULL, cfg->provider.ssl_validate_server, &response, - cfg->http_timeout_short, &cfg->outgoing_proxy, + &cfg->http_timeout_short, &cfg->outgoing_proxy, oidc_dir_cfg_pass_cookies(r), NULL, NULL, NULL) == FALSE) { /* errors will have been logged by now */ return FALSE; diff --git a/src/util.c b/src/util.c index 446eb87f..e6b7ce52 100644 --- a/src/util.c +++ b/src/util.c @@ -456,89 +456,89 @@ char* oidc_util_html_escape(apr_pool_t *pool, const char *s) { * JavaScript escape a string */ char* oidc_util_javascript_escape(apr_pool_t *pool, const char *s) { - const char *cp = NULL; - char *output = NULL; - size_t outputlen = 0; - int i = 0; - - if (s == NULL) { - return NULL; - } - - outputlen = 0; - for (cp = s; *cp; cp++) { - switch (*cp) { - case '\'': - case '"': - case '\\': - case '/': - case 0x0D: - case 0x0A: - outputlen += 2; - break; - case '<': - case '>': - outputlen += 4; - break; - default: - outputlen += 1; - break; - } - } - - i = 0; - output = apr_pcalloc(pool, outputlen + 1); - for (cp = s; *cp; cp++) { - switch (*cp) { - case '\'': - if (i <= outputlen - 2) - (void)_oidc_strcpy(&output[i], "\\'"); - i += 2; - break; - case '"': - if (i <= outputlen - 2) - (void)_oidc_strcpy(&output[i], "\\\""); - i += 2; - break; - case '\\': - if (i <= outputlen - 2) - (void)_oidc_strcpy(&output[i], "\\\\"); - i += 2; - break; - case '/': - if (i <= outputlen - 2) - (void)_oidc_strcpy(&output[i], "\\/"); - i += 2; - break; - case 0x0D: - if (i <= outputlen - 2) - (void)_oidc_strcpy(&output[i], "\\r"); - i += 2; - break; - case 0x0A: - if (i <= outputlen - 2) - (void)_oidc_strcpy(&output[i], "\\n"); - i += 2; - break; - case '<': - if (i <= outputlen - 4) - (void)_oidc_strcpy(&output[i], "\\x3c"); - i += 4; - break; - case '>': - if (i <= outputlen - 4) - (void)_oidc_strcpy(&output[i], "\\x3e"); - i += 4; - break; - default: - if (i <= outputlen - 1) - output[i] = *cp; - i += 1; - break; - } - } - output[i] = '\0'; - return output; + const char *cp = NULL; + char *output = NULL; + size_t outputlen = 0; + int i = 0; + + if (s == NULL) { + return NULL; + } + + outputlen = 0; + for (cp = s; *cp; cp++) { + switch (*cp) { + case '\'': + case '"': + case '\\': + case '/': + case 0x0D: + case 0x0A: + outputlen += 2; + break; + case '<': + case '>': + outputlen += 4; + break; + default: + outputlen += 1; + break; + } + } + + i = 0; + output = apr_pcalloc(pool, outputlen + 1); + for (cp = s; *cp; cp++) { + switch (*cp) { + case '\'': + if (i <= outputlen - 2) + (void) _oidc_strcpy(&output[i], "\\'"); + i += 2; + break; + case '"': + if (i <= outputlen - 2) + (void) _oidc_strcpy(&output[i], "\\\""); + i += 2; + break; + case '\\': + if (i <= outputlen - 2) + (void) _oidc_strcpy(&output[i], "\\\\"); + i += 2; + break; + case '/': + if (i <= outputlen - 2) + (void) _oidc_strcpy(&output[i], "\\/"); + i += 2; + break; + case 0x0D: + if (i <= outputlen - 2) + (void) _oidc_strcpy(&output[i], "\\r"); + i += 2; + break; + case 0x0A: + if (i <= outputlen - 2) + (void) _oidc_strcpy(&output[i], "\\n"); + i += 2; + break; + case '<': + if (i <= outputlen - 4) + (void) _oidc_strcpy(&output[i], "\\x3c"); + i += 4; + break; + case '>': + if (i <= outputlen - 4) + (void) _oidc_strcpy(&output[i], "\\x3e"); + i += 4; + break; + default: + if (i <= outputlen - 1) + output[i] = *cp; + i += 1; + break; + } + } + output[i] = '\0'; + return output; } const char* oidc_util_strcasestr(const char *s1, const char *s2) { @@ -559,7 +559,8 @@ const char* oidc_util_strcasestr(const char *s1, const char *s2) { } while (1); } -static const char* oidc_util_hdr_forwarded_get(const request_rec *r, const char *elem) { +static const char* oidc_util_hdr_forwarded_get(const request_rec *r, + const char *elem) { const char *value = NULL; char *ptr = NULL; const char *item = apr_psprintf(r->pool, "%s=", elem); @@ -601,7 +602,9 @@ static const char* oidc_get_current_url_scheme(const request_rec *r, if ((scheme_str == NULL) || ((_oidc_strcmp(scheme_str, "http") != 0) && (_oidc_strcmp(scheme_str, "https") != 0))) { - oidc_warn(r, "detected HTTP scheme \"%s\" is not \"http\" nor \"https\"; perhaps your reverse proxy passes a wrongly configured \"%s\" header: falling back to default \"https\"", scheme_str, OIDC_HTTP_HDR_X_FORWARDED_PROTO); + oidc_warn(r, + "detected HTTP scheme \"%s\" is not \"http\" nor \"https\"; perhaps your reverse proxy passes a wrongly configured \"%s\" header: falling back to default \"https\"", + scheme_str, OIDC_HTTP_HDR_X_FORWARDED_PROTO); scheme_str = "https"; } return scheme_str; @@ -631,8 +634,8 @@ static const char* oidc_get_port_from_host(const char *host_hdr) { /* * get the URL port that is currently being accessed */ -static const char* oidc_get_current_url_port(const request_rec *r, const char *scheme_str, - const apr_byte_t x_forwarded_headers) { +static const char* oidc_get_current_url_port(const request_rec *r, + const char *scheme_str, const apr_byte_t x_forwarded_headers) { const char *host_hdr = NULL; const char *port_str = NULL; @@ -682,13 +685,15 @@ static const char* oidc_get_current_url_port(const request_rec *r, const char *s * if X-Forwarded-Proto assume the default port otherwise the * port should have been set in the X-Forwarded-Port header */ - if ((x_forwarded_headers & OIDC_HDR_X_FORWARDED_PROTO) && (oidc_util_hdr_in_x_forwarded_proto_get(r))) + if ((x_forwarded_headers & OIDC_HDR_X_FORWARDED_PROTO) + && (oidc_util_hdr_in_x_forwarded_proto_get(r))) return NULL; /* * do the same for the Forwarded: proto= header */ - if ((x_forwarded_headers & OIDC_HDR_FORWARDED) && (oidc_util_hdr_forwarded_get(r, "proto"))) + if ((x_forwarded_headers & OIDC_HDR_FORWARDED) + && (oidc_util_hdr_forwarded_get(r, "proto"))) return NULL; /* @@ -708,7 +713,8 @@ static const char* oidc_get_current_url_port(const request_rec *r, const char *s /* * get the hostname part of the URL that is currently being accessed */ -const char* oidc_get_current_url_host(request_rec *r, const apr_byte_t x_forwarded_headers) { +const char* oidc_get_current_url_host(request_rec *r, + const apr_byte_t x_forwarded_headers) { const char *host_str = NULL; char *p = NULL; char *i = NULL; @@ -742,7 +748,8 @@ const char* oidc_get_current_url_host(request_rec *r, const apr_byte_t x_forward /* * get the base part of the current URL (scheme + host (+ port)) */ -static const char* oidc_get_current_url_base(request_rec *r, const apr_byte_t x_forwarded_headers) { +static const char* oidc_get_current_url_base(request_rec *r, + const apr_byte_t x_forwarded_headers) { const char *scheme_str = NULL; const char *host_str = NULL; @@ -756,7 +763,7 @@ static const char* oidc_get_current_url_base(request_rec *r, const apr_byte_t x_ port_str = port_str ? apr_psprintf(r->pool, ":%s", port_str) : ""; char *url = apr_pstrcat(r->pool, scheme_str, "://", host_str, port_str, - NULL); + NULL); return url; } @@ -775,17 +782,19 @@ char* oidc_get_current_url(request_rec *r, const apr_byte_t x_forwarded_headers) if ((path) && (path[0] != '/')) { _oidc_memset(&uri, 0, sizeof(apr_uri_t)); if (apr_uri_parse(r->pool, r->uri, &uri) == APR_SUCCESS) - path = - apr_pstrcat(r->pool, uri.path, (r->args != NULL && *r->args != '\0' ? "?" : ""), r->args, - NULL); + path = apr_pstrcat(r->pool, uri.path, + (r->args != NULL && *r->args != '\0' ? "?" : ""), r->args, + NULL); else - oidc_warn(r, "apr_uri_parse failed on non-relative URL: %s", r->uri); + oidc_warn(r, "apr_uri_parse failed on non-relative URL: %s", + r->uri); } else { /* make sure we retain URL-encoded characters original URL that we send the user back to */ path = r->unparsed_uri; } - url = apr_pstrcat(r->pool, oidc_get_current_url_base(r, x_forwarded_headers), path, NULL); + url = apr_pstrcat(r->pool, + oidc_get_current_url_base(r, x_forwarded_headers), path, NULL); oidc_debug(r, "current URL '%s'", url); @@ -856,7 +865,7 @@ size_t oidc_curl_write(void *contents, size_t size, size_t nmemb, void *userp) { if (mem->size + realsize > OIDC_CURL_MAX_RESPONSE_SIZE) { oidc_error(mem->r, "HTTP response larger than maximum allowed size: current size=%ld, additional size=%ld, max=%d", - (long)mem->size, (long)realsize, OIDC_CURL_MAX_RESPONSE_SIZE); + (long )mem->size, (long )realsize, OIDC_CURL_MAX_RESPONSE_SIZE); return 0; } @@ -865,7 +874,7 @@ size_t oidc_curl_write(void *contents, size_t size, size_t nmemb, void *userp) { if (newptr == NULL) { oidc_error(mem->r, "memory allocation for new buffer of %ld bytes failed", - (long)(mem->size + realsize + 1)); + (long )(mem->size + realsize + 1)); return 0; } @@ -1023,22 +1032,29 @@ static void oidc_util_set_curl_ssl_options(request_rec *r, CURL *curl) { static apr_byte_t oidc_util_http_call(request_rec *r, const char *url, const char *data, const char *content_type, const char *basic_auth, const char *bearer_token, int ssl_validate_server, char **response, - int timeout, const oidc_outgoing_proxy_t *outgoing_proxy, + oidc_http_timeout_t *http_timeout, + const oidc_outgoing_proxy_t *outgoing_proxy, apr_array_header_t *pass_cookies, const char *ssl_cert, const char *ssl_key, const char *ssl_key_pwd) { + char curlError[CURL_ERROR_SIZE]; oidc_curl_buffer curlBuffer; - CURL *curl; + CURL *curl = NULL; struct curl_slist *h_list = NULL; - int i; + int i = 0; + CURLcode res = CURLE_OK; + long response_code = 0; + apr_byte_t rv = FALSE; oidc_cfg *c = ap_get_module_config(r->server->module_config, &auth_openidc_module); /* do some logging about the inputs */ oidc_debug(r, - "url=%s, data=%s, content_type=%s, basic_auth=%s, bearer_token=%s, ssl_validate_server=%d, timeout=%d, outgoing_proxy=%s:%s:%d, pass_cookies=%pp, ssl_cert=%s, ssl_key=%s, ssl_key_pwd=%s", + "url=%s, data=%s, content_type=%s, basic_auth=%s, bearer_token=%s, ssl_validate_server=%d, request_timeout=%d, connect_timeout=%d, retries=%d, retry_interval=%d, outgoing_proxy=%s:%s:%d, pass_cookies=%pp, ssl_cert=%s, ssl_key=%s, ssl_key_pwd=%s", url, data, content_type, basic_auth ? "****" : "null", bearer_token, - ssl_validate_server, timeout, outgoing_proxy->host_port, + ssl_validate_server, http_timeout->request_timeout, + http_timeout->connect_timeout, http_timeout->retries, + (int )http_timeout->retry_interval, outgoing_proxy->host_port, outgoing_proxy->username_password ? "****" : "(null)", (int )outgoing_proxy->auth_type, pass_cookies, ssl_cert, ssl_key, ssl_key_pwd ? "****" : "(null)"); @@ -1046,7 +1062,7 @@ static apr_byte_t oidc_util_http_call(request_rec *r, const char *url, curl = curl_easy_init(); if (curl == NULL) { oidc_error(r, "curl_easy_init() error"); - return FALSE; + goto end; } /* set the error buffer as empty before performing a request */ @@ -1060,8 +1076,10 @@ static apr_byte_t oidc_util_http_call(request_rec *r, const char *url, curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L); curl_easy_setopt(curl, CURLOPT_MAXREDIRS, 5L); - /* set the timeout */ - curl_easy_setopt(curl, CURLOPT_TIMEOUT, timeout); + /* set the timeouts */ + curl_easy_setopt(curl, CURLOPT_TIMEOUT, http_timeout->request_timeout); + curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, + http_timeout->connect_timeout); /* setup the buffer where the response will be written to */ curlBuffer.r = r; @@ -1071,14 +1089,14 @@ static apr_byte_t oidc_util_http_call(request_rec *r, const char *url, curl_easy_setopt(curl, CURLOPT_WRITEDATA, (void* )&curlBuffer); #ifndef LIBCURL_NO_CURLPROTO - #if LIBCURL_VERSION_NUM >= 0x075500 - curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"); - curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, "http,https"); - #else - curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, - CURLPROTO_HTTP|CURLPROTO_HTTPS); - curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); - #endif +#if LIBCURL_VERSION_NUM >= 0x075500 + curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS_STR, "http,https"); + curl_easy_setopt(curl, CURLOPT_PROTOCOLS_STR, "http,https"); +#else + curl_easy_setopt(curl, CURLOPT_REDIR_PROTOCOLS, + CURLPROTO_HTTP|CURLPROTO_HTTPS); + curl_easy_setopt(curl, CURLOPT_PROTOCOLS, CURLPROTO_HTTP|CURLPROTO_HTTPS); +#endif #endif /* set the options for validating the SSL server certificate that the remote site presents */ @@ -1189,15 +1207,25 @@ static apr_byte_t oidc_util_http_call(request_rec *r, const char *url, curl_easy_setopt(curl, CURLOPT_URL, url); /* call it and record the result */ - int rv = TRUE; - if (curl_easy_perform(curl) != CURLE_OK) { - oidc_error(r, "curl_easy_perform() failed on: %s (%s)", url, - curlError[0] ? curlError : ""); - rv = FALSE; - goto out; + for (i = 0; i <= http_timeout->retries; i++) { + res = curl_easy_perform(curl); + if (res == CURLE_OK) { + rv = TRUE; + break; + } + oidc_error(r, "curl_easy_perform(%d/%d) failed for %s with: [%s]", + i + 1, http_timeout->retries + 1, url, + curlError[0] ? curlError : ""); + /* in case of a request/transfer timeout (which includes the connect timeout) we'll not retry */ + if (res == CURLE_OPERATION_TIMEDOUT) + break; + /* in case of a connectivity/network glitch we'll back off before retrying */ + if (i < http_timeout->retries) + apr_sleep(http_timeout->retry_interval); } + if (rv == FALSE) + goto end; - long response_code; curl_easy_getinfo(curl, CURLINFO_RESPONSE_CODE, &response_code); oidc_debug(r, "HTTP response code=%ld", response_code); @@ -1206,12 +1234,13 @@ static apr_byte_t oidc_util_http_call(request_rec *r, const char *url, /* set and log the response */ oidc_debug(r, "response=%s", *response ? *response : ""); -out: + end: /* cleanup and return the result */ if (h_list != NULL) curl_slist_free_all(h_list); - curl_easy_cleanup(curl); + if (curl != NULL) + curl_easy_cleanup(curl); return rv; } @@ -1222,12 +1251,13 @@ static apr_byte_t oidc_util_http_call(request_rec *r, const char *url, apr_byte_t oidc_util_http_get(request_rec *r, const char *url, const apr_table_t *params, const char *basic_auth, const char *bearer_token, int ssl_validate_server, char **response, - int timeout, const oidc_outgoing_proxy_t *outgoing_proxy, + oidc_http_timeout_t *http_timeout, + const oidc_outgoing_proxy_t *outgoing_proxy, apr_array_header_t *pass_cookies, const char *ssl_cert, const char *ssl_key, const char *ssl_key_pwd) { char *query_url = oidc_util_http_query_encoded_url(r, url, params); return oidc_util_http_call(r, query_url, NULL, NULL, basic_auth, - bearer_token, ssl_validate_server, response, timeout, + bearer_token, ssl_validate_server, response, http_timeout, outgoing_proxy, pass_cookies, ssl_cert, ssl_key, ssl_key_pwd); } @@ -1237,13 +1267,14 @@ apr_byte_t oidc_util_http_get(request_rec *r, const char *url, apr_byte_t oidc_util_http_post_form(request_rec *r, const char *url, const apr_table_t *params, const char *basic_auth, const char *bearer_token, int ssl_validate_server, char **response, - int timeout, const oidc_outgoing_proxy_t *outgoing_proxy, + oidc_http_timeout_t *http_timeout, + const oidc_outgoing_proxy_t *outgoing_proxy, apr_array_header_t *pass_cookies, const char *ssl_cert, const char *ssl_key, const char *ssl_key_pwd) { char *data = oidc_util_http_form_encoded_data(r, params); return oidc_util_http_call(r, url, data, OIDC_CONTENT_TYPE_FORM_ENCODED, basic_auth, bearer_token, - ssl_validate_server, response, timeout, outgoing_proxy, + ssl_validate_server, response, http_timeout, outgoing_proxy, pass_cookies, ssl_cert, ssl_key, ssl_key_pwd); } @@ -1252,14 +1283,16 @@ apr_byte_t oidc_util_http_post_form(request_rec *r, const char *url, */ apr_byte_t oidc_util_http_post_json(request_rec *r, const char *url, json_t *json, const char *basic_auth, const char *bearer_token, - int ssl_validate_server, char **response, int timeout, - const oidc_outgoing_proxy_t *outgoing_proxy, apr_array_header_t *pass_cookies, - const char *ssl_cert, const char *ssl_key, const char *ssl_key_pwd) { + int ssl_validate_server, char **response, + oidc_http_timeout_t *http_timeout, + const oidc_outgoing_proxy_t *outgoing_proxy, + apr_array_header_t *pass_cookies, const char *ssl_cert, + const char *ssl_key, const char *ssl_key_pwd) { char *data = json != NULL ? oidc_util_encode_json_object(r, json, JSON_COMPACT) : NULL; return oidc_util_http_call(r, url, data, OIDC_CONTENT_TYPE_JSON, basic_auth, - bearer_token, ssl_validate_server, response, timeout, + bearer_token, ssl_validate_server, response, http_timeout, outgoing_proxy, pass_cookies, ssl_cert, ssl_key, ssl_key_pwd); } @@ -1286,7 +1319,8 @@ static char* oidc_util_get_cookie_path(request_rec *r) { char *requestPath = oidc_util_get_path(r); char *cookie_path = oidc_cfg_dir_cookie_path(r); if (cookie_path != NULL) { - if (_oidc_strncmp(cookie_path, requestPath, _oidc_strlen(cookie_path)) == 0) + if (_oidc_strncmp(cookie_path, requestPath, _oidc_strlen(cookie_path)) + == 0) rv = cookie_path; else { oidc_warn(r, @@ -1330,16 +1364,18 @@ const char* oidc_util_set_cookie_append_value(request_rec *r) { } apr_byte_t oidc_util_request_is_secure(request_rec *r, const oidc_cfg *c) { - return (apr_strnatcasecmp("https", oidc_get_current_url_scheme(r, c->x_forwarded_headers)) == 0); + return (apr_strnatcasecmp("https", + oidc_get_current_url_scheme(r, c->x_forwarded_headers)) == 0); } /* * set a cookie in the HTTP response headers */ -void oidc_util_set_cookie(request_rec *r, const char *cookieName, const char *cookieValue, - apr_time_t expires, const char *ext) { +void oidc_util_set_cookie(request_rec *r, const char *cookieName, + const char *cookieValue, apr_time_t expires, const char *ext) { - oidc_cfg *c = ap_get_module_config(r->server->module_config, &auth_openidc_module); + oidc_cfg *c = ap_get_module_config(r->server->module_config, + &auth_openidc_module); char *headerString = NULL; char *expiresString = NULL; const char *appendString = NULL; @@ -1360,33 +1396,36 @@ void oidc_util_set_cookie(request_rec *r, const char *cookieName, const char *co headerString = apr_psprintf(r->pool, "%s=%s", cookieName, cookieValue); headerString = apr_psprintf(r->pool, "%s; %s=%s", headerString, - OIDC_COOKIE_FLAG_PATH, oidc_util_get_cookie_path(r)); + OIDC_COOKIE_FLAG_PATH, oidc_util_get_cookie_path(r)); if (expiresString != NULL) headerString = apr_psprintf(r->pool, "%s; %s=%s", headerString, - OIDC_COOKIE_FLAG_EXPIRES, expiresString); + OIDC_COOKIE_FLAG_EXPIRES, expiresString); if (c->cookie_domain != NULL) headerString = apr_psprintf(r->pool, "%s; %s=%s", headerString, - OIDC_COOKIE_FLAG_DOMAIN, c->cookie_domain); + OIDC_COOKIE_FLAG_DOMAIN, c->cookie_domain); if (oidc_util_request_is_secure(r, c)) headerString = apr_psprintf(r->pool, "%s; %s", headerString, - OIDC_COOKIE_FLAG_SECURE); + OIDC_COOKIE_FLAG_SECURE); if (c->cookie_http_only != FALSE) headerString = apr_psprintf(r->pool, "%s; %s", headerString, - OIDC_COOKIE_FLAG_HTTP_ONLY); + OIDC_COOKIE_FLAG_HTTP_ONLY); appendString = oidc_util_set_cookie_append_value(r); if (appendString != NULL) - headerString = apr_psprintf(r->pool, "%s; %s", headerString, appendString); + headerString = apr_psprintf(r->pool, "%s; %s", headerString, + appendString); else if (ext != NULL) headerString = apr_psprintf(r->pool, "%s; %s", headerString, ext); /* sanity check on overall cookie value size */ if (_oidc_strlen(headerString) > OIDC_COOKIE_MAX_SIZE) { - oidc_warn(r, "the length of the cookie value (%d) is greater than %d(!) bytes, this may not work with all browsers/server combinations: consider switching to a server side caching!", (int )_oidc_strlen(headerString), OIDC_COOKIE_MAX_SIZE); + oidc_warn(r, + "the length of the cookie value (%d) is greater than %d(!) bytes, this may not work with all browsers/server combinations: consider switching to a server side caching!", + (int )_oidc_strlen(headerString), OIDC_COOKIE_MAX_SIZE); } /* use r->err_headers_out so we always print our headers (even on 302 redirect) - headers_out only prints on 2xx responses */ @@ -1415,7 +1454,8 @@ char* oidc_util_get_cookie(request_rec *r, const char *cookieName) { cookie++; /* see if we've found the cookie that we're looking for */ - if ((_oidc_strncmp(cookie, cookieName, _oidc_strlen(cookieName)) == 0) + if ((_oidc_strncmp(cookie, cookieName, _oidc_strlen(cookieName)) + == 0) && (cookie[_oidc_strlen(cookieName)] == OIDC_CHAR_EQUAL)) { /* skip to the meat of the parameter (the value after the '=') */ @@ -2008,9 +2048,11 @@ apr_byte_t oidc_util_read_post_params(request_rec *r, apr_table_t *table, const char *content_type = NULL; content_type = oidc_util_hdr_in_content_type_get(r); - if ((r->method_number != M_POST) || (content_type == NULL) || (strstr(content_type, - OIDC_CONTENT_TYPE_FORM_ENCODED) != content_type)) { - oidc_debug(r, "required content-type %s not found", OIDC_CONTENT_TYPE_FORM_ENCODED); + if ((r->method_number != M_POST) || (content_type == NULL) + || (strstr(content_type, + OIDC_CONTENT_TYPE_FORM_ENCODED) != content_type)) { + oidc_debug(r, "required content-type %s not found", + OIDC_CONTENT_TYPE_FORM_ENCODED); goto end; } @@ -2048,7 +2090,8 @@ apr_byte_t oidc_util_file_read(request_rec *r, const char *path, /* open the file if it exists */ if ((rc = apr_file_open(&fd, path, APR_FOPEN_READ | APR_FOPEN_BUFFERED, APR_OS_DEFAULT, r->pool)) != APR_SUCCESS) { - oidc_warn(r, "no file found at: \"%s\" (%s)", path, apr_strerror(rc, s_err, sizeof(s_err))); + oidc_warn(r, "no file found at: \"%s\" (%s)", path, + apr_strerror(rc, s_err, sizeof(s_err))); return FALSE; } @@ -2265,7 +2308,8 @@ void oidc_util_set_app_info(request_rec *r, const char *s_key, if (s_value != NULL) { if (pass_as == OIDC_PASS_APP_INFO_AS_BASE64URL) { - oidc_base64url_encode(r, &d_value, s_value, _oidc_strlen(s_value), TRUE); + oidc_base64url_encode(r, &d_value, s_value, _oidc_strlen(s_value), + TRUE); } else if (pass_as == OIDC_PASS_APP_INFO_AS_LATIN1) { d_value = oidc_util_utf8_to_latin1(r, s_value); } @@ -2279,9 +2323,10 @@ void oidc_util_set_app_info(request_rec *r, const char *s_key, /* do some logging about this event */ oidc_debug(r, "setting environment variable \"%s: %s\"", s_name, - (d_value != NULL) ? d_value : s_value); + (d_value != NULL) ? d_value : s_value); - apr_table_set(r->subprocess_env, s_name, (d_value != NULL) ? d_value : s_value); + apr_table_set(r->subprocess_env, s_name, + (d_value != NULL) ? d_value : s_value); } } @@ -2330,7 +2375,8 @@ void oidc_util_set_app_infos(request_rec *r, json_t *j_attrs, } else if (json_is_integer(j_value)) { - if (snprintf(s_int, 255, "%ld", (long) json_integer_value(j_value)) > 0) { + if (snprintf(s_int, 255, "%ld", (long) json_integer_value(j_value)) + > 0) { /* set long value in the application header whose name is based on the key and the prefix */ oidc_util_set_app_info(r, s_key, s_int, claim_prefix, as_header, as_env_var, pass_as); @@ -2359,7 +2405,7 @@ void oidc_util_set_app_infos(request_rec *r, json_t *j_attrs, /* some logging about what we're going to do */ oidc_debug(r, "parsing attribute array for key \"%s\" (#nr-of-elems: %lu)", - s_key, (unsigned long)json_array_size(j_value)); + s_key, (unsigned long )json_array_size(j_value)); /* string to hold the concatenated array string values */ char *s_concat = apr_pstrdup(r->pool, ""); @@ -2489,8 +2535,8 @@ apr_byte_t oidc_json_object_get_string(apr_pool_t *pool, json_t *json, /* * get (optional) int from a JSON object */ -apr_byte_t oidc_json_object_get_int(const json_t *json, - const char *name, int *value, const int default_value) { +apr_byte_t oidc_json_object_get_int(const json_t *json, const char *name, + int *value, const int default_value) { const json_t *v = NULL; *value = default_value; if (json != NULL) { @@ -2505,8 +2551,8 @@ apr_byte_t oidc_json_object_get_int(const json_t *json, /* * get (optional) boolean from a JSON object */ -apr_byte_t oidc_json_object_get_bool(const json_t *json, - const char *name, int *value, const int default_value) { +apr_byte_t oidc_json_object_get_bool(const json_t *json, const char *name, + int *value, const int default_value) { const json_t *v = NULL; *value = default_value; if (json != NULL) { @@ -2585,8 +2631,8 @@ apr_byte_t oidc_util_create_symmetric_key(request_rec *r, } else { /* hash the client_secret first, this is OpenID Connect specific */ oidc_jose_hash_bytes(r->pool, hash_algo, - (const unsigned char*) client_secret, _oidc_strlen(client_secret), - &key, &key_len, &err); + (const unsigned char*) client_secret, + _oidc_strlen(client_secret), &key, &key_len, &err); } if ((key != NULL) && (key_len > 0)) {