1 /*
2 * Licensed to the Apache Software Foundation (ASF) under one
3 * or more contributor license agreements. See the NOTICE file
4 * distributed with this work for additional information
5 * regarding copyright ownership. The ASF licenses this file
6 * to you under the Apache License, Version 2.0 (the
7 * "License"); you may not use this file except in compliance
8 * with the License. You may obtain a copy of the License at
9 *
10 * http://www.apache.org/licenses/LICENSE-2.0
11 *
12 * Unless required by applicable law or agreed to in writing,
13 * software distributed under the License is distributed on an
14 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15 * KIND, either express or implied. See the License for the
16 * specific language governing permissions and limitations
17 * under the License.
18 */
19
20 /***************************************************************************
21 * Copyright (C) 2017-2021 ZmartZone Holding BV
22 * Copyright (C) 2013-2017 Ping Identity Corporation
23 * All rights reserved.
24 *
25 * DISCLAIMER OF WARRANTIES:
26 *
27 * THE SOFTWARE PROVIDED HEREUNDER IS PROVIDED ON AN "AS IS" BASIS, WITHOUT
28 * ANY WARRANTIES OR REPRESENTATIONS EXPRESS, IMPLIED OR STATUTORY; INCLUDING,
29 * WITHOUT LIMITATION, WARRANTIES OF QUALITY, PERFORMANCE, NONINFRINGEMENT,
30 * MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. NOR ARE THERE ANY
31 * WARRANTIES CREATED BY A COURSE OR DEALING, COURSE OF PERFORMANCE OR TRADE
32 * USAGE. FURTHERMORE, THERE ARE NO WARRANTIES THAT THE SOFTWARE WILL MEET
33 * YOUR NEEDS OR BE FREE FROM ERRORS, OR THAT THE OPERATION OF THE SOFTWARE
34 * WILL BE UNINTERRUPTED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS OR
35 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
36 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES HOWEVER CAUSED AND ON ANY THEORY OF
37 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
38 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
39 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
40 *
41 * @Author: Hans Zandbelt - hans.zandbelt@zmartzone.eu
42 */
43
44 #include <apr.h>
45 #include <apr_errno.h>
46 #include <apr_strings.h>
47 #include <apr_portable.h>
48 #include <apr_base64.h>
49
50 #include <httpd.h>
51 #include <http_config.h>
52 #include <http_log.h>
53 #include <http_request.h>
54 #include <ap_provider.h>
55
56 #include <curl/curl.h>
57
58 #include "mod_auth_openidc.h"
59 #include "parse.h"
60
61 #define OPENSSL_THREAD_DEFINES
62 #include <openssl/opensslconf.h>
63 #include <openssl/opensslv.h>
64 #include <openssl/evp.h>
65 #if (OPENSSL_VERSION_NUMBER < 0x01000000)
66 #define OPENSSL_NO_THREADID
67 #endif
68
69 /* validate SSL server certificates by default */
70 #define OIDC_DEFAULT_SSL_VALIDATE_SERVER 1
71 /* validate issuer by default */
72 #define OIDC_DEFAULT_VALIDATE_ISSUER 1
73 /* default scope requested from the OP */
74 #define OIDC_DEFAULT_SCOPE "openid"
75 /* default claim delimiter for multi-valued claims passed in a HTTP header */
76 #define OIDC_DEFAULT_CLAIM_DELIMITER ","
77 /* default prefix for claim names being passed in HTTP headers */
78 #define OIDC_DEFAULT_CLAIM_PREFIX "OIDC_CLAIM_"
79 /* default name for the claim that will contain the REMOTE_USER value for OpenID Connect protected paths */
80 #define OIDC_DEFAULT_CLAIM_REMOTE_USER "sub@"
81 /* default name for the claim that will contain the REMOTE_USER value for OAuth 2.0 protected paths */
82 #define OIDC_DEFAULT_OAUTH_CLAIM_REMOTE_USER "sub"
83 /* default name of the session cookie */
84 #define OIDC_DEFAULT_COOKIE "mod_auth_openidc_session"
85 /* default for the HTTP header name in which the remote user name is passed */
86 #define OIDC_DEFAULT_AUTHN_HEADER NULL
87 /* default client_name the client uses for dynamic client registration */
88 #define OIDC_DEFAULT_CLIENT_NAME "OpenID Connect Apache Module (mod_auth_openidc)"
89 /* timeouts in seconds for HTTP calls that may take a long time */
90 #define OIDC_DEFAULT_HTTP_TIMEOUT_LONG 60
91 /* timeouts in seconds for HTTP calls that should take a short time (registry/discovery related) */
92 #define OIDC_DEFAULT_HTTP_TIMEOUT_SHORT 5
93 /* default session storage type */
94 #define OIDC_DEFAULT_SESSION_TYPE OIDC_SESSION_TYPE_SERVER_CACHE
95 /* default client-cookie chunking size */
96 #define OIDC_DEFAULT_SESSION_CLIENT_COOKIE_CHUNK_SIZE 4000
97 /* timeout in seconds after which state expires */
98 #define OIDC_DEFAULT_STATE_TIMEOUT 300
99 /* maximum number of parallel state cookies; 0 means unlimited, until the browser or server gives up */
100 #define OIDC_DEFAULT_MAX_NUMBER_OF_STATE_COOKIES 7
101 /* default setting for deleting the oldest state cookies */
102 #define OIDC_DEFAULT_DELETE_OLDEST_STATE_COOKIES 0
103 /* default session inactivity timeout */
104 #define OIDC_DEFAULT_SESSION_INACTIVITY_TIMEOUT 300
105 /* default session max duration */
106 #define OIDC_DEFAULT_SESSION_MAX_DURATION 3600 * 8
107 /* default OpenID Connect authorization response type */
108 #define OIDC_DEFAULT_RESPONSE_TYPE OIDC_PROTO_CODE
109 /* default duration in seconds after which retrieved JWS should be refreshed */
110 #define OIDC_DEFAULT_JWKS_REFRESH_INTERVAL 3600
111 /* default max cache size for shm */
112 #define OIDC_DEFAULT_CACHE_SHM_SIZE 500
113 /* default max cache entry size for shm: # value + # key + # overhead */
114 #define OIDC_DEFAULT_CACHE_SHM_ENTRY_SIZE_MAX 16384 + 512 + 17
115 /* minimum size of a cache entry */
116 #define OIDC_MINIMUM_CACHE_SHM_ENTRY_SIZE_MAX 8192 + 512 + 17
117 /* for issued-at timestamp (iat) checking */
118 #define OIDC_DEFAULT_IDTOKEN_IAT_SLACK 600
119 /* for file-based caching: clean interval in seconds */
120 #define OIDC_DEFAULT_CACHE_FILE_CLEAN_INTERVAL 60
121 /* set httponly flag on cookies */
122 #define OIDC_DEFAULT_COOKIE_HTTPONLY 1
123 /* set Same-Site flag on cookies */
124 #define OIDC_DEFAULT_COOKIE_SAME_SITE 0
125 /* default cookie path */
126 #define OIDC_DEFAULT_COOKIE_PATH "/"
127 /* default OAuth 2.0 introspection token parameter name */
128 #define OIDC_DEFAULT_OAUTH_TOKEN_PARAM_NAME "token"
129 /* default OAuth 2.0 introspection call HTTP method */
130 #define OIDC_DEFAULT_OAUTH_ENDPOINT_METHOD OIDC_INTROSPECTION_METHOD_POST
131 /* default OAuth 2.0 non-spec compliant introspection expiry claim name */
132 #define OIDC_DEFAULT_OAUTH_EXPIRY_CLAIM_NAME OIDC_PROTO_EXPIRES_IN
133 /* default OAuth 2.0 non-spec compliant introspection expiry claim format */
134 #define OIDC_DEFAULT_OAUTH_EXPIRY_CLAIM_FORMAT OIDC_CLAIM_FORMAT_RELATIVE
135 /* default OAuth 2.0 non-spec compliant introspection expiry claim required */
136 #define OIDC_DEFAULT_OAUTH_EXPIRY_CLAIM_REQUIRED TRUE
137 /* default refresh interval in seconds after which claims from the user info endpoint should be refreshed */
138 #define OIDC_DEFAULT_USERINFO_REFRESH_INTERVAL 0
139 /* default for preserving POST parameters across authentication requests */
140 #define OIDC_DEFAULT_PRESERVE_POST 0
141 /* default for passing the access token in a header/environment variable */
142 #define OIDC_DEFAULT_PASS_REFRESH_TOKEN 0
143 /* default for passing app info in headers */
144 #define OIDC_DEFAULT_PASS_APP_INFO_IN_HEADERS 1
145 /* default for passing app info in environment variables */
146 #define OIDC_DEFAULT_PASS_APP_INFO_IN_ENVVARS 1
147 /* default for passing app info in base64 encoded format */
148 #define OIDC_DEFAULT_PASS_APP_INFO_BASE64URL 0
149 /* default value for the token introspection interval (0 = disabled, no expiry of claims) */
150 #define OIDC_DEFAULT_TOKEN_INTROSPECTION_INTERVAL 0
151 /* default action to take on an incoming unauthenticated request */
152 #define OIDC_DEFAULT_UNAUTH_ACTION OIDC_UNAUTH_AUTHENTICATE
153 /* default action to take on an incoming authorized request */
154 #define OIDC_DEFAULT_UNAUTZ_ACTION OIDC_UNAUTZ_RETURN403
155 /* defines for how long provider metadata will be cached */
156 #define OIDC_DEFAULT_PROVIDER_METADATA_REFRESH_INTERVAL 0
157 /* defines the default token binding policy for a provider */
158 #define OIDC_DEFAULT_PROVIDER_TOKEN_BINDING_POLICY OIDC_TOKEN_BINDING_POLICY_OPTIONAL
159 /* defines the default token binding policy for OAuth 2.0 access tokens */
160 #define OIDC_DEFAULT_OAUTH_ACCESS_TOKEN_BINDING_POLICY OIDC_TOKEN_BINDING_POLICY_OPTIONAL
161 /* define the default HTTP method used to send the authentication request to the provider */
162 #define OIDC_DEFAULT_AUTH_REQUEST_METHOD OIDC_AUTH_REQUEST_METHOD_GET
163 /* define whether the issuer will be added to the redirect uri by default to mitigate the IDP mixup attack */
164 #define OIDC_DEFAULT_PROVIDER_ISSUER_SPECIFIC_REDIRECT_URI 0
165 /* define the default number of seconds that the access token needs to be valid for; -1 = no refresh */
166 #define OIDC_DEFAULT_REFRESH_ACCESS_TOKEN_BEFORE_EXPIRY -1
167 /* default setting for calculating the fingerprint of the state from request headers during authentication */
168 #define OIDC_DEFAULT_STATE_INPUT_HEADERS (OIDC_STATE_INPUT_HEADERS_USER_AGENT | OIDC_STATE_INPUT_HEADERS_X_FORWARDED_FOR)
169 /* default prefix of the state cookie that binds the state in the authorization request/response to the browser */
170 #define OIDC_DEFAULT_STATE_COOKIE_PREFIX "mod_auth_openidc_state_"
171
172 #define OIDCProviderMetadataURL "OIDCProviderMetadataURL"
173 #define OIDCProviderIssuer "OIDCProviderIssuer"
174 #define OIDCProviderAuthorizationEndpoint "OIDCProviderAuthorizationEndpoint"
175 #define OIDCProviderTokenEndpoint "OIDCProviderTokenEndpoint"
176 #define OIDCProviderTokenEndpointAuth "OIDCProviderTokenEndpointAuth"
177 #define OIDCProviderTokenEndpointParams "OIDCProviderTokenEndpointParams"
178 #define OIDCProviderRegistrationEndpointJson "OIDCProviderRegistrationEndpointJson"
179 #define OIDCProviderUserInfoEndpoint "OIDCProviderUserInfoEndpoint"
180 #define OIDCProviderRevocationEndpoint "OIDCProviderRevocationEndpoint"
181 #define OIDCProviderCheckSessionIFrame "OIDCProviderCheckSessionIFrame"
182 #define OIDCProviderEndSessionEndpoint "OIDCProviderEndSessionEndpoint"
183 #define OIDCProviderBackChannelLogoutSupported "OIDCProviderBackChannelLogoutSupported"
184 #define OIDCProviderJwksUri "OIDCProviderJwksUri"
185 #define OIDCResponseType "OIDCResponseType"
186 #define OIDCResponseMode "OIDCResponseMode"
187 #define OIDCPublicKeyFiles "OIDCPublicKeyFiles"
188 #define OIDCClientJwksUri "OIDCClientJwksUri"
189 #define OIDCIDTokenSignedResponseAlg "OIDCIDTokenSignedResponseAlg"
190 #define OIDCIDTokenEncryptedResponseAlg "OIDCIDTokenEncryptedResponseAlg"
191 #define OIDCIDTokenEncryptedResponseEnc "OIDCIDTokenEncryptedResponseEnc"
192 #define OIDCUserInfoSignedResponseAlg "OIDCUserInfoSignedResponseAlg"
193 #define OIDCUserInfoEncryptedResponseAlg "OIDCUserInfoEncryptedResponseAlg"
194 #define OIDCUserInfoEncryptedResponseEnc "OIDCUserInfoEncryptedResponseEnc"
195 #define OIDCUserInfoTokenMethod "OIDCUserInfoTokenMethod"
196 #define OIDCTokenBindingPolicy "OIDCTokenBindingPolicy"
197 #define OIDCSSLValidateServer "OIDCSSLValidateServer"
198 #define OIDCValidateIssuer "OIDCValidateIssuer"
199 #define OIDCClientName "OIDCClientName"
200 #define OIDCClientContact "OIDCClientContact"
201 #define OIDCScope "OIDCScope"
202 #define OIDCPathScope "OIDCPathScope"
203 #define OIDCJWKSRefreshInterval "OIDCJWKSRefreshInterval"
204 #define OIDCIDTokenIatSlack "OIDCIDTokenIatSlack"
205 #define OIDCSessionMaxDuration "OIDCSessionMaxDuration"
206 #define OIDCAuthRequestParams "OIDCAuthRequestParams"
207 #define OIDCPathAuthRequestParams "OIDCPathAuthRequestParams"
208 #define OIDCPKCEMethod "OIDCPKCEMethod"
209 #define OIDCClientID "OIDCClientID"
210 #define OIDCClientSecret "OIDCClientSecret"
211 #define OIDCClientTokenEndpointCert "OIDCClientTokenEndpointCert"
212 #define OIDCClientTokenEndpointKey "OIDCClientTokenEndpointKey"
213 #define OIDCDefaultLoggedOutURL "OIDCDefaultLoggedOutURL"
214 #define OIDCCookieHTTPOnly "OIDCCookieHTTPOnly"
215 #define OIDCCookieSameSite "OIDCCookieSameSite"
216 #define OIDCOutgoingProxy "OIDCOutgoingProxy"
217 #define OIDCCryptoPassphrase "OIDCCryptoPassphrase"
218 #define OIDCClaimDelimiter "OIDCClaimDelimiter"
219 #define OIDCPassIDTokenAs "OIDCPassIDTokenAs"
220 #define OIDCPassUserInfoAs "OIDCPassUserInfoAs"
221 #define OIDCOAuthClientID "OIDCOAuthClientID"
222 #define OIDCOAuthClientSecret "OIDCOAuthClientSecret"
223 #define OIDCOAuthIntrospectionClientAuthBearerToken "OIDCOAuthIntrospectionClientAuthBearerToken"
224 #define OIDCOAuthIntrospectionEndpoint "OIDCOAuthIntrospectionEndpoint"
225 #define OIDCOAuthIntrospectionEndpointMethod "OIDCOAuthIntrospectionEndpointMethod"
226 #define OIDCOAuthIntrospectionEndpointParams "OIDCOAuthIntrospectionEndpointParams"
227 #define OIDCOAuthIntrospectionEndpointAuth "OIDCOAuthIntrospectionEndpointAuth"
228 #define OIDCOAuthIntrospectionEndpointCert "OIDCOAuthIntrospectionEndpointCert"
229 #define OIDCOAuthIntrospectionEndpointKey "OIDCOAuthIntrospectionEndpointKey"
230 #define OIDCOAuthIntrospectionTokenParamName "OIDCOAuthIntrospectionTokenParamName"
231 #define OIDCOAuthTokenExpiryClaim "OIDCOAuthTokenExpiryClaim"
232 #define OIDCOAuthSSLValidateServer "OIDCOAuthSSLValidateServer"
233 #define OIDCOAuthVerifyCertFiles "OIDCOAuthVerifyCertFiles"
234 #define OIDCOAuthVerifySharedKeys "OIDCOAuthVerifySharedKeys"
235 #define OIDCOAuthVerifyJwksUri "OIDCOAuthVerifyJwksUri"
236 #define OIDCHTTPTimeoutLong "OIDCHTTPTimeoutLong"
237 #define OIDCHTTPTimeoutShort "OIDCHTTPTimeoutShort"
238 #define OIDCStateTimeout "OIDCStateTimeout"
239 #define OIDCStateMaxNumberOfCookies "OIDCStateMaxNumberOfCookies"
240 #define OIDCSessionInactivityTimeout "OIDCSessionInactivityTimeout"
241 #define OIDCMetadataDir "OIDCMetadataDir"
242 #define OIDCSessionCacheFallbackToCookie "OIDCSessionCacheFallbackToCookie"
243 #define OIDCSessionCookieChunkSize "OIDCSessionCookieChunkSize"
244 #define OIDCScrubRequestHeaders "OIDCScrubRequestHeaders"
245 #define OIDCCacheType "OIDCCacheType"
246 #define OIDCCacheEncrypt "OIDCCacheEncrypt"
247 #define OIDCCacheDir "OIDCCacheDir"
248 #define OIDCCacheFileCleanInterval "OIDCCacheFileCleanInterval"
249 #define OIDCRedisCachePassword "OIDCRedisCachePassword"
250 #define OIDCRedisCacheDatabase "OIDCRedisCacheDatabase"
251 #define OIDCHTMLErrorTemplate "OIDCHTMLErrorTemplate"
252 #define OIDCDiscoverURL "OIDCDiscoverURL"
253 #define OIDCPassCookies "OIDCPassCookies"
254 #define OIDCStripCookies "OIDCStripCookies"
255 #define OIDCAuthNHeader "OIDCAuthNHeader"
256 #define OIDCCookie "OIDCCookie"
257 #define OIDCUnAuthAction "OIDCUnAuthAction"
258 #define OIDCUnAutzAction "OIDCUnAutzAction"
259 #define OIDCPassClaimsAs "OIDCPassClaimsAs"
260 #define OIDCOAuthAcceptTokenAs "OIDCOAuthAcceptTokenAs"
261 #define OIDCUserInfoRefreshInterval "OIDCUserInfoRefreshInterval"
262 #define OIDCOAuthTokenIntrospectionInterval "OIDCOAuthTokenIntrospectionInterval"
263 #define OIDCPreservePost "OIDCPreservePost"
264 #define OIDCPassRefreshToken "OIDCPassRefreshToken"
265 #define OIDCRequestObject "OIDCRequestObject"
266 #define OIDCProviderMetadataRefreshInterval "OIDCProviderMetadataRefreshInterval"
267 #define OIDCProviderAuthRequestMethod "OIDCProviderAuthRequestMethod"
268 #define OIDCBlackListedClaims "OIDCBlackListedClaims"
269 #define OIDCOAuthServerMetadataURL "OIDCOAuthServerMetadataURL"
270 #define OIDCOAuthAccessTokenBindingPolicy "OIDCOAuthAccessTokenBindingPolicy"
271 #define OIDCRefreshAccessTokenBeforeExpiry "OIDCRefreshAccessTokenBeforeExpiry"
272 #define OIDCStateInputHeaders "OIDCStateInputHeaders"
273 #define OIDCRedirectURLsAllowed "OIDCRedirectURLsAllowed"
274 #define OIDCStateCookiePrefix "OIDCStateCookiePrefix"
275 #define OIDCCABundlePath "OIDCCABundlePath"
276
277 extern module AP_MODULE_DECLARE_DATA auth_openidc_module;
278
279 /*
280 * directory related configuration
281 */
282 typedef struct oidc_dir_cfg {
283 char *discover_url;
284 char *cookie_path;
285 char *cookie;
286 char *authn_header;
287 int unauth_action;
288 #if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
289 ap_expr_info_t *unauth_expression;
290 #endif
291 int unautz_action;
292 apr_array_header_t *pass_cookies;
293 apr_array_header_t *strip_cookies;
294 int pass_info_in_headers;
295 int pass_info_in_env_vars;
296 int pass_info_base64url;
297 int oauth_accept_token_in;
298 apr_hash_t *oauth_accept_token_options;
299 int oauth_token_introspect_interval;
300 int preserve_post;
301 int pass_refresh_token;
302 char *path_auth_request_params;
303 char *path_scope;
304 int refresh_access_token_before_expiry;
305 int logout_on_error_refresh;
306 char *state_cookie_prefix;
307 } oidc_dir_cfg;
308
309 #define OIDC_CONFIG_DIR_RV(cmd, rv) rv != NULL ? apr_psprintf(cmd->pool, "Invalid value for directive '%s': %s", cmd->directive->directive, rv) : NULL
310
311 /*
312 * set a boolean value in the server config
313 */
oidc_set_flag_slot(cmd_parms * cmd,void * struct_ptr,int arg)314 static const char* oidc_set_flag_slot(cmd_parms *cmd, void *struct_ptr, int arg) {
315 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
316 &auth_openidc_module);
317 return ap_set_flag_slot(cmd, cfg, arg);
318 }
319
320 /*
321 * set a string value in the server config
322 */
oidc_set_string_slot(cmd_parms * cmd,void * struct_ptr,const char * arg)323 static const char* oidc_set_string_slot(cmd_parms *cmd, void *struct_ptr,
324 const char *arg) {
325 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
326 &auth_openidc_module);
327 return ap_set_string_slot(cmd, cfg, arg);
328 }
329
330 /*
331 * set an integer value in the server config
332 */
oidc_set_int_slot(cmd_parms * cmd,void * struct_ptr,const char * arg)333 static const char* oidc_set_int_slot(cmd_parms *cmd, void *struct_ptr,
334 const char *arg) {
335 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
336 &auth_openidc_module);
337 return ap_set_int_slot(cmd, cfg, arg);
338 }
339
340 /*
341 * set a URL value in a config record
342 */
oidc_set_url_slot_type(cmd_parms * cmd,void * ptr,const char * arg,const char * type)343 static const char* oidc_set_url_slot_type(cmd_parms *cmd, void *ptr,
344 const char *arg, const char *type) {
345 const char *rv =
346 type != NULL ?
347 oidc_valid_url(cmd->pool, arg, type) :
348 oidc_valid_http_url(cmd->pool, arg);
349 if (rv == NULL)
350 rv = ap_set_string_slot(cmd, ptr, arg);
351 return rv;
352 }
353
354 /*
355 * set a HTTPS value in the server config
356 */
oidc_set_https_slot(cmd_parms * cmd,void * ptr,const char * arg)357 static const char* oidc_set_https_slot(cmd_parms *cmd, void *ptr,
358 const char *arg) {
359 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
360 &auth_openidc_module);
361 return oidc_set_url_slot_type(cmd, cfg, arg, "https");
362 }
363
364 /*
365 * set a HTTPS/HTTP value in the server config
366 */
oidc_set_url_slot(cmd_parms * cmd,void * ptr,const char * arg)367 static const char* oidc_set_url_slot(cmd_parms *cmd, void *ptr, const char *arg) {
368 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
369 &auth_openidc_module);
370 return oidc_set_url_slot_type(cmd, cfg, arg, NULL);
371 }
372
373 /*
374 * set a relative or absolute URL value in a config rec
375 */
oidc_set_relative_or_absolute_url_slot_dir_cfg(cmd_parms * cmd,void * ptr,const char * arg)376 static const char* oidc_set_relative_or_absolute_url_slot_dir_cfg(
377 cmd_parms *cmd, void *ptr, const char *arg) {
378 if (arg[0] == OIDC_CHAR_FORWARD_SLASH) {
379 // relative uri
380 apr_uri_t uri;
381 if (apr_uri_parse(cmd->pool, arg, &uri) != APR_SUCCESS) {
382 const char *rv = apr_psprintf(cmd->pool,
383 "cannot parse '%s' as relative URI", arg);
384 return OIDC_CONFIG_DIR_RV(cmd, rv);
385 } else {
386 return ap_set_string_slot(cmd, ptr, arg);
387 }
388 } else {
389 // absolute uri
390 return oidc_set_url_slot_type(cmd, ptr, arg, NULL);
391 }
392 }
393
394 /*
395 * set a relative or absolute URL value in the server config
396 */
oidc_set_relative_or_absolute_url_slot(cmd_parms * cmd,void * ptr,const char * arg)397 static const char* oidc_set_relative_or_absolute_url_slot(cmd_parms *cmd,
398 void *ptr, const char *arg) {
399 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
400 &auth_openidc_module);
401 return oidc_set_relative_or_absolute_url_slot_dir_cfg(cmd, cfg, arg);
402 }
403
404 /*
405 * set a directory value in the server config
406 */
407 // TODO: it's not really a syntax error... (could be fixed at runtime but then we'd have to restart the server)
oidc_set_dir_slot(cmd_parms * cmd,void * ptr,const char * arg)408 static const char* oidc_set_dir_slot(cmd_parms *cmd, void *ptr, const char *arg) {
409 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
410 &auth_openidc_module);
411 const char *rv = oidc_valid_dir(cmd->pool, arg);
412 if (rv == NULL)
413 rv = ap_set_string_slot(cmd, cfg, arg);
414 return rv;
415 }
416
417 /*
418 * set a path value in the server config, converting to absolute if necessary
419 */
oidc_set_path_slot(cmd_parms * cmd,void * ptr,const char * arg)420 static const char* oidc_set_path_slot(cmd_parms *cmd, void *ptr,
421 const char *arg) {
422 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
423 &auth_openidc_module);
424 const char *full_path = oidc_util_get_full_path(cmd->pool, arg);
425 return ap_set_string_slot(cmd, cfg, full_path);
426 }
427
428 /*
429 * set a string value in the server config with exec support
430 */
oidc_set_passphrase_slot(cmd_parms * cmd,void * struct_ptr,const char * arg)431 static const char* oidc_set_passphrase_slot(cmd_parms *cmd, void *struct_ptr,
432 const char *arg) {
433 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
434 &auth_openidc_module);
435 const char *passphrase = NULL;
436 #if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
437 int arglen = strlen(arg);
438 char **argv = NULL;
439 char *result = NULL;
440 /* Based on code from mod_session_crypto. */
441 if (arglen > 5 && strncmp(arg, "exec:", 5) == 0) {
442 if (apr_tokenize_to_argv(arg + 5, &argv, cmd->temp_pool) != APR_SUCCESS) {
443 return apr_pstrcat(cmd->pool,
444 "Unable to parse exec arguments from ", arg + 5, NULL);
445 }
446 argv[0] = ap_server_root_relative(cmd->temp_pool, argv[0]);
447 if (!argv[0]) {
448 return apr_pstrcat(cmd->pool, "Invalid ", cmd->cmd->name,
449 " exec location:", arg + 5, NULL);
450 }
451 result = ap_get_exec_line(cmd->pool, argv[0],
452 (const char* const*) argv);
453 if (!result) {
454 return apr_pstrcat(cmd->pool,
455 "Unable to get passphrase from exec of ", arg + 5, NULL);
456 }
457 passphrase = result;
458 } else {
459 passphrase = arg;
460 }
461 #else
462 passphrase = arg;
463 #endif
464
465 return ap_set_string_slot(cmd, cfg, passphrase);
466 }
467
468 /*
469 * set the cookie domain in the server config and check it syntactically
470 */
oidc_set_cookie_domain(cmd_parms * cmd,void * ptr,const char * value)471 static const char* oidc_set_cookie_domain(cmd_parms *cmd, void *ptr,
472 const char *value) {
473 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
474 &auth_openidc_module);
475 const char *rv = oidc_valid_cookie_domain(cmd->pool, value);
476 if (rv == NULL)
477 cfg->cookie_domain = apr_pstrdup(cmd->pool, value);
478 return OIDC_CONFIG_DIR_RV(cmd, rv);
479 }
480
481 /*
482 * set the session storage type
483 */
oidc_set_session_type(cmd_parms * cmd,void * ptr,const char * arg)484 static const char* oidc_set_session_type(cmd_parms *cmd, void *ptr,
485 const char *arg) {
486 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
487 &auth_openidc_module);
488 const char *rv = oidc_parse_session_type(cmd->pool, arg, &cfg->session_type,
489 &cfg->persistent_session_cookie);
490 return OIDC_CONFIG_DIR_RV(cmd, rv);
491 }
492
493 /*
494 * set the maximum size of a shared memory cache entry and enforces a minimum
495 */
oidc_set_cache_shm_entry_size_max(cmd_parms * cmd,void * ptr,const char * arg)496 static const char* oidc_set_cache_shm_entry_size_max(cmd_parms *cmd, void *ptr,
497 const char *arg) {
498 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
499 &auth_openidc_module);
500 const char *rv = oidc_parse_cache_shm_entry_size_max(cmd->pool, arg,
501 &cfg->cache_shm_entry_size_max);
502 return OIDC_CONFIG_DIR_RV(cmd, rv);
503 }
504
505 /*
506 * set the cache type
507 */
oidc_set_cache_type(cmd_parms * cmd,void * ptr,const char * arg)508 static const char* oidc_set_cache_type(cmd_parms *cmd, void *ptr,
509 const char *arg) {
510 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
511 &auth_openidc_module);
512 const char *rv = oidc_parse_cache_type(cmd->pool, arg, &cfg->cache);
513 return OIDC_CONFIG_DIR_RV(cmd, rv);
514 }
515
516 /*
517 * set SSL validation slot
518 */
oidc_set_ssl_validate_slot(cmd_parms * cmd,void * struct_ptr,const char * arg)519 static const char* oidc_set_ssl_validate_slot(cmd_parms *cmd, void *struct_ptr,
520 const char *arg) {
521 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
522 &auth_openidc_module);
523 int b = 0;
524 const char *rv = oidc_parse_boolean(cmd->pool, arg, &b);
525 if (rv == NULL)
526 rv = ap_set_flag_slot(cmd, cfg, b);
527 return OIDC_CONFIG_DIR_RV(cmd, rv);
528 }
529
530 /*
531 * set validate issuer slot
532 */
oidc_set_validate_issuer_slot(cmd_parms * cmd,void * struct_ptr,const char * arg)533 static const char* oidc_set_validate_issuer_slot(cmd_parms *cmd,
534 void *struct_ptr, const char *arg) {
535 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
536 &auth_openidc_module);
537 int b = 0;
538 const char *rv = oidc_parse_boolean(cmd->pool, arg, &b);
539 if (rv == NULL)
540 rv = ap_set_flag_slot(cmd, cfg, b);
541 return OIDC_CONFIG_DIR_RV(cmd, rv);
542 }
543
544 /*
545 * return the right token endpoint authentication method validation function, based on whether private keys are set
546 */
oidc_cfg_get_valid_endpoint_auth_function(oidc_cfg * cfg)547 oidc_valid_function_t oidc_cfg_get_valid_endpoint_auth_function(oidc_cfg *cfg) {
548 return (cfg->private_keys != NULL) ?
549 oidc_valid_endpoint_auth_method :
550 oidc_valid_endpoint_auth_method_no_private_key;
551 }
552
553 /*
554 * set an authentication method for an endpoint and check it is one that we support
555 */
oidc_set_endpoint_auth_slot(cmd_parms * cmd,void * struct_ptr,const char * arg)556 static const char* oidc_set_endpoint_auth_slot(cmd_parms *cmd, void *struct_ptr,
557 const char *arg) {
558 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
559 &auth_openidc_module);
560 const char *rv = oidc_cfg_get_valid_endpoint_auth_function(cfg)(cmd->pool,
561 arg);
562 if (rv == NULL)
563 rv = ap_set_string_slot(cmd, cfg, arg);
564 return OIDC_CONFIG_DIR_RV(cmd, rv);
565 }
566
567 /*
568 * set the response type used
569 */
oidc_set_response_type(cmd_parms * cmd,void * struct_ptr,const char * arg)570 static const char* oidc_set_response_type(cmd_parms *cmd, void *struct_ptr,
571 const char *arg) {
572 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
573 &auth_openidc_module);
574
575 const char *rv = oidc_valid_response_type(cmd->pool, arg);
576 if (rv == NULL)
577 rv = ap_set_string_slot(cmd, cfg, arg);
578 return OIDC_CONFIG_DIR_RV(cmd, rv);
579 }
580
oidc_parse_pkce_type(apr_pool_t * pool,const char * arg,oidc_proto_pkce_t ** type)581 const char* oidc_parse_pkce_type(apr_pool_t *pool, const char *arg,
582 oidc_proto_pkce_t **type) {
583 const char *rv = oidc_valid_pkce_method(pool, arg);
584 if (rv != NULL)
585 return rv;
586
587 if (apr_strnatcmp(arg, OIDC_PKCE_METHOD_PLAIN) == 0) {
588 *type = &oidc_pkce_plain;
589 } else if (apr_strnatcmp(arg, OIDC_PKCE_METHOD_S256) == 0) {
590 *type = &oidc_pkce_s256;
591 } else if (apr_strnatcmp(arg, OIDC_PKCE_METHOD_REFERRED_TB) == 0) {
592 *type = &oidc_pkce_referred_tb;
593 }
594
595 return NULL;
596 }
597
598 /*
599 * define the PCKE method to use
600 */
oidc_set_pkce_method(cmd_parms * cmd,void * ptr,const char * arg)601 static const char* oidc_set_pkce_method(cmd_parms *cmd, void *ptr,
602 const char *arg) {
603 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
604 &auth_openidc_module);
605 const char *rv = oidc_parse_pkce_type(cmd->pool, arg, &cfg->provider.pkce);
606 return OIDC_CONFIG_DIR_RV(cmd, rv);
607 }
608
609 /*
610 * set the response mode used
611 */
oidc_set_response_mode(cmd_parms * cmd,void * struct_ptr,const char * arg)612 static const char* oidc_set_response_mode(cmd_parms *cmd, void *struct_ptr,
613 const char *arg) {
614 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
615 &auth_openidc_module);
616
617 const char *rv = oidc_valid_response_mode(cmd->pool, arg);
618 if (rv == NULL)
619 rv = ap_set_string_slot(cmd, cfg, arg);
620 return OIDC_CONFIG_DIR_RV(cmd, rv);
621 }
622
623 /*
624 * set the signing algorithm to be used by the OP (id_token/user_info)
625 */
oidc_set_signed_response_alg(cmd_parms * cmd,void * struct_ptr,const char * arg)626 static const char* oidc_set_signed_response_alg(cmd_parms *cmd,
627 void *struct_ptr, const char *arg) {
628 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
629 &auth_openidc_module);
630 const char *rv = oidc_valid_signed_response_alg(cmd->pool, arg);
631 if (rv == NULL)
632 rv = ap_set_string_slot(cmd, cfg, arg);
633 return OIDC_CONFIG_DIR_RV(cmd, rv);
634 }
635
636 /*
637 * set the Content Encryption Key encryption algorithm to be used by the OP (id_token/user_info)
638 */
oidc_set_encrypted_response_alg(cmd_parms * cmd,void * struct_ptr,const char * arg)639 static const char* oidc_set_encrypted_response_alg(cmd_parms *cmd,
640 void *struct_ptr, const char *arg) {
641 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
642 &auth_openidc_module);
643 const char *rv = oidc_valid_encrypted_response_alg(cmd->pool, arg);
644 if (rv == NULL)
645 rv = ap_set_string_slot(cmd, cfg, arg);
646 return OIDC_CONFIG_DIR_RV(cmd, rv);
647 }
648
649 /*
650 * set the content encryption algorithm to be used by the OP (id_token/user_info)
651 */
oidc_set_encrypted_response_enc(cmd_parms * cmd,void * struct_ptr,const char * arg)652 static const char* oidc_set_encrypted_response_enc(cmd_parms *cmd,
653 void *struct_ptr, const char *arg) {
654 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
655 &auth_openidc_module);
656 const char *rv = oidc_valid_encrypted_response_enc(cmd->pool, arg);
657 if (rv == NULL)
658 rv = ap_set_string_slot(cmd, cfg, arg);
659 return OIDC_CONFIG_DIR_RV(cmd, rv);
660 }
661
662 /*
663 * set the userinfo endpoint token presentation method
664 */
oidc_set_userinfo_token_method(cmd_parms * cmd,void * struct_ptr,const char * arg)665 static const char* oidc_set_userinfo_token_method(cmd_parms *cmd,
666 void *struct_ptr, const char *arg) {
667 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
668 &auth_openidc_module);
669 const char *rv = oidc_parse_userinfo_token_method(cmd->pool, arg,
670 &cfg->provider.userinfo_token_method);
671 return OIDC_CONFIG_DIR_RV(cmd, rv);
672 }
673
674 /*
675 * set the session inactivity timeout
676 */
oidc_set_session_inactivity_timeout(cmd_parms * cmd,void * struct_ptr,const char * arg)677 static const char* oidc_set_session_inactivity_timeout(cmd_parms *cmd,
678 void *struct_ptr, const char *arg) {
679 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
680 &auth_openidc_module);
681 const char *rv = oidc_parse_session_inactivity_timeout(cmd->pool, arg,
682 &cfg->session_inactivity_timeout);
683 return OIDC_CONFIG_DIR_RV(cmd, rv);
684 }
685
686 /*
687 * set the maximum session duration; 0 means take it from the ID token expiry time
688 */
oidc_set_session_max_duration(cmd_parms * cmd,void * struct_ptr,const char * arg)689 static const char* oidc_set_session_max_duration(cmd_parms *cmd,
690 void *struct_ptr, const char *arg) {
691 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
692 &auth_openidc_module);
693 const char *rv = oidc_parse_session_max_duration(cmd->pool, arg,
694 &cfg->provider.session_max_duration);
695 return OIDC_CONFIG_DIR_RV(cmd, rv);
696 }
697
oidc_cleanup_keys(void * data)698 static apr_status_t oidc_cleanup_keys(void *data) {
699 apr_array_header_t *keys_list = (apr_array_header_t*) data;
700 oidc_jwk_t **jwk = NULL;
701 while ((jwk = apr_array_pop(keys_list))) {
702 oidc_jwk_destroy(*jwk);
703 }
704 return APR_SUCCESS;
705 }
706
707 /*
708 * add a public key from an X.509 file to our list of JWKs with public keys
709 */
oidc_set_public_key_files(cmd_parms * cmd,void * struct_ptr,const char * arg)710 static const char* oidc_set_public_key_files(cmd_parms *cmd, void *struct_ptr,
711 const char *arg) {
712 oidc_jwk_t *jwk = NULL;
713 oidc_jose_error_t err;
714
715 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
716 &auth_openidc_module);
717
718 int offset = (int) (long) cmd->info;
719 apr_array_header_t **public_keys = (apr_array_header_t**) ((char*) cfg
720 + offset);
721
722 char *kid = NULL, *fname = NULL;
723 int fname_len;
724 const char *rv = oidc_parse_enc_kid_key_tuple(cmd->pool, arg, &kid, &fname,
725 &fname_len, FALSE);
726 if (rv != NULL)
727 return rv;
728
729 fname = oidc_util_get_full_path(cmd->pool, fname);
730
731 if (oidc_jwk_parse_rsa_public_key(cmd->pool, kid, fname, &jwk, &err)
732 == FALSE) {
733 return apr_psprintf(cmd->pool,
734 "oidc_jwk_parse_rsa_public_key failed for (kid=%s) \"%s\": %s",
735 kid, fname, oidc_jose_e2s(cmd->pool, err));
736 }
737
738 if (*public_keys == NULL) {
739 *public_keys = apr_array_make(cmd->pool, 4, sizeof(const oidc_jwk_t*));
740 apr_pool_cleanup_register(cmd->pool, *public_keys, oidc_cleanup_keys,
741 oidc_cleanup_keys);
742 }
743
744 *(const oidc_jwk_t**) apr_array_push(*public_keys) = jwk;
745
746 return NULL;
747 }
748
749 /*
750 * add a shared key to a list of JWKs with shared keys
751 */
oidc_set_shared_keys(cmd_parms * cmd,void * struct_ptr,const char * arg)752 static const char* oidc_set_shared_keys(cmd_parms *cmd, void *struct_ptr,
753 const char *arg) {
754 oidc_jose_error_t err;
755 oidc_jwk_t *jwk = NULL;
756
757 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
758 &auth_openidc_module);
759 int offset = (int) (long) cmd->info;
760 apr_hash_t **shared_keys = (apr_hash_t**) ((char*) cfg + offset);
761
762 char *kid = NULL, *secret = NULL;
763 int key_len = 0;
764 const char *rv = oidc_parse_enc_kid_key_tuple(cmd->pool, arg, &kid, &secret,
765 &key_len, TRUE);
766 if (rv != NULL)
767 return rv;
768
769 jwk = oidc_jwk_create_symmetric_key(cmd->pool, kid,
770 (const unsigned char*) secret, key_len, TRUE, &err);
771 if (jwk == NULL) {
772 return apr_psprintf(cmd->pool,
773 "oidc_jwk_create_symmetric_key failed for (kid=%s) \"%s\": %s",
774 kid, secret, oidc_jose_e2s(cmd->pool, err));
775 }
776
777 if (*shared_keys == NULL)
778 *shared_keys = apr_hash_make(cmd->pool);
779 apr_hash_set(*shared_keys, jwk->kid,
780 APR_HASH_KEY_STRING, jwk);
781
782 return NULL;
783 }
784
785 /*
786 * add a private key from an RSA private key file to our list of JWKs with private keys
787 */
oidc_set_private_key_files_enc(cmd_parms * cmd,void * dummy,const char * arg)788 static const char* oidc_set_private_key_files_enc(cmd_parms *cmd, void *dummy,
789 const char *arg) {
790 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
791 &auth_openidc_module);
792 oidc_jwk_t *jwk = NULL;
793 oidc_jose_error_t err;
794
795 char *kid = NULL, *fname = NULL;
796 int fname_len;
797 const char *rv = oidc_parse_enc_kid_key_tuple(cmd->pool, arg, &kid, &fname,
798 &fname_len, FALSE);
799 if (rv != NULL)
800 return rv;
801
802 fname = oidc_util_get_full_path(cmd->pool, fname);
803
804 if (oidc_jwk_parse_rsa_private_key(cmd->pool, kid, fname, &jwk, &err)
805 == FALSE) {
806 return apr_psprintf(cmd->pool,
807 "oidc_jwk_parse_rsa_private_key failed for (kid=%s) \"%s\": %s",
808 kid, fname, oidc_jose_e2s(cmd->pool, err));
809 }
810
811 if (cfg->private_keys == NULL) {
812 cfg->private_keys = apr_array_make(cmd->pool, 4,
813 sizeof(const oidc_jwk_t*));
814 apr_pool_cleanup_register(cmd->pool, cfg->private_keys,
815 oidc_cleanup_keys, oidc_cleanup_keys);
816 }
817
818 *(const oidc_jwk_t**) apr_array_push(cfg->private_keys) = jwk;
819
820 return NULL;
821 }
822
823 /*
824 * define how to pass the id_token/claims in HTTP headers
825 */
oidc_set_pass_idtoken_as(cmd_parms * cmd,void * dummy,const char * v1,const char * v2,const char * v3)826 static const char* oidc_set_pass_idtoken_as(cmd_parms *cmd, void *dummy,
827 const char *v1, const char *v2, const char *v3) {
828 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
829 &auth_openidc_module);
830 const char *rv = oidc_parse_pass_idtoken_as(cmd->pool, v1, v2, v3,
831 &cfg->pass_idtoken_as);
832 return OIDC_CONFIG_DIR_RV(cmd, rv);
833 }
834
835 /*
836 * define how to pass the userinfo/claims in HTTP headers
837 */
oidc_set_pass_userinfo_as(cmd_parms * cmd,void * dummy,const char * v1,const char * v2,const char * v3)838 static const char* oidc_set_pass_userinfo_as(cmd_parms *cmd, void *dummy,
839 const char *v1, const char *v2, const char *v3) {
840 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
841 &auth_openidc_module);
842 const char *rv = oidc_parse_pass_userinfo_as(cmd->pool, v1, v2, v3,
843 &cfg->pass_userinfo_as);
844 return OIDC_CONFIG_DIR_RV(cmd, rv);
845 }
846
847 /*
848 * define which method of pass an OAuth Bearer token is accepted
849 */
oidc_set_accept_oauth_token_in(cmd_parms * cmd,void * m,const char * arg)850 static const char* oidc_set_accept_oauth_token_in(cmd_parms *cmd, void *m,
851 const char *arg) {
852 oidc_dir_cfg *dir_cfg = (oidc_dir_cfg*) m;
853 const char *rv = oidc_parse_accept_oauth_token_in(cmd->pool, arg,
854 &dir_cfg->oauth_accept_token_in,
855 dir_cfg->oauth_accept_token_options);
856 return OIDC_CONFIG_DIR_RV(cmd, rv);
857 }
858
859 /*
860 * set the syntax of the token expiry claim in the introspection response
861 */
oidc_set_token_expiry_claim(cmd_parms * cmd,void * dummy,const char * claim_name,const char * claim_format,const char * claim_required)862 static const char* oidc_set_token_expiry_claim(cmd_parms *cmd, void *dummy,
863 const char *claim_name, const char *claim_format,
864 const char *claim_required) {
865 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
866 &auth_openidc_module);
867
868 const char *rv = NULL;
869
870 cfg->oauth.introspection_token_expiry_claim_name = apr_pstrdup(cmd->pool,
871 claim_name);
872
873 if ((rv == NULL) && (claim_format != NULL)) {
874 rv = oidc_valid_claim_format(cmd->pool, claim_format);
875 if (rv == NULL)
876 cfg->oauth.introspection_token_expiry_claim_format = apr_pstrdup(
877 cmd->pool, claim_format);
878 }
879
880 if ((rv == NULL) && (claim_required != NULL)) {
881 rv = oidc_parse_claim_required(cmd->pool, claim_required,
882 &cfg->oauth.introspection_token_expiry_claim_required);
883 }
884
885 return OIDC_CONFIG_DIR_RV(cmd, rv);
886 }
887
888 /*
889 * specify cookies names to pass/strip
890 */
oidc_set_cookie_names(cmd_parms * cmd,void * m,const char * arg)891 static const char* oidc_set_cookie_names(cmd_parms *cmd, void *m,
892 const char *arg) {
893 oidc_dir_cfg *dir_cfg = (oidc_dir_cfg*) m;
894 int offset = (int) (long) cmd->info;
895 apr_array_header_t **cookie_names = (apr_array_header_t**) ((char*) dir_cfg
896 + offset);
897 if (*cookie_names == NULL)
898 *cookie_names = apr_array_make(cmd->pool, 3, sizeof(const char*));
899 *(const char**) apr_array_push((*cookie_names)) = arg;
900 return NULL;
901 }
902
903 /*
904 * set the HTTP method to use in an OAuth 2.0 token introspection/validation call
905 */
oidc_set_introspection_method(cmd_parms * cmd,void * m,const char * arg)906 static const char* oidc_set_introspection_method(cmd_parms *cmd, void *m,
907 const char *arg) {
908 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
909 &auth_openidc_module);
910 const char *rv = oidc_valid_introspection_method(cmd->pool, arg);
911 if (rv == NULL)
912 rv = ap_set_string_slot(cmd, cfg, arg);
913 return OIDC_CONFIG_DIR_RV(cmd, rv);
914 }
915
916 /*
917 * set POST preservation behavior
918 */
oidc_set_preserve_post(cmd_parms * cmd,void * m,const char * arg)919 static const char* oidc_set_preserve_post(cmd_parms *cmd, void *m,
920 const char *arg) {
921 oidc_dir_cfg *dir_cfg = (oidc_dir_cfg*) m;
922 int b = 0;
923 const char *rv = oidc_parse_boolean(cmd->pool, arg, &b);
924 if (rv == NULL)
925 rv = ap_set_flag_slot(cmd, dir_cfg, b);
926 return OIDC_CONFIG_DIR_RV(cmd, rv);
927 }
928
929 /*
930 * set the remote user name claims, optionally plus the regular expression applied to it
931 */
oidc_set_remote_user_claim(cmd_parms * cmd,void * struct_ptr,const char * v1,const char * v2,const char * v3)932 static const char* oidc_set_remote_user_claim(cmd_parms *cmd, void *struct_ptr,
933 const char *v1, const char *v2, const char *v3) {
934 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
935 &auth_openidc_module);
936
937 int offset = (int) (long) cmd->info;
938 oidc_remote_user_claim_t *remote_user_claim =
939 (oidc_remote_user_claim_t*) ((char*) cfg + offset);
940
941 remote_user_claim->claim_name = v1;
942 if (v2)
943 remote_user_claim->reg_exp = v2;
944 if (v3)
945 remote_user_claim->replace = v3;
946
947 return NULL;
948 }
949
950 /*
951 * define how to pass claims information to the application: in headers and/or environment variables
952 */
oidc_set_pass_claims_as(cmd_parms * cmd,void * m,const char * arg1,const char * arg2)953 static const char* oidc_set_pass_claims_as(cmd_parms *cmd, void *m,
954 const char *arg1, const char *arg2) {
955 oidc_dir_cfg *dir_cfg = (oidc_dir_cfg*) m;
956 const char *rv = oidc_parse_set_claims_as(cmd->pool, arg1,
957 &dir_cfg->pass_info_in_headers, &dir_cfg->pass_info_in_env_vars);
958 if (rv == NULL) {
959 if (arg2 != NULL) {
960 if (apr_strnatcmp(arg2, "base64url") == 0) {
961 dir_cfg->pass_info_base64url = 1;
962 } else {
963 rv = apr_pstrcat(cmd->temp_pool, "unknown encoding option \"",
964 arg2, "\", only \"base64url\" is supported", NULL);
965 }
966 }
967 }
968 return OIDC_CONFIG_DIR_RV(cmd, rv);
969 }
970
971 /*
972 * define how to act on unauthenticated requests
973 */
oidc_set_unauth_action(cmd_parms * cmd,void * m,const char * arg1,const char * arg2)974 static const char* oidc_set_unauth_action(cmd_parms *cmd, void *m,
975 const char *arg1, const char *arg2) {
976 oidc_dir_cfg *dir_cfg = (oidc_dir_cfg*) m;
977 const char *rv = oidc_parse_unauth_action(cmd->pool, arg1,
978 &dir_cfg->unauth_action);
979 #if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
980 const char *expr_err = NULL;
981 if ((rv == NULL) && (arg2 != NULL)) {
982 dir_cfg->unauth_expression = ap_expr_parse_cmd(cmd, arg2,
983 AP_EXPR_FLAG_DONT_VARY & AP_EXPR_FLAG_RESTRICTED, &expr_err,
984 NULL);
985 if (expr_err != NULL) {
986 rv = apr_pstrcat(cmd->temp_pool, "cannot parse expression: ",
987 expr_err, NULL);
988 }
989 }
990 #endif
991 return OIDC_CONFIG_DIR_RV(cmd, rv);
992 }
993
994 /*
995 * define how to act on unauthorized requests
996 */
oidc_set_unautz_action(cmd_parms * cmd,void * m,const char * arg)997 static const char* oidc_set_unautz_action(cmd_parms *cmd, void *m,
998 const char *arg) {
999 oidc_dir_cfg *dir_cfg = (oidc_dir_cfg*) m;
1000 const char *rv = oidc_parse_unautz_action(cmd->pool, arg,
1001 &dir_cfg->unautz_action);
1002 return OIDC_CONFIG_DIR_RV(cmd, rv);
1003 }
1004
1005 /*
1006 * set the JWKS refresh interval
1007 */
oidc_set_jwks_refresh_interval(cmd_parms * cmd,void * struct_ptr,const char * arg)1008 static const char* oidc_set_jwks_refresh_interval(cmd_parms *cmd,
1009 void *struct_ptr, const char *arg) {
1010 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1011 &auth_openidc_module);
1012 const char *rv = oidc_parse_jwks_refresh_interval(cmd->pool, arg,
1013 &cfg->provider.jwks_refresh_interval);
1014 return OIDC_CONFIG_DIR_RV(cmd, rv);
1015 }
1016
1017 /*
1018 * set the ID token "iat" slack
1019 */
oidc_set_idtoken_iat_slack(cmd_parms * cmd,void * struct_ptr,const char * arg)1020 static const char* oidc_set_idtoken_iat_slack(cmd_parms *cmd, void *struct_ptr,
1021 const char *arg) {
1022 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1023 &auth_openidc_module);
1024 const char *rv = oidc_parse_idtoken_iat_slack(cmd->pool, arg,
1025 &cfg->provider.idtoken_iat_slack);
1026 return OIDC_CONFIG_DIR_RV(cmd, rv);
1027 }
1028
1029 /*
1030 * set the userinfo refresh interval
1031 */
oidc_set_userinfo_refresh_interval(cmd_parms * cmd,void * struct_ptr,const char * arg)1032 static const char* oidc_set_userinfo_refresh_interval(cmd_parms *cmd,
1033 void *struct_ptr, const char *arg) {
1034 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1035 &auth_openidc_module);
1036 const char *rv = oidc_parse_userinfo_refresh_interval(cmd->pool, arg,
1037 &cfg->provider.userinfo_refresh_interval);
1038 return OIDC_CONFIG_DIR_RV(cmd, rv);
1039 }
1040
1041 /*
1042 * define which data will be returned from the info hook
1043 */
oidc_set_info_hook_data(cmd_parms * cmd,void * m,const char * arg)1044 static const char* oidc_set_info_hook_data(cmd_parms *cmd, void *m,
1045 const char *arg) {
1046 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1047 &auth_openidc_module);
1048 const char *rv = oidc_parse_info_hook_data(cmd->pool, arg,
1049 &cfg->info_hook_data);
1050 return OIDC_CONFIG_DIR_RV(cmd, rv);
1051 }
1052
oidc_set_filtered_claims(cmd_parms * cmd,void * m,const char * arg)1053 static const char* oidc_set_filtered_claims(cmd_parms *cmd, void *m,
1054 const char *arg) {
1055 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1056 &auth_openidc_module);
1057 int offset = (int) (long) cmd->info;
1058 apr_hash_t **list = (apr_hash_t**) ((char*) cfg + offset);
1059 if (*list == NULL)
1060 *list = apr_hash_make(cmd->pool);
1061 apr_hash_set(*list, arg, APR_HASH_KEY_STRING, arg);
1062 return NULL;
1063 }
1064
1065 /*
1066 * set the token binding policy
1067 */
oidc_set_token_binding_policy(cmd_parms * cmd,void * struct_ptr,const char * arg)1068 static const char* oidc_set_token_binding_policy(cmd_parms *cmd,
1069 void *struct_ptr, const char *arg) {
1070 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1071 &auth_openidc_module);
1072 int offset = (int) (long) cmd->info;
1073 int *token_binding_policy = (int*) ((char*) cfg + offset);
1074 const char *rv = oidc_parse_token_binding_policy(cmd->pool, arg,
1075 token_binding_policy);
1076 return OIDC_CONFIG_DIR_RV(cmd, rv);
1077 }
1078
1079 /*
1080 * set the claim prefix
1081 */
oidc_cfg_set_claim_prefix(cmd_parms * cmd,void * struct_ptr,const char * args)1082 static const char* oidc_cfg_set_claim_prefix(cmd_parms *cmd, void *struct_ptr,
1083 const char *args) {
1084 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1085 &auth_openidc_module);
1086 char *w = ap_getword_conf(cmd->pool, &args);
1087 if (*w == '\0' || *args != 0)
1088 cfg->claim_prefix = "";
1089 else
1090 cfg->claim_prefix = w;
1091 return NULL;
1092 }
1093
1094 /*
1095 * get the claim prefix
1096 */
oidc_cfg_claim_prefix(request_rec * r)1097 const char* oidc_cfg_claim_prefix(request_rec *r) {
1098 oidc_cfg *cfg = ap_get_module_config(r->server->module_config,
1099 &auth_openidc_module);
1100 if (cfg->claim_prefix == NULL)
1101 return OIDC_DEFAULT_CLAIM_PREFIX;
1102 return cfg->claim_prefix;
1103 }
1104
1105 /*
1106 * set the HTTP method used to send the authentication request to the provider
1107 */
oidc_set_auth_request_method(cmd_parms * cmd,void * struct_ptr,const char * arg)1108 const char* oidc_set_auth_request_method(cmd_parms *cmd, void *struct_ptr,
1109 const char *arg) {
1110 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1111 &auth_openidc_module);
1112 const char *rv = oidc_parse_auth_request_method(cmd->pool, arg,
1113 &cfg->provider.auth_request_method);
1114 return OIDC_CONFIG_DIR_RV(cmd, rv);
1115 }
1116
1117 /*
1118 * set the introspection authorization static bearer token
1119 */
oidc_set_client_auth_bearer_token(cmd_parms * cmd,void * struct_ptr,const char * args)1120 static const char* oidc_set_client_auth_bearer_token(cmd_parms *cmd,
1121 void *struct_ptr, const char *args) {
1122 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1123 &auth_openidc_module);
1124 char *w = ap_getword_conf(cmd->pool, &args);
1125 cfg->oauth.introspection_client_auth_bearer_token =
1126 (*w == '\0' || *args != 0) ? "" : w;
1127 return NULL;
1128 }
1129
1130 /*
1131 * set the maximum number of parallel state cookies
1132 */
oidc_set_max_number_of_state_cookies(cmd_parms * cmd,void * struct_ptr,const char * arg1,const char * arg2)1133 static const char* oidc_set_max_number_of_state_cookies(cmd_parms *cmd,
1134 void *struct_ptr, const char *arg1, const char *arg2) {
1135 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1136 &auth_openidc_module);
1137 const char *rv = oidc_parse_max_number_of_state_cookies(cmd->pool, arg1,
1138 arg2, &cfg->max_number_of_state_cookies,
1139 &cfg->delete_oldest_state_cookies);
1140 return OIDC_CONFIG_DIR_RV(cmd, rv);
1141 }
1142
1143 /*
1144 * return the maximum number of parallel state cookies
1145 */
oidc_cfg_max_number_of_state_cookies(oidc_cfg * cfg)1146 int oidc_cfg_max_number_of_state_cookies(oidc_cfg *cfg) {
1147 if (cfg->max_number_of_state_cookies == OIDC_CONFIG_POS_INT_UNSET)
1148 return OIDC_DEFAULT_MAX_NUMBER_OF_STATE_COOKIES;
1149 return cfg->max_number_of_state_cookies;
1150 }
1151
1152 /*
1153 * return the number of oldest state cookies that need to be deleted
1154 */
oidc_cfg_delete_oldest_state_cookies(oidc_cfg * cfg)1155 int oidc_cfg_delete_oldest_state_cookies(oidc_cfg *cfg) {
1156 if (cfg->delete_oldest_state_cookies == OIDC_CONFIG_POS_INT_UNSET)
1157 return OIDC_DEFAULT_DELETE_OLDEST_STATE_COOKIES;
1158 return cfg->delete_oldest_state_cookies;
1159 }
1160
1161 /*
1162 * set the time in seconds that the access token needs to be valid for
1163 */
oidc_set_refresh_access_token_before_expiry(cmd_parms * cmd,void * m,const char * arg1,const char * arg2)1164 static const char* oidc_set_refresh_access_token_before_expiry(cmd_parms *cmd,
1165 void *m, const char *arg1, const char *arg2) {
1166 oidc_dir_cfg *dir_cfg = (oidc_dir_cfg*) m;
1167 const char *rv1 = oidc_parse_refresh_access_token_before_expiry(cmd->pool,
1168 arg1, &dir_cfg->refresh_access_token_before_expiry);
1169 if (rv1 != NULL)
1170 return apr_psprintf(cmd->pool, "Invalid value for directive '%s': %s",
1171 cmd->directive->directive, rv1);
1172
1173 if (arg2) {
1174 const char *rv2 = oidc_parse_logout_on_error_refresh_as(cmd->pool, arg2,
1175 &dir_cfg->logout_on_error_refresh);
1176 return OIDC_CONFIG_DIR_RV(cmd, rv2);
1177 }
1178
1179 return NULL;
1180 }
1181
1182 /*
1183 * define which header we use for calculating the fingerprint of the state during authentication
1184 */
oidc_set_state_input_headers_as(cmd_parms * cmd,void * m,const char * arg)1185 static const char* oidc_set_state_input_headers_as(cmd_parms *cmd, void *m,
1186 const char *arg) {
1187 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1188 &auth_openidc_module);
1189 const char *rv = oidc_parse_set_state_input_headers_as(cmd->pool, arg,
1190 &cfg->state_input_headers);
1191 return OIDC_CONFIG_DIR_RV(cmd, rv);
1192 }
1193
oidc_set_redirect_urls_allowed(cmd_parms * cmd,void * m,const char * arg)1194 static const char* oidc_set_redirect_urls_allowed(cmd_parms *cmd, void *m,
1195 const char *arg) {
1196 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(cmd->server->module_config,
1197 &auth_openidc_module);
1198 if (cfg->redirect_urls_allowed == NULL)
1199 cfg->redirect_urls_allowed = apr_hash_make(cmd->pool);
1200 apr_hash_set(cfg->redirect_urls_allowed, arg, APR_HASH_KEY_STRING, arg);
1201 return NULL;
1202 }
1203
oidc_cfg_dir_refresh_access_token_before_expiry(request_rec * r)1204 int oidc_cfg_dir_refresh_access_token_before_expiry(request_rec *r) {
1205 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
1206 &auth_openidc_module);
1207 if (dir_cfg->refresh_access_token_before_expiry == OIDC_CONFIG_POS_INT_UNSET)
1208 return OIDC_DEFAULT_REFRESH_ACCESS_TOKEN_BEFORE_EXPIRY;
1209 return dir_cfg->refresh_access_token_before_expiry;
1210 }
1211
oidc_cfg_dir_logout_on_error_refresh(request_rec * r)1212 int oidc_cfg_dir_logout_on_error_refresh(request_rec *r) {
1213 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
1214 &auth_openidc_module);
1215 if (dir_cfg->logout_on_error_refresh == OIDC_CONFIG_POS_INT_UNSET)
1216 return 0; // no mask
1217 return dir_cfg->logout_on_error_refresh;
1218 }
1219
oidc_cfg_dir_state_cookie_prefix(request_rec * r)1220 char* oidc_cfg_dir_state_cookie_prefix(request_rec *r) {
1221 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
1222 &auth_openidc_module);
1223 if ((dir_cfg->state_cookie_prefix == NULL)
1224 || ((dir_cfg->state_cookie_prefix != NULL)
1225 && (apr_strnatcmp(dir_cfg->state_cookie_prefix,
1226 OIDC_CONFIG_STRING_UNSET) == 0)))
1227 return OIDC_DEFAULT_STATE_COOKIE_PREFIX;
1228 return dir_cfg->state_cookie_prefix;
1229 }
1230
oidc_cfg_provider_init(oidc_provider_t * provider)1231 void oidc_cfg_provider_init(oidc_provider_t *provider) {
1232 provider->metadata_url = NULL;
1233 provider->issuer = NULL;
1234 provider->authorization_endpoint_url = NULL;
1235 provider->token_endpoint_url = NULL;
1236 provider->token_endpoint_auth = NULL;
1237 provider->token_endpoint_params = NULL;
1238 provider->userinfo_endpoint_url = NULL;
1239 provider->revocation_endpoint_url = NULL;
1240 provider->client_id = NULL;
1241 provider->client_secret = NULL;
1242 provider->token_endpoint_tls_client_cert = NULL;
1243 provider->token_endpoint_tls_client_key = NULL;
1244 provider->registration_endpoint_url = NULL;
1245 provider->registration_endpoint_json = NULL;
1246 provider->check_session_iframe = NULL;
1247 provider->end_session_endpoint = NULL;
1248 provider->jwks_uri = NULL;
1249 provider->backchannel_logout_supported = OIDC_CONFIG_POS_INT_UNSET;
1250
1251 provider->ssl_validate_server = OIDC_DEFAULT_SSL_VALIDATE_SERVER;
1252 provider->validate_issuer = OIDC_DEFAULT_VALIDATE_ISSUER;
1253 provider->client_name = OIDC_DEFAULT_CLIENT_NAME;
1254 provider->client_contact = NULL;
1255 provider->registration_token = NULL;
1256 provider->scope = OIDC_DEFAULT_SCOPE;
1257 provider->response_type = OIDC_DEFAULT_RESPONSE_TYPE;
1258 provider->response_mode = NULL;
1259 provider->jwks_refresh_interval = OIDC_DEFAULT_JWKS_REFRESH_INTERVAL;
1260 provider->idtoken_iat_slack = OIDC_DEFAULT_IDTOKEN_IAT_SLACK;
1261 provider->session_max_duration = OIDC_DEFAULT_SESSION_MAX_DURATION;
1262 provider->auth_request_params = NULL;
1263 provider->pkce = NULL;
1264
1265 provider->client_jwks_uri = NULL;
1266 provider->client_signing_keys = NULL;
1267 provider->client_encryption_keys = NULL;
1268
1269 provider->id_token_signed_response_alg = NULL;
1270 provider->id_token_encrypted_response_alg = NULL;
1271 provider->id_token_encrypted_response_enc = NULL;
1272 provider->userinfo_signed_response_alg = NULL;
1273 provider->userinfo_encrypted_response_alg = NULL;
1274 provider->userinfo_encrypted_response_enc = NULL;
1275 provider->userinfo_token_method = OIDC_USER_INFO_TOKEN_METHOD_HEADER;
1276 provider->auth_request_method = OIDC_DEFAULT_AUTH_REQUEST_METHOD;
1277 }
1278
1279 /*
1280 * create a new server config record with defaults
1281 */
oidc_create_server_config(apr_pool_t * pool,server_rec * svr)1282 void* oidc_create_server_config(apr_pool_t *pool, server_rec *svr) {
1283 oidc_cfg *c = apr_pcalloc(pool, sizeof(oidc_cfg));
1284
1285 c->merged = FALSE;
1286
1287 c->redirect_uri = NULL;
1288 c->default_sso_url = NULL;
1289 c->default_slo_url = NULL;
1290 c->public_keys = NULL;
1291 c->private_keys = NULL;
1292
1293 oidc_cfg_provider_init(&c->provider);
1294
1295 c->oauth.ssl_validate_server = OIDC_DEFAULT_SSL_VALIDATE_SERVER;
1296 c->oauth.metadata_url = NULL;
1297 c->oauth.client_id = NULL;
1298 c->oauth.client_secret = NULL;
1299 c->oauth.introspection_endpoint_tls_client_cert = NULL;
1300 c->oauth.introspection_endpoint_tls_client_key = NULL;
1301 c->oauth.introspection_endpoint_url = NULL;
1302 c->oauth.introspection_endpoint_method = OIDC_DEFAULT_OAUTH_ENDPOINT_METHOD;
1303 c->oauth.introspection_endpoint_params = NULL;
1304 c->oauth.introspection_endpoint_auth = NULL;
1305 c->oauth.introspection_client_auth_bearer_token = NULL;
1306 c->oauth.introspection_token_param_name =
1307 OIDC_DEFAULT_OAUTH_TOKEN_PARAM_NAME;
1308
1309 c->oauth.introspection_token_expiry_claim_name =
1310 OIDC_DEFAULT_OAUTH_EXPIRY_CLAIM_NAME;
1311 c->oauth.introspection_token_expiry_claim_format =
1312 OIDC_DEFAULT_OAUTH_EXPIRY_CLAIM_FORMAT;
1313 c->oauth.introspection_token_expiry_claim_required =
1314 OIDC_DEFAULT_OAUTH_EXPIRY_CLAIM_REQUIRED;
1315
1316 c->oauth.remote_user_claim.claim_name =
1317 OIDC_DEFAULT_OAUTH_CLAIM_REMOTE_USER;
1318 c->oauth.remote_user_claim.reg_exp = NULL;
1319 c->oauth.remote_user_claim.replace = NULL;
1320
1321 c->oauth.verify_jwks_uri = NULL;
1322 c->oauth.verify_public_keys = NULL;
1323 c->oauth.verify_shared_keys = NULL;
1324
1325 c->oauth.access_token_binding_policy =
1326 OIDC_DEFAULT_OAUTH_ACCESS_TOKEN_BINDING_POLICY;
1327
1328 c->cache = &oidc_cache_shm;
1329 c->cache_cfg = NULL;
1330 c->cache_encrypt = OIDC_CONFIG_POS_INT_UNSET;
1331
1332 c->cache_file_dir = NULL;
1333 c->cache_file_clean_interval = OIDC_DEFAULT_CACHE_FILE_CLEAN_INTERVAL;
1334 #ifdef USE_MEMCACHE
1335 c->cache_memcache_servers = NULL;
1336 #endif
1337 c->cache_shm_size_max = OIDC_DEFAULT_CACHE_SHM_SIZE;
1338 c->cache_shm_entry_size_max = OIDC_DEFAULT_CACHE_SHM_ENTRY_SIZE_MAX;
1339 #ifdef USE_LIBHIREDIS
1340 c->cache_redis_server = NULL;
1341 c->cache_redis_password = NULL;
1342 c->cache_redis_database = -1;
1343 #endif
1344
1345 c->metadata_dir = NULL;
1346 c->session_type = OIDC_DEFAULT_SESSION_TYPE;
1347 c->session_cache_fallback_to_cookie = OIDC_CONFIG_POS_INT_UNSET;
1348 c->persistent_session_cookie = 0;
1349 c->session_cookie_chunk_size =
1350 OIDC_DEFAULT_SESSION_CLIENT_COOKIE_CHUNK_SIZE;
1351
1352 c->http_timeout_long = OIDC_DEFAULT_HTTP_TIMEOUT_LONG;
1353 c->http_timeout_short = OIDC_DEFAULT_HTTP_TIMEOUT_SHORT;
1354 c->state_timeout = OIDC_DEFAULT_STATE_TIMEOUT;
1355 c->max_number_of_state_cookies = OIDC_CONFIG_POS_INT_UNSET;
1356 c->delete_oldest_state_cookies = OIDC_CONFIG_POS_INT_UNSET;
1357 c->session_inactivity_timeout = OIDC_DEFAULT_SESSION_INACTIVITY_TIMEOUT;
1358
1359 c->cookie_domain = NULL;
1360 c->claim_delimiter = OIDC_DEFAULT_CLAIM_DELIMITER;
1361 c->claim_prefix = NULL;
1362 c->remote_user_claim.claim_name = OIDC_DEFAULT_CLAIM_REMOTE_USER;
1363 c->remote_user_claim.reg_exp = NULL;
1364 c->remote_user_claim.replace = NULL;
1365 c->pass_idtoken_as = OIDC_PASS_IDTOKEN_AS_CLAIMS;
1366 c->pass_userinfo_as = OIDC_PASS_USERINFO_AS_CLAIMS;
1367 c->cookie_http_only = OIDC_DEFAULT_COOKIE_HTTPONLY;
1368 c->cookie_same_site = OIDC_DEFAULT_COOKIE_SAME_SITE;
1369
1370 c->outgoing_proxy = NULL;
1371 c->crypto_passphrase = NULL;
1372
1373 c->error_template = NULL;
1374
1375 c->provider.userinfo_refresh_interval =
1376 OIDC_DEFAULT_USERINFO_REFRESH_INTERVAL;
1377 c->provider.request_object = NULL;
1378
1379 c->provider_metadata_refresh_interval =
1380 OIDC_DEFAULT_PROVIDER_METADATA_REFRESH_INTERVAL;
1381
1382 c->provider.token_binding_policy =
1383 OIDC_DEFAULT_PROVIDER_TOKEN_BINDING_POLICY;
1384
1385 c->info_hook_data = NULL;
1386 c->black_listed_claims = NULL;
1387 c->white_listed_claims = NULL;
1388
1389 c->provider.issuer_specific_redirect_uri =
1390 OIDC_DEFAULT_PROVIDER_ISSUER_SPECIFIC_REDIRECT_URI;
1391
1392 c->state_input_headers = OIDC_DEFAULT_STATE_INPUT_HEADERS;
1393
1394 c->redirect_urls_allowed = NULL;
1395
1396 c->ca_bundle_path = NULL;
1397
1398 return c;
1399 }
1400
1401 /*
1402 * merge a new server config with a base one
1403 */
oidc_merge_server_config(apr_pool_t * pool,void * BASE,void * ADD)1404 void* oidc_merge_server_config(apr_pool_t *pool, void *BASE, void *ADD) {
1405 oidc_cfg *c = apr_pcalloc(pool, sizeof(oidc_cfg));
1406 oidc_cfg *base = BASE;
1407 oidc_cfg *add = ADD;
1408
1409 c->merged = TRUE;
1410
1411 c->redirect_uri =
1412 add->redirect_uri != NULL ? add->redirect_uri : base->redirect_uri;
1413 c->default_sso_url =
1414 add->default_sso_url != NULL ?
1415 add->default_sso_url : base->default_sso_url;
1416 c->default_slo_url =
1417 add->default_slo_url != NULL ?
1418 add->default_slo_url : base->default_slo_url;
1419 c->public_keys =
1420 add->public_keys != NULL ? add->public_keys : base->public_keys;
1421 c->private_keys =
1422 add->private_keys != NULL ? add->private_keys : base->private_keys;
1423
1424 c->provider.metadata_url =
1425 add->provider.metadata_url != NULL ?
1426 add->provider.metadata_url : base->provider.metadata_url;
1427 c->provider.issuer =
1428 add->provider.issuer != NULL ?
1429 add->provider.issuer : base->provider.issuer;
1430 c->provider.authorization_endpoint_url =
1431 add->provider.authorization_endpoint_url != NULL ?
1432 add->provider.authorization_endpoint_url :
1433 base->provider.authorization_endpoint_url;
1434 c->provider.token_endpoint_url =
1435 add->provider.token_endpoint_url != NULL ?
1436 add->provider.token_endpoint_url :
1437 base->provider.token_endpoint_url;
1438 c->provider.token_endpoint_auth =
1439 add->provider.token_endpoint_auth != NULL ?
1440 add->provider.token_endpoint_auth :
1441 base->provider.token_endpoint_auth;
1442 c->provider.token_endpoint_params =
1443 add->provider.token_endpoint_params != NULL ?
1444 add->provider.token_endpoint_params :
1445 base->provider.token_endpoint_params;
1446 c->provider.userinfo_endpoint_url =
1447 add->provider.userinfo_endpoint_url != NULL ?
1448 add->provider.userinfo_endpoint_url :
1449 base->provider.userinfo_endpoint_url;
1450 c->provider.revocation_endpoint_url =
1451 add->provider.revocation_endpoint_url != NULL ?
1452 add->provider.revocation_endpoint_url :
1453 base->provider.revocation_endpoint_url;
1454 c->provider.jwks_uri =
1455 add->provider.jwks_uri != NULL ?
1456 add->provider.jwks_uri : base->provider.jwks_uri;
1457 c->provider.client_id =
1458 add->provider.client_id != NULL ?
1459 add->provider.client_id : base->provider.client_id;
1460 c->provider.client_secret =
1461 add->provider.client_secret != NULL ?
1462 add->provider.client_secret : base->provider.client_secret;
1463
1464 c->provider.token_endpoint_tls_client_key =
1465 add->provider.token_endpoint_tls_client_key != NULL ?
1466 add->provider.token_endpoint_tls_client_key :
1467 base->provider.token_endpoint_tls_client_key;
1468 c->provider.token_endpoint_tls_client_cert =
1469 add->provider.token_endpoint_tls_client_cert != NULL ?
1470 add->provider.token_endpoint_tls_client_cert :
1471 base->provider.token_endpoint_tls_client_cert;
1472
1473 c->provider.registration_endpoint_url =
1474 add->provider.registration_endpoint_url != NULL ?
1475 add->provider.registration_endpoint_url :
1476 base->provider.registration_endpoint_url;
1477 c->provider.registration_endpoint_json =
1478 add->provider.registration_endpoint_json != NULL ?
1479 add->provider.registration_endpoint_json :
1480 base->provider.registration_endpoint_json;
1481
1482 c->provider.check_session_iframe =
1483 add->provider.check_session_iframe != NULL ?
1484 add->provider.check_session_iframe :
1485 base->provider.check_session_iframe;
1486 c->provider.end_session_endpoint =
1487 add->provider.end_session_endpoint != NULL ?
1488 add->provider.end_session_endpoint :
1489 base->provider.end_session_endpoint;
1490 c->provider.backchannel_logout_supported =
1491 add->provider.backchannel_logout_supported
1492 != OIDC_CONFIG_POS_INT_UNSET ?
1493 add->provider.backchannel_logout_supported :
1494 base->provider.backchannel_logout_supported;
1495
1496 c->provider.ssl_validate_server =
1497 add->provider.ssl_validate_server
1498 != OIDC_DEFAULT_SSL_VALIDATE_SERVER ?
1499 add->provider.ssl_validate_server :
1500 base->provider.ssl_validate_server;
1501 c->provider.validate_issuer =
1502 add->provider.validate_issuer != OIDC_DEFAULT_VALIDATE_ISSUER ?
1503 add->provider.validate_issuer :
1504 base->provider.validate_issuer;
1505 c->provider.client_name =
1506 apr_strnatcmp(add->provider.client_name, OIDC_DEFAULT_CLIENT_NAME)
1507 != 0 ?
1508 add->provider.client_name : base->provider.client_name;
1509 c->provider.client_contact =
1510 add->provider.client_contact != NULL ?
1511 add->provider.client_contact :
1512 base->provider.client_contact;
1513 c->provider.registration_token =
1514 add->provider.registration_token != NULL ?
1515 add->provider.registration_token :
1516 base->provider.registration_token;
1517 c->provider.scope =
1518 apr_strnatcmp(add->provider.scope, OIDC_DEFAULT_SCOPE) != 0 ?
1519 add->provider.scope : base->provider.scope;
1520 c->provider.response_type =
1521 apr_strnatcmp(add->provider.response_type,
1522 OIDC_DEFAULT_RESPONSE_TYPE) != 0 ?
1523 add->provider.response_type : base->provider.response_type;
1524 c->provider.response_mode =
1525 add->provider.response_mode != NULL ?
1526 add->provider.response_mode : base->provider.response_mode;
1527 c->provider.jwks_refresh_interval =
1528 add->provider.jwks_refresh_interval
1529 != OIDC_DEFAULT_JWKS_REFRESH_INTERVAL ?
1530 add->provider.jwks_refresh_interval :
1531 base->provider.jwks_refresh_interval;
1532 c->provider.idtoken_iat_slack =
1533 add->provider.idtoken_iat_slack != OIDC_DEFAULT_IDTOKEN_IAT_SLACK ?
1534 add->provider.idtoken_iat_slack :
1535 base->provider.idtoken_iat_slack;
1536 c->provider.session_max_duration =
1537 add->provider.session_max_duration
1538 != OIDC_DEFAULT_SESSION_MAX_DURATION ?
1539 add->provider.session_max_duration :
1540 base->provider.session_max_duration;
1541 c->provider.auth_request_params =
1542 add->provider.auth_request_params != NULL ?
1543 add->provider.auth_request_params :
1544 base->provider.auth_request_params;
1545 c->provider.pkce =
1546 add->provider.pkce != NULL ?
1547 add->provider.pkce : base->provider.pkce;
1548
1549 c->provider.client_jwks_uri =
1550 add->provider.client_jwks_uri != NULL ?
1551 add->provider.client_jwks_uri :
1552 base->provider.client_jwks_uri;
1553 c->provider.client_signing_keys =
1554 add->provider.client_signing_keys != NULL ?
1555 add->provider.client_signing_keys :
1556 base->provider.client_signing_keys;
1557 c->provider.client_encryption_keys =
1558 add->provider.client_encryption_keys != NULL ?
1559 add->provider.client_encryption_keys :
1560 base->provider.client_encryption_keys;
1561
1562 c->provider.id_token_signed_response_alg =
1563 add->provider.id_token_signed_response_alg != NULL ?
1564 add->provider.id_token_signed_response_alg :
1565 base->provider.id_token_signed_response_alg;
1566 c->provider.id_token_encrypted_response_alg =
1567 add->provider.id_token_encrypted_response_alg != NULL ?
1568 add->provider.id_token_encrypted_response_alg :
1569 base->provider.id_token_encrypted_response_alg;
1570 c->provider.id_token_encrypted_response_enc =
1571 add->provider.id_token_encrypted_response_enc != NULL ?
1572 add->provider.id_token_encrypted_response_enc :
1573 base->provider.id_token_encrypted_response_enc;
1574 c->provider.userinfo_signed_response_alg =
1575 add->provider.userinfo_signed_response_alg != NULL ?
1576 add->provider.userinfo_signed_response_alg :
1577 base->provider.userinfo_signed_response_alg;
1578 c->provider.userinfo_encrypted_response_alg =
1579 add->provider.userinfo_encrypted_response_alg != NULL ?
1580 add->provider.userinfo_encrypted_response_alg :
1581 base->provider.userinfo_encrypted_response_alg;
1582 c->provider.userinfo_encrypted_response_enc =
1583 add->provider.userinfo_encrypted_response_enc != NULL ?
1584 add->provider.userinfo_encrypted_response_enc :
1585 base->provider.userinfo_encrypted_response_enc;
1586 c->provider.userinfo_token_method =
1587 add->provider.userinfo_token_method
1588 != OIDC_USER_INFO_TOKEN_METHOD_HEADER ?
1589 add->provider.userinfo_token_method :
1590 base->provider.userinfo_token_method;
1591 c->provider.auth_request_method =
1592 add->provider.auth_request_method
1593 != OIDC_DEFAULT_AUTH_REQUEST_METHOD ?
1594 add->provider.auth_request_method :
1595 base->provider.auth_request_method;
1596
1597 c->oauth.ssl_validate_server =
1598 add->oauth.ssl_validate_server != OIDC_DEFAULT_SSL_VALIDATE_SERVER ?
1599 add->oauth.ssl_validate_server :
1600 base->oauth.ssl_validate_server;
1601 c->oauth.metadata_url =
1602 add->oauth.metadata_url != NULL ?
1603 add->oauth.metadata_url : base->oauth.metadata_url;
1604 c->oauth.client_id =
1605 add->oauth.client_id != NULL ?
1606 add->oauth.client_id : base->oauth.client_id;
1607 c->oauth.client_secret =
1608 add->oauth.client_secret != NULL ?
1609 add->oauth.client_secret : base->oauth.client_secret;
1610
1611 c->oauth.introspection_endpoint_tls_client_key =
1612 add->oauth.introspection_endpoint_tls_client_key != NULL ?
1613 add->oauth.introspection_endpoint_tls_client_key :
1614 base->oauth.introspection_endpoint_tls_client_key;
1615 c->oauth.introspection_endpoint_tls_client_cert =
1616 add->oauth.introspection_endpoint_tls_client_cert != NULL ?
1617 add->oauth.introspection_endpoint_tls_client_cert :
1618 base->oauth.introspection_endpoint_tls_client_cert;
1619
1620 c->oauth.introspection_endpoint_url =
1621 add->oauth.introspection_endpoint_url != NULL ?
1622 add->oauth.introspection_endpoint_url :
1623 base->oauth.introspection_endpoint_url;
1624 c->oauth.introspection_endpoint_method =
1625 apr_strnatcmp(add->oauth.introspection_endpoint_method,
1626 OIDC_DEFAULT_OAUTH_ENDPOINT_METHOD) != 0 ?
1627 add->oauth.introspection_endpoint_method :
1628 base->oauth.introspection_endpoint_method;
1629 c->oauth.introspection_endpoint_params =
1630 add->oauth.introspection_endpoint_params != NULL ?
1631 add->oauth.introspection_endpoint_params :
1632 base->oauth.introspection_endpoint_params;
1633 c->oauth.introspection_endpoint_auth =
1634 add->oauth.introspection_endpoint_auth != NULL ?
1635 add->oauth.introspection_endpoint_auth :
1636 base->oauth.introspection_endpoint_auth;
1637 c->oauth.introspection_client_auth_bearer_token =
1638 add->oauth.introspection_client_auth_bearer_token != NULL ?
1639 add->oauth.introspection_client_auth_bearer_token :
1640 base->oauth.introspection_client_auth_bearer_token;
1641 c->oauth.introspection_token_param_name =
1642 apr_strnatcmp(add->oauth.introspection_token_param_name,
1643 OIDC_DEFAULT_OAUTH_TOKEN_PARAM_NAME) != 0 ?
1644 add->oauth.introspection_token_param_name :
1645 base->oauth.introspection_token_param_name;
1646
1647 c->oauth.introspection_token_expiry_claim_name =
1648 apr_strnatcmp(add->oauth.introspection_token_expiry_claim_name,
1649 OIDC_DEFAULT_OAUTH_EXPIRY_CLAIM_NAME) != 0 ?
1650 add->oauth.introspection_token_expiry_claim_name :
1651 base->oauth.introspection_token_expiry_claim_name;
1652 c->oauth.introspection_token_expiry_claim_format =
1653 apr_strnatcmp(add->oauth.introspection_token_expiry_claim_format,
1654 OIDC_DEFAULT_OAUTH_EXPIRY_CLAIM_FORMAT) != 0 ?
1655 add->oauth.introspection_token_expiry_claim_format :
1656 base->oauth.introspection_token_expiry_claim_format;
1657 c->oauth.introspection_token_expiry_claim_required =
1658 add->oauth.introspection_token_expiry_claim_required
1659 != OIDC_DEFAULT_OAUTH_EXPIRY_CLAIM_REQUIRED ?
1660 add->oauth.introspection_token_expiry_claim_required :
1661 base->oauth.introspection_token_expiry_claim_required;
1662
1663 c->oauth.remote_user_claim.claim_name =
1664 apr_strnatcmp(add->oauth.remote_user_claim.claim_name,
1665 OIDC_DEFAULT_OAUTH_CLAIM_REMOTE_USER) != 0 ?
1666 add->oauth.remote_user_claim.claim_name :
1667 base->oauth.remote_user_claim.claim_name;
1668 c->oauth.remote_user_claim.reg_exp =
1669 add->oauth.remote_user_claim.reg_exp != NULL ?
1670 add->oauth.remote_user_claim.reg_exp :
1671 base->oauth.remote_user_claim.reg_exp;
1672 c->oauth.remote_user_claim.replace =
1673 add->oauth.remote_user_claim.replace != NULL ?
1674 add->oauth.remote_user_claim.replace :
1675 base->oauth.remote_user_claim.replace;
1676
1677 c->oauth.verify_jwks_uri =
1678 add->oauth.verify_jwks_uri != NULL ?
1679 add->oauth.verify_jwks_uri : base->oauth.verify_jwks_uri;
1680 c->oauth.verify_public_keys =
1681 add->oauth.verify_public_keys != NULL ?
1682 add->oauth.verify_public_keys :
1683 base->oauth.verify_public_keys;
1684 c->oauth.verify_shared_keys =
1685 add->oauth.verify_shared_keys != NULL ?
1686 add->oauth.verify_shared_keys :
1687 base->oauth.verify_shared_keys;
1688
1689 c->oauth.access_token_binding_policy =
1690 add->oauth.access_token_binding_policy
1691 != OIDC_DEFAULT_OAUTH_ACCESS_TOKEN_BINDING_POLICY ?
1692 add->oauth.access_token_binding_policy :
1693 base->oauth.access_token_binding_policy;
1694
1695 c->http_timeout_long =
1696 add->http_timeout_long != OIDC_DEFAULT_HTTP_TIMEOUT_LONG ?
1697 add->http_timeout_long : base->http_timeout_long;
1698 c->http_timeout_short =
1699 add->http_timeout_short != OIDC_DEFAULT_HTTP_TIMEOUT_SHORT ?
1700 add->http_timeout_short : base->http_timeout_short;
1701 c->state_timeout =
1702 add->state_timeout != OIDC_DEFAULT_STATE_TIMEOUT ?
1703 add->state_timeout : base->state_timeout;
1704 c->max_number_of_state_cookies =
1705 add->max_number_of_state_cookies != OIDC_CONFIG_POS_INT_UNSET ?
1706 add->max_number_of_state_cookies :
1707 base->max_number_of_state_cookies;
1708 c->delete_oldest_state_cookies =
1709 add->delete_oldest_state_cookies != OIDC_CONFIG_POS_INT_UNSET ?
1710 add->delete_oldest_state_cookies :
1711 base->delete_oldest_state_cookies;
1712 c->session_inactivity_timeout =
1713 add->session_inactivity_timeout
1714 != OIDC_DEFAULT_SESSION_INACTIVITY_TIMEOUT ?
1715 add->session_inactivity_timeout :
1716 base->session_inactivity_timeout;
1717
1718 if (add->cache != &oidc_cache_shm) {
1719 c->cache = add->cache;
1720 } else {
1721 c->cache = base->cache;
1722 }
1723
1724 c->cache_encrypt =
1725 add->cache_encrypt != OIDC_CONFIG_POS_INT_UNSET ?
1726 add->cache_encrypt : base->cache_encrypt;
1727
1728 c->cache_cfg = NULL;
1729
1730 c->cache_file_dir =
1731 add->cache_file_dir != NULL ?
1732 add->cache_file_dir : base->cache_file_dir;
1733 c->cache_file_clean_interval =
1734 add->cache_file_clean_interval
1735 != OIDC_DEFAULT_CACHE_FILE_CLEAN_INTERVAL ?
1736 add->cache_file_clean_interval :
1737 base->cache_file_clean_interval;
1738
1739 #ifdef USE_MEMCACHE
1740 c->cache_memcache_servers =
1741 add->cache_memcache_servers != NULL ?
1742 add->cache_memcache_servers : base->cache_memcache_servers;
1743 #endif
1744 c->cache_shm_size_max =
1745 add->cache_shm_size_max != OIDC_DEFAULT_CACHE_SHM_SIZE ?
1746 add->cache_shm_size_max : base->cache_shm_size_max;
1747 c->cache_shm_entry_size_max =
1748 add->cache_shm_entry_size_max
1749 != OIDC_DEFAULT_CACHE_SHM_ENTRY_SIZE_MAX ?
1750 add->cache_shm_entry_size_max :
1751 base->cache_shm_entry_size_max;
1752
1753 #ifdef USE_LIBHIREDIS
1754 c->cache_redis_server =
1755 add->cache_redis_server != NULL ?
1756 add->cache_redis_server : base->cache_redis_server;
1757 c->cache_redis_password =
1758 add->cache_redis_password != NULL ?
1759 add->cache_redis_password : base->cache_redis_password;
1760 c->cache_redis_database =
1761 add->cache_redis_database != -1 ?
1762 add->cache_redis_database : base->cache_redis_database;
1763 #endif
1764
1765 c->metadata_dir =
1766 add->metadata_dir != NULL ? add->metadata_dir : base->metadata_dir;
1767 c->session_type =
1768 add->session_type != OIDC_DEFAULT_SESSION_TYPE ?
1769 add->session_type : base->session_type;
1770 c->session_cache_fallback_to_cookie =
1771 add->session_cache_fallback_to_cookie != OIDC_CONFIG_POS_INT_UNSET ?
1772 add->session_cache_fallback_to_cookie :
1773 base->session_cache_fallback_to_cookie;
1774 c->persistent_session_cookie =
1775 add->persistent_session_cookie != 0 ?
1776 add->persistent_session_cookie :
1777 base->persistent_session_cookie;
1778 c->session_cookie_chunk_size =
1779 add->session_cookie_chunk_size
1780 != OIDC_DEFAULT_SESSION_CLIENT_COOKIE_CHUNK_SIZE ?
1781 add->session_cookie_chunk_size :
1782 base->session_cookie_chunk_size;
1783
1784 c->cookie_domain =
1785 add->cookie_domain != NULL ?
1786 add->cookie_domain : base->cookie_domain;
1787 c->claim_delimiter =
1788 apr_strnatcmp(add->claim_delimiter, OIDC_DEFAULT_CLAIM_DELIMITER)
1789 != 0 ? add->claim_delimiter : base->claim_delimiter;
1790 c->claim_prefix =
1791 add->claim_prefix != NULL ? add->claim_prefix : base->claim_prefix;
1792 c->remote_user_claim.claim_name =
1793 apr_strnatcmp(add->remote_user_claim.claim_name,
1794 OIDC_DEFAULT_CLAIM_REMOTE_USER) != 0 ?
1795 add->remote_user_claim.claim_name :
1796 base->remote_user_claim.claim_name;
1797 c->remote_user_claim.reg_exp =
1798 add->remote_user_claim.reg_exp != NULL ?
1799 add->remote_user_claim.reg_exp :
1800 base->remote_user_claim.reg_exp;
1801 c->remote_user_claim.replace =
1802 add->remote_user_claim.replace != NULL ?
1803 add->remote_user_claim.replace :
1804 base->remote_user_claim.replace;
1805 c->pass_idtoken_as =
1806 add->pass_idtoken_as != OIDC_PASS_IDTOKEN_AS_CLAIMS ?
1807 add->pass_idtoken_as : base->pass_idtoken_as;
1808 c->pass_userinfo_as =
1809 add->pass_userinfo_as != OIDC_PASS_USERINFO_AS_CLAIMS ?
1810 add->pass_userinfo_as : base->pass_userinfo_as;
1811 c->cookie_http_only =
1812 add->cookie_http_only != OIDC_DEFAULT_COOKIE_HTTPONLY ?
1813 add->cookie_http_only : base->cookie_http_only;
1814 c->cookie_same_site =
1815 add->cookie_same_site != OIDC_DEFAULT_COOKIE_SAME_SITE ?
1816 add->cookie_same_site : base->cookie_same_site;
1817
1818 c->outgoing_proxy =
1819 add->outgoing_proxy != NULL ?
1820 add->outgoing_proxy : base->outgoing_proxy;
1821
1822 c->crypto_passphrase =
1823 add->crypto_passphrase != NULL ?
1824 add->crypto_passphrase : base->crypto_passphrase;
1825
1826 c->error_template =
1827 add->error_template != NULL ?
1828 add->error_template : base->error_template;
1829
1830 c->provider.userinfo_refresh_interval =
1831 add->provider.userinfo_refresh_interval
1832 != OIDC_DEFAULT_USERINFO_REFRESH_INTERVAL ?
1833 add->provider.userinfo_refresh_interval :
1834 base->provider.userinfo_refresh_interval;
1835 c->provider.request_object =
1836 add->provider.request_object != NULL ?
1837 add->provider.request_object :
1838 base->provider.request_object;
1839
1840 c->provider_metadata_refresh_interval =
1841 add->provider_metadata_refresh_interval
1842 != OIDC_DEFAULT_PROVIDER_METADATA_REFRESH_INTERVAL ?
1843 add->provider_metadata_refresh_interval :
1844 base->provider_metadata_refresh_interval;
1845
1846 c->provider.token_binding_policy =
1847 add->provider.token_binding_policy
1848 != OIDC_DEFAULT_PROVIDER_TOKEN_BINDING_POLICY ?
1849 add->provider.token_binding_policy :
1850 base->provider.token_binding_policy;
1851
1852 c->info_hook_data =
1853 add->info_hook_data != NULL ?
1854 add->info_hook_data : base->info_hook_data;
1855 c->black_listed_claims =
1856 add->black_listed_claims != NULL ?
1857 add->black_listed_claims : base->black_listed_claims;
1858 c->white_listed_claims =
1859 add->white_listed_claims != NULL ?
1860 add->white_listed_claims : base->white_listed_claims;
1861
1862 c->provider.issuer_specific_redirect_uri =
1863 add->provider.issuer_specific_redirect_uri
1864 != OIDC_DEFAULT_PROVIDER_ISSUER_SPECIFIC_REDIRECT_URI ?
1865 add->provider.issuer_specific_redirect_uri :
1866 base->provider.issuer_specific_redirect_uri;
1867
1868 c->state_input_headers =
1869 add->state_input_headers != OIDC_DEFAULT_STATE_INPUT_HEADERS ?
1870 add->state_input_headers : base->state_input_headers;
1871
1872 c->redirect_urls_allowed =
1873 add->redirect_urls_allowed != NULL ?
1874 add->redirect_urls_allowed : base->redirect_urls_allowed;
1875
1876 c->ca_bundle_path =
1877 add->ca_bundle_path != NULL ?
1878 add->ca_bundle_path : base->ca_bundle_path;
1879
1880 return c;
1881 }
1882
oidc_cfg_cache_encrypt(request_rec * r)1883 int oidc_cfg_cache_encrypt(request_rec *r) {
1884 oidc_cfg *cfg = ap_get_module_config(r->server->module_config,
1885 &auth_openidc_module);
1886 if (cfg->cache_encrypt == OIDC_CONFIG_POS_INT_UNSET)
1887 return cfg->cache->encrypt_by_default;
1888 return cfg->cache_encrypt;
1889 }
1890
oidc_cfg_session_cache_fallback_to_cookie(request_rec * r)1891 int oidc_cfg_session_cache_fallback_to_cookie(request_rec *r) {
1892 oidc_cfg *cfg = ap_get_module_config(r->server->module_config,
1893 &auth_openidc_module);
1894 if (cfg->session_cache_fallback_to_cookie == OIDC_CONFIG_POS_INT_UNSET)
1895 return 0;
1896 return cfg->session_cache_fallback_to_cookie;
1897 }
1898
1899 /*
1900 * create a new directory config record with defaults
1901 */
oidc_create_dir_config(apr_pool_t * pool,char * path)1902 void* oidc_create_dir_config(apr_pool_t *pool, char *path) {
1903 oidc_dir_cfg *c = apr_pcalloc(pool, sizeof(oidc_dir_cfg));
1904 c->discover_url = OIDC_CONFIG_STRING_UNSET;
1905 c->cookie = OIDC_CONFIG_STRING_UNSET;
1906 c->cookie_path = OIDC_CONFIG_STRING_UNSET;
1907 c->authn_header = OIDC_CONFIG_STRING_UNSET;
1908 c->unauth_action = OIDC_CONFIG_POS_INT_UNSET;
1909 #if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
1910 c->unauth_expression = NULL;
1911 #endif
1912 c->unautz_action = OIDC_CONFIG_POS_INT_UNSET;
1913 c->pass_cookies = NULL;
1914 c->strip_cookies = NULL;
1915 c->pass_info_in_headers = OIDC_CONFIG_POS_INT_UNSET;
1916 c->pass_info_in_env_vars = OIDC_CONFIG_POS_INT_UNSET;
1917 c->pass_info_base64url = OIDC_CONFIG_POS_INT_UNSET;
1918 c->oauth_accept_token_in = OIDC_CONFIG_POS_INT_UNSET;
1919 c->oauth_accept_token_options = apr_hash_make(pool);
1920 c->oauth_token_introspect_interval = -2;
1921 c->preserve_post = OIDC_CONFIG_POS_INT_UNSET;
1922 c->pass_refresh_token = OIDC_CONFIG_POS_INT_UNSET;
1923 c->path_auth_request_params = NULL;
1924 c->path_scope = NULL;
1925 c->refresh_access_token_before_expiry = OIDC_CONFIG_POS_INT_UNSET;
1926 c->logout_on_error_refresh = OIDC_CONFIG_POS_INT_UNSET;
1927 c->state_cookie_prefix = OIDC_CONFIG_STRING_UNSET;
1928 return (c);
1929 }
1930
oidc_cfg_dir_discover_url(request_rec * r)1931 char* oidc_cfg_dir_discover_url(request_rec *r) {
1932 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
1933 &auth_openidc_module);
1934 if ((dir_cfg->discover_url != NULL) && (apr_strnatcmp(dir_cfg->discover_url,
1935 OIDC_CONFIG_STRING_UNSET) == 0))
1936 return NULL;
1937 return dir_cfg->discover_url;
1938 }
1939
oidc_cfg_dir_cookie(request_rec * r)1940 char* oidc_cfg_dir_cookie(request_rec *r) {
1941 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
1942 &auth_openidc_module);
1943 if ((dir_cfg->cookie == NULL)
1944 || ((dir_cfg->cookie != NULL)
1945 && (apr_strnatcmp(dir_cfg->cookie, OIDC_CONFIG_STRING_UNSET)
1946 == 0)))
1947 return OIDC_DEFAULT_COOKIE;
1948 return dir_cfg->cookie;
1949 }
1950
oidc_cfg_dir_cookie_path(request_rec * r)1951 char* oidc_cfg_dir_cookie_path(request_rec *r) {
1952 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
1953 &auth_openidc_module);
1954 if ((dir_cfg->cookie_path == NULL)
1955 || ((dir_cfg->cookie_path != NULL)
1956 && (apr_strnatcmp(dir_cfg->cookie_path,
1957 OIDC_CONFIG_STRING_UNSET) == 0)))
1958 return OIDC_DEFAULT_COOKIE_PATH;
1959 return dir_cfg->cookie_path;
1960 }
1961
oidc_cfg_dir_authn_header(request_rec * r)1962 char* oidc_cfg_dir_authn_header(request_rec *r) {
1963 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
1964 &auth_openidc_module);
1965 if ((dir_cfg->authn_header == NULL)
1966 || ((dir_cfg->authn_header != NULL)
1967 && (apr_strnatcmp(dir_cfg->authn_header,
1968 OIDC_CONFIG_STRING_UNSET) == 0)))
1969 return OIDC_DEFAULT_AUTHN_HEADER;
1970 return dir_cfg->authn_header;
1971 }
1972
oidc_cfg_dir_pass_info_in_headers(request_rec * r)1973 apr_byte_t oidc_cfg_dir_pass_info_in_headers(request_rec *r) {
1974 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
1975 &auth_openidc_module);
1976 if (dir_cfg->pass_info_in_headers == OIDC_CONFIG_POS_INT_UNSET)
1977 return OIDC_DEFAULT_PASS_APP_INFO_IN_HEADERS;
1978 return dir_cfg->pass_info_in_headers;
1979 }
1980
oidc_cfg_dir_pass_info_in_envvars(request_rec * r)1981 apr_byte_t oidc_cfg_dir_pass_info_in_envvars(request_rec *r) {
1982 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
1983 &auth_openidc_module);
1984 if (dir_cfg->pass_info_in_env_vars == OIDC_CONFIG_POS_INT_UNSET)
1985 return OIDC_DEFAULT_PASS_APP_INFO_IN_ENVVARS;
1986 return dir_cfg->pass_info_in_env_vars;
1987 }
1988
oidc_cfg_dir_pass_info_base64url(request_rec * r)1989 apr_byte_t oidc_cfg_dir_pass_info_base64url(request_rec *r) {
1990 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
1991 &auth_openidc_module);
1992 if (dir_cfg->pass_info_base64url == OIDC_CONFIG_POS_INT_UNSET)
1993 return OIDC_DEFAULT_PASS_APP_INFO_BASE64URL;
1994 return dir_cfg->pass_info_base64url;
1995 }
1996
oidc_cfg_dir_pass_refresh_token(request_rec * r)1997 apr_byte_t oidc_cfg_dir_pass_refresh_token(request_rec *r) {
1998 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
1999 &auth_openidc_module);
2000 if (dir_cfg->pass_refresh_token == OIDC_CONFIG_POS_INT_UNSET)
2001 return OIDC_DEFAULT_PASS_REFRESH_TOKEN;
2002 return dir_cfg->pass_refresh_token;
2003 }
2004
oidc_cfg_dir_accept_token_in(request_rec * r)2005 apr_byte_t oidc_cfg_dir_accept_token_in(request_rec *r) {
2006 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
2007 &auth_openidc_module);
2008 if (dir_cfg->oauth_accept_token_in == OIDC_CONFIG_POS_INT_UNSET)
2009 return OIDC_OAUTH_ACCEPT_TOKEN_IN_DEFAULT;
2010 return dir_cfg->oauth_accept_token_in;
2011 }
2012
oidc_cfg_dir_accept_token_in_option(request_rec * r,const char * key)2013 char* oidc_cfg_dir_accept_token_in_option(request_rec *r, const char *key) {
2014 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
2015 &auth_openidc_module);
2016 return apr_hash_get(dir_cfg->oauth_accept_token_options, key,
2017 APR_HASH_KEY_STRING);
2018 }
2019
oidc_cfg_token_introspection_interval(request_rec * r)2020 int oidc_cfg_token_introspection_interval(request_rec *r) {
2021 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
2022 &auth_openidc_module);
2023 if (dir_cfg->oauth_token_introspect_interval <= -2)
2024 return OIDC_DEFAULT_TOKEN_INTROSPECTION_INTERVAL;
2025 return dir_cfg->oauth_token_introspect_interval;
2026 }
2027
oidc_cfg_dir_preserve_post(request_rec * r)2028 int oidc_cfg_dir_preserve_post(request_rec *r) {
2029 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
2030 &auth_openidc_module);
2031 if (dir_cfg->preserve_post == OIDC_CONFIG_POS_INT_UNSET)
2032 return OIDC_DEFAULT_PRESERVE_POST;
2033 return dir_cfg->preserve_post;
2034 }
2035
oidc_dir_cfg_pass_cookies(request_rec * r)2036 apr_array_header_t* oidc_dir_cfg_pass_cookies(request_rec *r) {
2037 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
2038 &auth_openidc_module);
2039 return dir_cfg->pass_cookies;
2040 }
2041
oidc_dir_cfg_strip_cookies(request_rec * r)2042 apr_array_header_t* oidc_dir_cfg_strip_cookies(request_rec *r) {
2043 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
2044 &auth_openidc_module);
2045 return dir_cfg->strip_cookies;
2046 }
2047
oidc_dir_cfg_unauth_action(request_rec * r)2048 int oidc_dir_cfg_unauth_action(request_rec *r) {
2049 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
2050 &auth_openidc_module);
2051
2052 if (dir_cfg->unauth_action == OIDC_CONFIG_POS_INT_UNSET)
2053 return OIDC_DEFAULT_UNAUTH_ACTION;
2054
2055 #if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
2056 int rc = 0;
2057 const char *err_str = NULL;
2058 if (dir_cfg->unauth_expression == NULL)
2059 return dir_cfg->unauth_action;
2060
2061 rc = ap_expr_exec(r, dir_cfg->unauth_expression, &err_str);
2062
2063 if (rc < 0) {
2064 oidc_warn(r, "executing expression failed");
2065 return OIDC_DEFAULT_UNAUTH_ACTION;
2066 }
2067
2068 return (rc > 0) ? dir_cfg->unauth_action : OIDC_DEFAULT_UNAUTH_ACTION;
2069 #else
2070 return dir_cfg->unauth_action;
2071 #endif
2072 }
2073
oidc_dir_cfg_unauth_expr_is_set(request_rec * r)2074 apr_byte_t oidc_dir_cfg_unauth_expr_is_set(request_rec *r) {
2075 #if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
2076 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
2077 &auth_openidc_module);
2078 return (dir_cfg->unauth_expression != NULL) ? TRUE : FALSE;
2079 #else
2080 return FALSE;
2081 #endif
2082 }
2083
oidc_dir_cfg_unautz_action(request_rec * r)2084 int oidc_dir_cfg_unautz_action(request_rec *r) {
2085 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
2086 &auth_openidc_module);
2087 if (dir_cfg->unautz_action == OIDC_CONFIG_POS_INT_UNSET)
2088 return OIDC_DEFAULT_UNAUTZ_ACTION;
2089 return dir_cfg->unautz_action;
2090 }
2091
oidc_dir_cfg_path_auth_request_params(request_rec * r)2092 char* oidc_dir_cfg_path_auth_request_params(request_rec *r) {
2093 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
2094 &auth_openidc_module);
2095 return dir_cfg->path_auth_request_params;
2096 }
2097
oidc_dir_cfg_path_scope(request_rec * r)2098 char* oidc_dir_cfg_path_scope(request_rec *r) {
2099 oidc_dir_cfg *dir_cfg = ap_get_module_config(r->per_dir_config,
2100 &auth_openidc_module);
2101 return dir_cfg->path_scope;
2102 }
2103
2104 /*
2105 * merge a new directory config with a base one
2106 */
oidc_merge_dir_config(apr_pool_t * pool,void * BASE,void * ADD)2107 void* oidc_merge_dir_config(apr_pool_t *pool, void *BASE, void *ADD) {
2108 oidc_dir_cfg *c = apr_pcalloc(pool, sizeof(oidc_dir_cfg));
2109 oidc_dir_cfg *base = BASE;
2110 oidc_dir_cfg *add = ADD;
2111 c->discover_url =
2112 (apr_strnatcmp(add->discover_url, OIDC_CONFIG_STRING_UNSET) != 0) ?
2113 add->discover_url : base->discover_url;
2114 c->cookie =
2115 (apr_strnatcmp(add->cookie, OIDC_CONFIG_STRING_UNSET) != 0) ?
2116 add->cookie : base->cookie;
2117 c->cookie_path =
2118 (apr_strnatcmp(add->cookie_path, OIDC_CONFIG_STRING_UNSET) != 0) ?
2119 add->cookie_path : base->cookie_path;
2120 c->authn_header =
2121 (apr_strnatcmp(add->authn_header, OIDC_CONFIG_STRING_UNSET) != 0) ?
2122 add->authn_header : base->authn_header;
2123 c->unauth_action =
2124 add->unauth_action != OIDC_CONFIG_POS_INT_UNSET ?
2125 add->unauth_action : base->unauth_action;
2126 #if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
2127 c->unauth_expression =
2128 add->unauth_expression != NULL ?
2129 add->unauth_expression : base->unauth_expression;
2130 #endif
2131 c->unautz_action =
2132 add->unautz_action != OIDC_CONFIG_POS_INT_UNSET ?
2133 add->unautz_action : base->unautz_action;
2134
2135 c->pass_cookies =
2136 add->pass_cookies != NULL ? add->pass_cookies : base->pass_cookies;
2137 c->strip_cookies =
2138 add->strip_cookies != NULL ?
2139 add->strip_cookies : base->strip_cookies;
2140
2141 c->pass_info_in_headers =
2142 add->pass_info_in_headers != OIDC_CONFIG_POS_INT_UNSET ?
2143 add->pass_info_in_headers : base->pass_info_in_headers;
2144 c->pass_info_in_env_vars =
2145 add->pass_info_in_env_vars != OIDC_CONFIG_POS_INT_UNSET ?
2146 add->pass_info_in_env_vars : base->pass_info_in_env_vars;
2147 c->pass_info_base64url =
2148 add->pass_info_base64url != OIDC_CONFIG_POS_INT_UNSET ?
2149 add->pass_info_base64url : base->pass_info_base64url;
2150 c->oauth_accept_token_in =
2151 add->oauth_accept_token_in != OIDC_CONFIG_POS_INT_UNSET ?
2152 add->oauth_accept_token_in : base->oauth_accept_token_in;
2153 c->oauth_accept_token_options =
2154 apr_hash_count(add->oauth_accept_token_options) > 0 ?
2155 add->oauth_accept_token_options :
2156 base->oauth_accept_token_options;
2157 c->oauth_token_introspect_interval =
2158 add->oauth_token_introspect_interval >= -1 ?
2159 add->oauth_token_introspect_interval :
2160 base->oauth_token_introspect_interval;
2161 c->preserve_post =
2162 add->preserve_post != OIDC_CONFIG_POS_INT_UNSET ?
2163 add->preserve_post : base->preserve_post;
2164 c->pass_refresh_token =
2165 add->pass_refresh_token != OIDC_CONFIG_POS_INT_UNSET ?
2166 add->pass_refresh_token : base->pass_refresh_token;
2167 c->path_auth_request_params =
2168 add->path_auth_request_params != NULL ?
2169 add->path_auth_request_params :
2170 base->path_auth_request_params;
2171 c->path_scope =
2172 add->path_scope != NULL ? add->path_scope : base->path_scope;
2173
2174 c->refresh_access_token_before_expiry =
2175 add->refresh_access_token_before_expiry != OIDC_CONFIG_POS_INT_UNSET ?
2176 add->refresh_access_token_before_expiry :
2177 base->refresh_access_token_before_expiry;
2178
2179 c->logout_on_error_refresh =
2180 add->logout_on_error_refresh != OIDC_CONFIG_POS_INT_UNSET ?
2181 add->logout_on_error_refresh :
2182 base->logout_on_error_refresh;
2183
2184 c->state_cookie_prefix =
2185 (apr_strnatcmp(add->state_cookie_prefix, OIDC_CONFIG_STRING_UNSET)
2186 != 0) ?
2187 add->state_cookie_prefix : base->state_cookie_prefix;
2188
2189 return (c);
2190 }
2191
2192 /*
2193 * report a config error
2194 */
oidc_check_config_error(server_rec * s,const char * config_str)2195 static int oidc_check_config_error(server_rec *s, const char *config_str) {
2196 oidc_serror(s, "mandatory parameter '%s' is not set", config_str);
2197 return HTTP_INTERNAL_SERVER_ERROR;
2198 }
2199
2200 /*
2201 * check the config required for the OpenID Connect RP role
2202 */
oidc_check_config_openid_openidc(server_rec * s,oidc_cfg * c)2203 static int oidc_check_config_openid_openidc(server_rec *s, oidc_cfg *c) {
2204
2205 apr_uri_t r_uri;
2206 apr_byte_t redirect_uri_is_relative;
2207
2208 if ((c->metadata_dir == NULL) && (c->provider.issuer == NULL)
2209 && (c->provider.metadata_url == NULL)) {
2210 oidc_serror(s,
2211 "one of '" OIDCProviderIssuer "', '" OIDCProviderMetadataURL "' or '" OIDCMetadataDir "' must be set");
2212 return HTTP_INTERNAL_SERVER_ERROR;
2213 }
2214
2215 if (c->redirect_uri == NULL)
2216 return oidc_check_config_error(s, OIDCRedirectURI);
2217 redirect_uri_is_relative = (c->redirect_uri[0] == OIDC_CHAR_FORWARD_SLASH);
2218
2219 if (c->crypto_passphrase == NULL)
2220 return oidc_check_config_error(s, OIDCCryptoPassphrase);
2221
2222 if (c->metadata_dir == NULL) {
2223 if (c->provider.metadata_url == NULL) {
2224 if (c->provider.issuer == NULL)
2225 return oidc_check_config_error(s, OIDCProviderIssuer);
2226 if (c->provider.authorization_endpoint_url == NULL)
2227 return oidc_check_config_error(s,
2228 OIDCProviderAuthorizationEndpoint);
2229 } else {
2230 apr_uri_parse(s->process->pconf, c->provider.metadata_url, &r_uri);
2231 if ((r_uri.scheme == NULL)
2232 || (apr_strnatcmp(r_uri.scheme, "https") != 0)) {
2233 oidc_swarn(s,
2234 "the URL scheme (%s) of the configured " OIDCProviderMetadataURL " SHOULD be \"https\" for security reasons!",
2235 r_uri.scheme);
2236 }
2237 }
2238 if (c->provider.client_id == NULL)
2239 return oidc_check_config_error(s, OIDCClientID);
2240 } else {
2241 if (c->provider.metadata_url != NULL) {
2242 oidc_serror(s,
2243 "only one of '" OIDCProviderMetadataURL "' or '" OIDCMetadataDir "' should be set");
2244 return HTTP_INTERNAL_SERVER_ERROR;
2245 }
2246 }
2247
2248 apr_uri_parse(s->process->pconf, c->redirect_uri, &r_uri);
2249 if (!redirect_uri_is_relative) {
2250 if (apr_strnatcmp(r_uri.scheme, "https") != 0) {
2251 oidc_swarn(s,
2252 "the URL scheme (%s) of the configured " OIDCRedirectURI " SHOULD be \"https\" for security reasons (moreover: some Providers may reject non-HTTPS URLs)",
2253 r_uri.scheme);
2254 }
2255 }
2256
2257 if (c->cookie_domain != NULL) {
2258 if (redirect_uri_is_relative) {
2259 oidc_swarn(s,
2260 "if the configured " OIDCRedirectURI " is relative, " OIDCCookieDomain " SHOULD be empty");
2261 } else if (!oidc_util_cookie_domain_valid(r_uri.hostname,
2262 c->cookie_domain)) {
2263 oidc_serror(s,
2264 "the domain (%s) configured in " OIDCCookieDomain " does not match the URL hostname (%s) of the configured " OIDCRedirectURI " (%s): setting \"state\" and \"session\" cookies will not work!",
2265 c->cookie_domain, r_uri.hostname, c->redirect_uri);
2266 return HTTP_INTERNAL_SERVER_ERROR;
2267 }
2268 }
2269
2270 return OK;
2271 }
2272
2273 /*
2274 * check the config required for the OAuth 2.0 RS role
2275 */
oidc_check_config_oauth(server_rec * s,oidc_cfg * c)2276 static int oidc_check_config_oauth(server_rec *s, oidc_cfg *c) {
2277
2278 apr_uri_t r_uri;
2279
2280 oidc_swarn(s,
2281 "The OAuth 2.0 Resource Server functionality is deprecated and superseded by a new module, see: https://github.com/zmartzone/mod_oauth2!");
2282
2283 if (c->oauth.metadata_url != NULL) {
2284 apr_uri_parse(s->process->pconf, c->oauth.metadata_url, &r_uri);
2285 if ((r_uri.scheme == NULL)
2286 || (apr_strnatcmp(r_uri.scheme, "https") != 0)) {
2287 oidc_swarn(s,
2288 "the URL scheme (%s) of the configured " OIDCOAuthServerMetadataURL " SHOULD be \"https\" for security reasons!",
2289 r_uri.scheme);
2290 }
2291 return OK;
2292 }
2293
2294 if (c->oauth.introspection_endpoint_url == NULL) {
2295
2296 if ((c->oauth.verify_jwks_uri == NULL)
2297 && (c->oauth.verify_public_keys == NULL)
2298 && (c->oauth.verify_shared_keys == NULL)) {
2299 oidc_serror(s,
2300 "one of '" OIDCOAuthServerMetadataURL "', '" OIDCOAuthIntrospectionEndpoint "', '" OIDCOAuthVerifyJwksUri "', '" OIDCOAuthVerifySharedKeys "' or '" OIDCOAuthVerifyCertFiles "' must be set");
2301 return HTTP_INTERNAL_SERVER_ERROR;
2302 }
2303
2304 } else if ((c->oauth.verify_jwks_uri != NULL)
2305 || (c->oauth.verify_public_keys != NULL)
2306 || (c->oauth.verify_shared_keys != NULL)) {
2307 oidc_serror(s,
2308 "only '" OIDCOAuthIntrospectionEndpoint "' OR one (or more) out of ('" OIDCOAuthVerifyJwksUri "', '" OIDCOAuthVerifySharedKeys "' or '" OIDCOAuthVerifyCertFiles "') must be set");
2309 return HTTP_INTERNAL_SERVER_ERROR;
2310
2311 }
2312
2313 if ((c->cache_encrypt == 1) && (c->crypto_passphrase == NULL))
2314 return oidc_check_config_error(s, OIDCCryptoPassphrase);
2315
2316 return OK;
2317 }
2318
2319 /*
2320 * check the config of a vhost
2321 */
oidc_config_check_vhost_config(apr_pool_t * pool,server_rec * s)2322 static int oidc_config_check_vhost_config(apr_pool_t *pool, server_rec *s) {
2323 oidc_cfg *cfg = ap_get_module_config(s->module_config,
2324 &auth_openidc_module);
2325
2326 oidc_sdebug(s, "enter");
2327
2328 if ((cfg->metadata_dir != NULL) || (cfg->provider.issuer != NULL)
2329 || (cfg->provider.metadata_url != NULL)) {
2330 if (oidc_check_config_openid_openidc(s, cfg) != OK)
2331 return HTTP_INTERNAL_SERVER_ERROR;
2332 }
2333
2334 if ((cfg->oauth.metadata_url != NULL) || (cfg->oauth.client_id != NULL)
2335 || (cfg->oauth.client_secret != NULL)
2336 || (cfg->oauth.introspection_endpoint_url != NULL)
2337 || (cfg->oauth.verify_jwks_uri != NULL)
2338 || (cfg->oauth.verify_public_keys != NULL)
2339 || (cfg->oauth.verify_shared_keys != NULL)) {
2340 if (oidc_check_config_oauth(s, cfg) != OK)
2341 return HTTP_INTERNAL_SERVER_ERROR;
2342 }
2343
2344 return OK;
2345 }
2346
2347 /*
2348 * check the config of a merged vhost
2349 */
oidc_config_check_merged_vhost_configs(apr_pool_t * pool,server_rec * s)2350 static int oidc_config_check_merged_vhost_configs(apr_pool_t *pool,
2351 server_rec *s) {
2352 int status = OK;
2353 while (s != NULL && status == OK) {
2354 oidc_cfg *cfg = ap_get_module_config(s->module_config,
2355 &auth_openidc_module);
2356 if (cfg->merged) {
2357 status = oidc_config_check_vhost_config(pool, s);
2358 }
2359 s = s->next;
2360 }
2361 return status;
2362 }
2363
2364 /*
2365 * check if any merged vhost configs exist
2366 */
oidc_config_merged_vhost_configs_exist(server_rec * s)2367 static int oidc_config_merged_vhost_configs_exist(server_rec *s) {
2368 while (s != NULL) {
2369 oidc_cfg *cfg = ap_get_module_config(s->module_config,
2370 &auth_openidc_module);
2371 if (cfg->merged) {
2372 return TRUE;
2373 }
2374 s = s->next;
2375 }
2376 return FALSE;
2377 }
2378
2379 /*
2380 * SSL initialization magic copied from mod_auth_cas
2381 */
2382 #if ((OPENSSL_VERSION_NUMBER < 0x10100000) && defined(OPENSSL_THREADS) && APR_HAS_THREADS)
2383
2384 static apr_thread_mutex_t **ssl_locks;
2385 static int ssl_num_locks;
2386
oidc_ssl_locking_callback(int mode,int type,const char * file,int line)2387 static void oidc_ssl_locking_callback(int mode, int type, const char *file,
2388 int line) {
2389 if (type < ssl_num_locks) {
2390 if (mode & CRYPTO_LOCK)
2391 apr_thread_mutex_lock(ssl_locks[type]);
2392 else
2393 apr_thread_mutex_unlock(ssl_locks[type]);
2394 }
2395 }
2396
2397 #ifdef OPENSSL_NO_THREADID
oidc_ssl_id_callback(void)2398 static unsigned long oidc_ssl_id_callback(void) {
2399 return (unsigned long) apr_os_thread_current();
2400 }
2401 #else
oidc_ssl_id_callback(CRYPTO_THREADID * id)2402 static void oidc_ssl_id_callback(CRYPTO_THREADID *id) {
2403 CRYPTO_THREADID_set_numeric(id, (unsigned long) apr_os_thread_current());
2404 }
2405 #endif /* OPENSSL_NO_THREADID */
2406
2407 #endif /* defined(OPENSSL_THREADS) && APR_HAS_THREADS */
2408
oidc_cleanup_child(void * data)2409 static apr_status_t oidc_cleanup_child(void *data) {
2410 server_rec *sp = (server_rec*) data;
2411 while (sp != NULL) {
2412 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(sp->module_config,
2413 &auth_openidc_module);
2414 if (cfg->cache->destroy != NULL) {
2415 if (cfg->cache->destroy(sp) != APR_SUCCESS) {
2416 oidc_serror(sp, "cache destroy function failed");
2417 }
2418 }
2419
2420 // can do this even though we haven't got a deep copy
2421 // since references within the object will be set to NULL
2422 oidc_jwk_list_destroy_hash(sp->process->pool,
2423 cfg->oauth.verify_public_keys);
2424 oidc_jwk_list_destroy_hash(sp->process->pool,
2425 cfg->oauth.verify_shared_keys);
2426 oidc_jwk_list_destroy(sp->process->pool, cfg->public_keys);
2427 oidc_jwk_list_destroy(sp->process->pool, cfg->private_keys);
2428
2429 sp = sp->next;
2430 }
2431
2432 return APR_SUCCESS;
2433 }
2434
oidc_cleanup_parent(void * data)2435 static apr_status_t oidc_cleanup_parent(void *data) {
2436
2437 oidc_cleanup_child(data);
2438
2439 #if ((OPENSSL_VERSION_NUMBER < 0x10100000) && defined (OPENSSL_THREADS) && APR_HAS_THREADS)
2440 if (CRYPTO_get_locking_callback() == oidc_ssl_locking_callback)
2441 CRYPTO_set_locking_callback(NULL);
2442 #ifdef OPENSSL_NO_THREADID
2443 if (CRYPTO_get_id_callback() == oidc_ssl_id_callback)
2444 CRYPTO_set_id_callback(NULL);
2445 #else
2446 if (CRYPTO_THREADID_get_callback() == oidc_ssl_id_callback)
2447 CRYPTO_THREADID_set_callback(NULL);
2448 #endif /* OPENSSL_NO_THREADID */
2449
2450 #endif /* (OPENSSL_VERSION_NUMBER < 0x10100000) && defined (OPENSSL_THREADS) && APR_HAS_THREADS */
2451
2452 EVP_cleanup();
2453 curl_global_cleanup();
2454
2455 ap_log_error(APLOG_MARK, APLOG_INFO, 0, (server_rec* ) data,
2456 "%s - shutdown", NAMEVERSION);
2457
2458 return APR_SUCCESS;
2459 }
2460
2461 /*
2462 * handler that is called (twice) after the configuration phase; check if everything is OK
2463 */
oidc_post_config(apr_pool_t * pool,apr_pool_t * p1,apr_pool_t * p2,server_rec * s)2464 static int oidc_post_config(apr_pool_t *pool, apr_pool_t *p1, apr_pool_t *p2,
2465 server_rec *s) {
2466 const char *userdata_key = "oidc_post_config";
2467 void *data = NULL;
2468
2469 /* Since the post_config hook is invoked twice (once
2470 * for 'sanity checking' of the config and once for
2471 * the actual server launch, we have to use a hack
2472 * to not run twice
2473 */
2474 apr_pool_userdata_get(&data, userdata_key, s->process->pool);
2475 if (data == NULL) {
2476 apr_pool_userdata_set((const void*) 1, userdata_key,
2477 apr_pool_cleanup_null, s->process->pool);
2478 return OK;
2479 }
2480
2481 ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
2482 "%s - init - cjose %s, %s, EC=%s, GCM=%s, Memcache=%s, Redis=%s, JQ=%s",
2483 NAMEVERSION, cjose_version(), OPENSSL_VERSION_TEXT,
2484 OIDC_JOSE_EC_SUPPORT ? "yes" : "no",
2485 OIDC_JOSE_GCM_SUPPORT ? "yes" : "no",
2486 #ifdef USE_MEMCACHE
2487 "yes"
2488 #else
2489 "no"
2490 #endif
2491 ,
2492 #ifdef USE_LIBHIREDIS
2493 "yes"
2494 #else
2495 "no"
2496 #endif
2497 ,
2498 #ifdef USE_LIBJQ
2499 "yes"
2500 #else
2501 "no"
2502 #endif
2503 );
2504
2505 curl_global_init(CURL_GLOBAL_ALL);
2506 OpenSSL_add_all_digests();
2507
2508 #if ((OPENSSL_VERSION_NUMBER < 0x10100000) && defined (OPENSSL_THREADS) && APR_HAS_THREADS)
2509 ssl_num_locks = CRYPTO_num_locks();
2510 ssl_locks = apr_pcalloc(s->process->pool,
2511 ssl_num_locks * sizeof(*ssl_locks));
2512
2513 int i;
2514 for (i = 0; i < ssl_num_locks; i++)
2515 apr_thread_mutex_create(&(ssl_locks[i]), APR_THREAD_MUTEX_DEFAULT,
2516 s->process->pool);
2517
2518 #ifdef OPENSSL_NO_THREADID
2519 if (CRYPTO_get_locking_callback() == NULL && CRYPTO_get_id_callback() == NULL) {
2520 CRYPTO_set_locking_callback(oidc_ssl_locking_callback);
2521 CRYPTO_set_id_callback(oidc_ssl_id_callback);
2522 }
2523 #else
2524 if (CRYPTO_get_locking_callback() == NULL
2525 && CRYPTO_THREADID_get_callback() == NULL) {
2526 CRYPTO_set_locking_callback(oidc_ssl_locking_callback);
2527 CRYPTO_THREADID_set_callback(oidc_ssl_id_callback);
2528 }
2529 #endif /* OPENSSL_NO_THREADID */
2530
2531 #endif /* (OPENSSL_VERSION_NUMBER < 0x10100000) && defined (OPENSSL_THREADS) && APR_HAS_THREADS */
2532
2533 apr_pool_cleanup_register(pool, s, oidc_cleanup_parent,
2534 apr_pool_cleanup_null);
2535
2536 server_rec *sp = s;
2537 while (sp != NULL) {
2538 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(sp->module_config,
2539 &auth_openidc_module);
2540 if (cfg->cache->post_config != NULL) {
2541 if (cfg->cache->post_config(sp) != OK)
2542 return HTTP_INTERNAL_SERVER_ERROR;
2543 }
2544 sp = sp->next;
2545 }
2546
2547 /*
2548 * Apache has a base vhost that true vhosts derive from.
2549 * There are two startup scenarios:
2550 *
2551 * 1. Only the base vhost contains OIDC settings.
2552 * No server configs have been merged.
2553 * Only the base vhost needs to be checked.
2554 *
2555 * 2. The base vhost contains zero or more OIDC settings.
2556 * One or more vhosts override these.
2557 * These vhosts have a merged config.
2558 * All merged configs need to be checked.
2559 */
2560 if (!oidc_config_merged_vhost_configs_exist(s)) {
2561 /* nothing merged, only check the base vhost */
2562 return oidc_config_check_vhost_config(pool, s);
2563 }
2564 return oidc_config_check_merged_vhost_configs(pool, s);
2565 }
2566
2567 #if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
oidc_parse_config(cmd_parms * cmd,const char * require_line,const void ** parsed_require_line)2568 static const char* oidc_parse_config(cmd_parms *cmd, const char *require_line,
2569 const void **parsed_require_line) {
2570 const char *expr_err = NULL;
2571 ap_expr_info_t *expr;
2572
2573 expr = ap_expr_parse_cmd(cmd, require_line, AP_EXPR_FLAG_STRING_RESULT,
2574 &expr_err, NULL);
2575
2576 if (expr_err)
2577 return apr_pstrcat(cmd->temp_pool,
2578 "Cannot parse expression in require line: ", expr_err, NULL);
2579
2580 *parsed_require_line = expr;
2581
2582 return NULL;
2583 }
2584
2585 static const authz_provider oidc_authz_claim_provider = {
2586 &oidc_authz_checker_claim, &oidc_parse_config, };
2587 #ifdef USE_LIBJQ
2588 static const authz_provider oidc_authz_claims_expr_provider = {
2589 &oidc_authz_checker_claims_expr,
2590 NULL,
2591 };
2592 #endif
2593 #endif
2594
2595 /*
2596 * initialize cache context in child process if required
2597 */
oidc_child_init(apr_pool_t * p,server_rec * s)2598 static void oidc_child_init(apr_pool_t *p, server_rec *s) {
2599 server_rec *sp = s;
2600 while (sp != NULL) {
2601 oidc_cfg *cfg = (oidc_cfg*) ap_get_module_config(sp->module_config,
2602 &auth_openidc_module);
2603 if (cfg->cache->child_init != NULL) {
2604 if (cfg->cache->child_init(p, sp) != APR_SUCCESS) {
2605 oidc_serror(sp, "cfg->cache->child_init failed");
2606 }
2607 }
2608 sp = sp->next;
2609 }
2610 apr_pool_cleanup_register(p, s, oidc_cleanup_child, apr_pool_cleanup_null);
2611 }
2612
2613 static const char oidcFilterName[] = "oidc_filter_in_filter";
2614
oidc_filter_in_insert_filter(request_rec * r)2615 static void oidc_filter_in_insert_filter(request_rec *r) {
2616
2617 if (oidc_enabled(r) == FALSE)
2618 return;
2619
2620 if (ap_is_initial_req(r) == 0)
2621 return;
2622
2623 apr_table_t *userdata_post_params = NULL;
2624 apr_pool_userdata_get((void**) &userdata_post_params,
2625 OIDC_USERDATA_POST_PARAMS_KEY, r->pool);
2626 if (userdata_post_params == NULL)
2627 return;
2628
2629 ap_add_input_filter(oidcFilterName, NULL, r, r->connection);
2630 }
2631
2632 typedef struct oidc_filter_in_context {
2633 apr_bucket_brigade *pbbTmp;
2634 apr_size_t nbytes;
2635 } oidc_filter_in_context;
2636
oidc_filter_in_filter(ap_filter_t * f,apr_bucket_brigade * brigade,ap_input_mode_t mode,apr_read_type_e block,apr_off_t nbytes)2637 static apr_status_t oidc_filter_in_filter(ap_filter_t *f,
2638 apr_bucket_brigade *brigade, ap_input_mode_t mode,
2639 apr_read_type_e block, apr_off_t nbytes) {
2640 oidc_filter_in_context *ctx = NULL;
2641 apr_bucket *b_in = NULL, *b_out = NULL;
2642 char *buf = NULL;
2643 apr_table_t *userdata_post_params = NULL;
2644 apr_status_t rc = APR_SUCCESS;
2645
2646 if (!(ctx = f->ctx)) {
2647 f->ctx = ctx = apr_palloc(f->r->pool, sizeof *ctx);
2648 ctx->pbbTmp = apr_brigade_create(f->r->pool,
2649 f->r->connection->bucket_alloc);
2650 ctx->nbytes = 0;
2651 }
2652
2653 if (APR_BRIGADE_EMPTY(ctx->pbbTmp)) {
2654 rc = ap_get_brigade(f->next, ctx->pbbTmp, mode, block, nbytes);
2655
2656 if (mode == AP_MODE_EATCRLF || rc != APR_SUCCESS)
2657 return rc;
2658 }
2659
2660 while (!APR_BRIGADE_EMPTY(ctx->pbbTmp)) {
2661
2662 b_in = APR_BRIGADE_FIRST(ctx->pbbTmp);
2663
2664 if (APR_BUCKET_IS_EOS(b_in)) {
2665
2666 APR_BUCKET_REMOVE(b_in);
2667
2668 apr_pool_userdata_get((void**) &userdata_post_params,
2669 OIDC_USERDATA_POST_PARAMS_KEY, f->r->pool);
2670
2671 if (userdata_post_params != NULL) {
2672 buf = apr_psprintf(f->r->pool, "%s%s",
2673 ctx->nbytes > 0 ? "&" : "",
2674 oidc_util_http_form_encoded_data(f->r,
2675 userdata_post_params));
2676 b_out = apr_bucket_heap_create(buf, strlen(buf), 0,
2677 f->r->connection->bucket_alloc);
2678
2679 APR_BRIGADE_INSERT_TAIL(brigade, b_out);
2680
2681 ctx->nbytes += strlen(buf);
2682
2683 if (oidc_util_hdr_in_content_length_get(f->r) != NULL)
2684 oidc_util_hdr_in_set(f->r, OIDC_HTTP_HDR_CONTENT_LENGTH,
2685 apr_psprintf(f->r->pool, "%ld", ctx->nbytes));
2686
2687 apr_pool_userdata_set(NULL, OIDC_USERDATA_POST_PARAMS_KEY,
2688 NULL, f->r->pool);
2689 }
2690
2691 APR_BRIGADE_INSERT_TAIL(brigade, b_in);
2692
2693 break;
2694 }
2695
2696 APR_BUCKET_REMOVE(b_in);
2697 APR_BRIGADE_INSERT_TAIL(brigade, b_in);
2698 ctx->nbytes += b_in->length;
2699 }
2700
2701 return rc;
2702 }
2703
2704 /*
2705 * register our authentication and authorization functions
2706 */
oidc_register_hooks(apr_pool_t * pool)2707 void oidc_register_hooks(apr_pool_t *pool) {
2708 ap_hook_post_config(oidc_post_config, NULL, NULL, APR_HOOK_LAST);
2709 ap_hook_child_init(oidc_child_init, NULL, NULL, APR_HOOK_MIDDLE);
2710 ap_hook_handler(oidc_content_handler, NULL, NULL, APR_HOOK_FIRST);
2711 ap_hook_insert_filter(oidc_filter_in_insert_filter, NULL, NULL,
2712 APR_HOOK_MIDDLE);
2713 ap_register_input_filter(oidcFilterName, oidc_filter_in_filter, NULL,
2714 AP_FTYPE_RESOURCE);
2715 #if MODULE_MAGIC_NUMBER_MAJOR >= 20100714
2716 ap_hook_check_authn(oidc_check_user_id, NULL, NULL, APR_HOOK_MIDDLE,
2717 AP_AUTH_INTERNAL_PER_CONF);
2718 ap_register_auth_provider(pool, AUTHZ_PROVIDER_GROUP,
2719 OIDC_REQUIRE_CLAIM_NAME, "0", &oidc_authz_claim_provider,
2720 AP_AUTH_INTERNAL_PER_CONF);
2721 #ifdef USE_LIBJQ
2722 ap_register_auth_provider(pool, AUTHZ_PROVIDER_GROUP,
2723 OIDC_REQUIRE_CLAIMS_EXPR_NAME, "0",
2724 &oidc_authz_claims_expr_provider, AP_AUTH_INTERNAL_PER_CONF);
2725 #endif
2726 #else
2727 static const char * const authzSucc[] = {"mod_authz_user.c", NULL};
2728 ap_hook_check_user_id(oidc_check_user_id, NULL, NULL, APR_HOOK_MIDDLE);
2729 ap_hook_auth_checker(oidc_auth_checker, NULL, authzSucc, APR_HOOK_MIDDLE);
2730 #endif
2731 }
2732
2733 /*
2734 * set of configuration primitives
2735 */
2736 const command_rec oidc_config_cmds[] = {
2737
2738 AP_INIT_TAKE1(OIDCProviderMetadataURL,
2739 oidc_set_url_slot,
2740 (void*)APR_OFFSETOF(oidc_cfg, provider.metadata_url),
2741 RSRC_CONF,
2742 "OpenID Connect OP configuration metadata URL."),
2743 AP_INIT_TAKE1(OIDCProviderIssuer,
2744 oidc_set_string_slot,
2745 (void*)APR_OFFSETOF(oidc_cfg, provider.issuer),
2746 RSRC_CONF,
2747 "OpenID Connect OP issuer identifier."),
2748 AP_INIT_TAKE1(OIDCProviderAuthorizationEndpoint,
2749 oidc_set_https_slot,
2750 (void *)APR_OFFSETOF(oidc_cfg, provider.authorization_endpoint_url),
2751 RSRC_CONF,
2752 "Define the OpenID OP Authorization Endpoint URL (e.g.: https://localhost:9031/as/authorization.oauth2)"),
2753 AP_INIT_TAKE1(OIDCProviderTokenEndpoint,
2754 oidc_set_https_slot,
2755 (void *)APR_OFFSETOF(oidc_cfg, provider.token_endpoint_url),
2756 RSRC_CONF,
2757 "Define the OpenID OP Token Endpoint URL (e.g.: https://localhost:9031/as/token.oauth2)"),
2758 AP_INIT_TAKE1(OIDCProviderTokenEndpointAuth,
2759 oidc_set_endpoint_auth_slot,
2760 (void *)APR_OFFSETOF(oidc_cfg, provider.token_endpoint_auth),
2761 RSRC_CONF,
2762 "Specify an authentication method for the OpenID OP Token Endpoint (e.g.: client_secret_basic)"),
2763 AP_INIT_TAKE1(OIDCProviderTokenEndpointParams,
2764 oidc_set_string_slot,
2765 (void *)APR_OFFSETOF(oidc_cfg, provider.token_endpoint_params),
2766 RSRC_CONF,
2767 "Define extra parameters that will be posted to the OpenID OP Token Endpoint (e.g.: param1=value1¶m2=value2, all urlencoded)."),
2768 AP_INIT_TAKE1(OIDCProviderRegistrationEndpointJson,
2769 oidc_set_string_slot,
2770 (void *)APR_OFFSETOF(oidc_cfg, provider.registration_endpoint_json),
2771 RSRC_CONF,
2772 "Define a JSON object with parameters that will be merged into the client registration request to the OpenID OP Registration Endpoint (e.g.: { \"request_uris\" : [ \"https://example.com/uri\"] })."),
2773 AP_INIT_TAKE1(OIDCProviderUserInfoEndpoint,
2774 oidc_set_https_slot,
2775 (void *)APR_OFFSETOF(oidc_cfg, provider.userinfo_endpoint_url),
2776 RSRC_CONF,
2777 "Define the OpenID OP UserInfo Endpoint URL (e.g.: https://localhost:9031/idp/userinfo.openid)"),
2778 AP_INIT_TAKE1(OIDCProviderRevocationEndpoint,
2779 oidc_set_https_slot,
2780 (void *)APR_OFFSETOF(oidc_cfg, provider.revocation_endpoint_url),
2781 RSRC_CONF,
2782 "Define the RFC 7009 Token Revocation Endpoint URL (e.g.: https://localhost:9031/as/revoke_token.oauth2)"),
2783 AP_INIT_TAKE1(OIDCProviderCheckSessionIFrame,
2784 oidc_set_url_slot,
2785 (void *)APR_OFFSETOF(oidc_cfg, provider.check_session_iframe),
2786 RSRC_CONF,
2787 "Define the OpenID OP Check Session iFrame URL."),
2788 AP_INIT_TAKE1(OIDCProviderEndSessionEndpoint,
2789 oidc_set_url_slot,
2790 (void *)APR_OFFSETOF(oidc_cfg, provider.end_session_endpoint),
2791 RSRC_CONF,
2792 "Define the OpenID OP End Session Endpoint URL."),
2793 AP_INIT_FLAG(OIDCProviderBackChannelLogoutSupported,
2794 oidc_set_flag_slot,
2795 (void *)APR_OFFSETOF(oidc_cfg, provider.backchannel_logout_supported),
2796 RSRC_CONF,
2797 "Define whether the OP supports OpenID Connect Back Channel Logout."),
2798 AP_INIT_TAKE1(OIDCProviderJwksUri,
2799 oidc_set_https_slot,
2800 (void *)APR_OFFSETOF(oidc_cfg, provider.jwks_uri),
2801 RSRC_CONF,
2802 "Define the OpenID OP JWKS URL (e.g.: https://localhost:9031/pf/JWKS)"),
2803 AP_INIT_TAKE1(OIDCResponseType,
2804 oidc_set_response_type,
2805 (void *)APR_OFFSETOF(oidc_cfg, provider.response_type),
2806 RSRC_CONF,
2807 "The response type (or OpenID Connect Flow) used; must be one of \"code\", \"id_token\", \"id_token token\", \"code id_token\", \"code token\" or \"code id_token token\" (serves as default value for discovered OPs too)"),
2808 AP_INIT_TAKE1(OIDCResponseMode,
2809 oidc_set_response_mode,
2810 (void *)APR_OFFSETOF(oidc_cfg, provider.response_mode),
2811 RSRC_CONF,
2812 "The response mode used; must be one of \"fragment\", \"query\" or \"form_post\" (serves as default value for discovered OPs too)"),
2813
2814 AP_INIT_ITERATE(OIDCPublicKeyFiles,
2815 oidc_set_public_key_files,
2816 (void *)APR_OFFSETOF(oidc_cfg, public_keys),
2817 RSRC_CONF,
2818 "The fully qualified names of the files that contain the RSA public keys or X.509 certificates that contains the RSA public keys that can be used for signature validation or encryption by the OP."),
2819 AP_INIT_ITERATE(OIDCPrivateKeyFiles,
2820 oidc_set_private_key_files_enc,
2821 NULL,
2822 RSRC_CONF,
2823 "The fully qualified names of the files that contain the RSA private keys that can be used to decrypt content sent to us by the OP."),
2824
2825 AP_INIT_TAKE1(OIDCClientJwksUri,
2826 oidc_set_https_slot,
2827 (void *)APR_OFFSETOF(oidc_cfg, provider.client_jwks_uri),
2828 RSRC_CONF,
2829 "Define the Client JWKS URL (e.g.: https://localhost/protected/?jwks=rsa)"),
2830 AP_INIT_TAKE1(OIDCIDTokenSignedResponseAlg,
2831 oidc_set_signed_response_alg,
2832 (void *)APR_OFFSETOF(oidc_cfg, provider.id_token_signed_response_alg),
2833 RSRC_CONF,
2834 "The algorithm that the OP must use to sign the ID token."),
2835 AP_INIT_TAKE1(OIDCIDTokenEncryptedResponseAlg,
2836 oidc_set_encrypted_response_alg,
2837 (void *)APR_OFFSETOF(oidc_cfg, provider.id_token_encrypted_response_alg),
2838 RSRC_CONF,
2839 "The algorithm that the OP should use to encrypt the Content Encryption Key that is used to encrypt the id_token (used only in dynamic client registration); must be one of [RSA1_5|A128KW|A256KW|RSA-OAEP]"),
2840 AP_INIT_TAKE1(OIDCIDTokenEncryptedResponseEnc,
2841 oidc_set_encrypted_response_enc,
2842 (void *)APR_OFFSETOF(oidc_cfg, provider.id_token_encrypted_response_enc),
2843 RSRC_CONF,
2844 "The algorithm that the OP should use to encrypt to the id_token with the Content Encryption Key (used only in dynamic client registration); must be one of [A128CBC-HS256|A256CBC-HS512|A256GCM]"),
2845 AP_INIT_TAKE1(OIDCUserInfoSignedResponseAlg,
2846 oidc_set_signed_response_alg,
2847 (void *)APR_OFFSETOF(oidc_cfg, provider.userinfo_signed_response_alg),
2848 RSRC_CONF,
2849 "The algorithm that the OP should use to sign the UserInfo response (used only in dynamic client registration); must be one of [RS256|RS384|RS512|PS256|PS384|PS512|HS256|HS384|HS512]"),
2850 AP_INIT_TAKE1(OIDCUserInfoEncryptedResponseAlg,
2851 oidc_set_encrypted_response_alg,
2852 (void *)APR_OFFSETOF(oidc_cfg, provider.userinfo_encrypted_response_alg),
2853 RSRC_CONF,
2854 "The algorithm that the OP should use to encrypt the Content Encryption Key that is used to encrypt the UserInfo response (used only in dynamic client registration); must be one of [RSA1_5|A128KW|A256KW|RSA-OAEP]"),
2855 AP_INIT_TAKE1(OIDCUserInfoEncryptedResponseEnc,
2856 oidc_set_encrypted_response_enc,
2857 (void *)APR_OFFSETOF(oidc_cfg, provider.userinfo_encrypted_response_enc),
2858 RSRC_CONF,
2859 "The algorithm that the OP should use to encrypt to encrypt the UserInfo response with the Content Encryption Key (used only in dynamic client registration); must be one of [A128CBC-HS256|A256CBC-HS512|A256GCM]"),
2860 AP_INIT_TAKE1(OIDCUserInfoTokenMethod,
2861 oidc_set_userinfo_token_method,
2862 (void *)APR_OFFSETOF(oidc_cfg, provider.userinfo_token_method),
2863 RSRC_CONF,
2864 "The method that is used to present the access token to the userinfo endpoint; must be one of [authz_header|post_param]"),
2865 AP_INIT_TAKE1(OIDCTokenBindingPolicy,
2866 oidc_set_token_binding_policy,
2867 (void *)APR_OFFSETOF(oidc_cfg, provider.token_binding_policy),
2868 RSRC_CONF,
2869 "The token binding policy used with the provider; must be one of [disabled|optional|required|enforced]"),
2870
2871 AP_INIT_TAKE1(OIDCSSLValidateServer,
2872 oidc_set_ssl_validate_slot,
2873 (void*)APR_OFFSETOF(oidc_cfg, provider.ssl_validate_server),
2874 RSRC_CONF,
2875 "Require validation of the OpenID Connect OP SSL server certificate for successful authentication (On or Off)"),
2876 AP_INIT_TAKE1(OIDCValidateIssuer,
2877 oidc_set_validate_issuer_slot,
2878 (void*)APR_OFFSETOF(oidc_cfg, provider.validate_issuer),
2879 RSRC_CONF,
2880 "Require validation of token issuer for successful authentication (On or Off)"),
2881 AP_INIT_TAKE1(OIDCClientName,
2882 oidc_set_string_slot,
2883 (void *) APR_OFFSETOF(oidc_cfg, provider.client_name),
2884 RSRC_CONF,
2885 "Define the (client_name) name that the client uses for dynamic registration to the OP."),
2886 AP_INIT_TAKE1(OIDCClientContact,
2887 oidc_set_string_slot,
2888 (void *) APR_OFFSETOF(oidc_cfg, provider.client_contact),
2889 RSRC_CONF,
2890 "Define the contact that the client registers in dynamic registration with the OP."),
2891 AP_INIT_TAKE1(OIDCScope,
2892 oidc_set_string_slot,
2893 (void *) APR_OFFSETOF(oidc_cfg, provider.scope),
2894 RSRC_CONF,
2895 "Define the OpenID Connect scope that is requested from the OP."),
2896 AP_INIT_TAKE1(OIDCPathScope,
2897 ap_set_string_slot,
2898 (void*)APR_OFFSETOF(oidc_dir_cfg, path_scope),
2899 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
2900 "Define the OpenID Connect scope that is requested from all providers for a specific path/context."),
2901 AP_INIT_TAKE1(OIDCJWKSRefreshInterval,
2902 oidc_set_jwks_refresh_interval,
2903 (void*)APR_OFFSETOF(oidc_cfg, provider.jwks_refresh_interval),
2904 RSRC_CONF,
2905 "Duration in seconds after which retrieved JWS should be refreshed."),
2906 AP_INIT_TAKE1(OIDCIDTokenIatSlack,
2907 oidc_set_idtoken_iat_slack,
2908 (void*)APR_OFFSETOF(oidc_cfg, provider.idtoken_iat_slack),
2909 RSRC_CONF,
2910 "Acceptable offset (both before and after) for checking the \"iat\" (= issued at) timestamp in the id_token."),
2911 AP_INIT_TAKE1(OIDCSessionMaxDuration,
2912 oidc_set_session_max_duration,
2913 (void*)APR_OFFSETOF(oidc_cfg, provider.session_max_duration),
2914 RSRC_CONF,
2915 "Maximum duration of a session in seconds."),
2916 AP_INIT_TAKE1(OIDCAuthRequestParams,
2917 oidc_set_string_slot,
2918 (void*)APR_OFFSETOF(oidc_cfg, provider.auth_request_params),
2919 RSRC_CONF,
2920 "Extra parameters that need to be sent in the Authorization Request (must be query-encoded like \"display=popup&prompt=consent\"."),
2921 AP_INIT_TAKE1(OIDCPathAuthRequestParams,
2922 ap_set_string_slot,
2923 (void*)APR_OFFSETOF(oidc_dir_cfg, path_auth_request_params),
2924 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
2925 "Extra parameters that need to be sent in the Authorization Request (must be query-encoded like \"display=popup&prompt=consent\"."),
2926 AP_INIT_TAKE1(OIDCPKCEMethod,
2927 oidc_set_pkce_method,
2928 (void *)APR_OFFSETOF(oidc_cfg, provider.pkce),
2929 RSRC_CONF,
2930 "The RFC 7636 PCKE mode used; must be one of \"plain\", \"S256\" or \"referred_tb\""),
2931
2932 AP_INIT_TAKE1(OIDCClientID,
2933 oidc_set_string_slot,
2934 (void*)APR_OFFSETOF(oidc_cfg, provider.client_id),
2935 RSRC_CONF,
2936 "Client identifier used in calls to OpenID Connect OP."),
2937 AP_INIT_TAKE1(OIDCClientSecret,
2938 oidc_set_string_slot,
2939 (void*)APR_OFFSETOF(oidc_cfg, provider.client_secret),
2940 RSRC_CONF,
2941 "Client secret used in calls to OpenID Connect OP."),
2942
2943 AP_INIT_TAKE1(OIDCClientTokenEndpointCert,
2944 oidc_set_string_slot,
2945 (void*)APR_OFFSETOF(oidc_cfg, provider.token_endpoint_tls_client_cert),
2946 RSRC_CONF,
2947 "TLS client certificate used for calls to OpenID Connect OP token endpoint."),
2948 AP_INIT_TAKE1(OIDCClientTokenEndpointKey,
2949 oidc_set_string_slot,
2950 (void*)APR_OFFSETOF(oidc_cfg, provider.token_endpoint_tls_client_key),
2951 RSRC_CONF,
2952 "TLS client certificate private key used for calls to OpenID Connect OP token endpoint."),
2953
2954 AP_INIT_TAKE1(OIDCRedirectURI,
2955 oidc_set_relative_or_absolute_url_slot,
2956 (void *)APR_OFFSETOF(oidc_cfg, redirect_uri),
2957 RSRC_CONF,
2958 "Define the Redirect URI (e.g.: https://localhost:9031/protected/example/)"),
2959 AP_INIT_TAKE1(OIDCDefaultURL,
2960 oidc_set_url_slot,
2961 (void *)APR_OFFSETOF(oidc_cfg, default_sso_url),
2962 RSRC_CONF,
2963 "Defines the default URL where the user is directed to in case of 3rd-party initiated SSO."),
2964 AP_INIT_TAKE1(OIDCDefaultLoggedOutURL,
2965 oidc_set_url_slot,
2966 (void *)APR_OFFSETOF(oidc_cfg, default_slo_url),
2967 RSRC_CONF,
2968 "Defines the default URL where the user is directed to after logout."),
2969 AP_INIT_TAKE1(OIDCCookieDomain,
2970 oidc_set_cookie_domain,
2971 NULL,
2972 RSRC_CONF,
2973 "Specify domain element for OIDC session cookie."),
2974 AP_INIT_FLAG(OIDCCookieHTTPOnly,
2975 oidc_set_flag_slot,
2976 (void *) APR_OFFSETOF(oidc_cfg, cookie_http_only),
2977 RSRC_CONF,
2978 "Defines whether or not the cookie httponly flag is set on cookies."),
2979 AP_INIT_FLAG(OIDCCookieSameSite,
2980 oidc_set_flag_slot,
2981 (void *) APR_OFFSETOF(oidc_cfg, cookie_same_site),
2982 RSRC_CONF,
2983 "Defines whether or not the cookie Same-Site flag is set on cookies."),
2984 AP_INIT_TAKE1(OIDCOutgoingProxy,
2985 oidc_set_string_slot,
2986 (void*)APR_OFFSETOF(oidc_cfg, outgoing_proxy),
2987 RSRC_CONF,
2988 "Specify an outgoing proxy for your network (<host>[:<port>]."),
2989 AP_INIT_TAKE1(OIDCCryptoPassphrase,
2990 oidc_set_passphrase_slot,
2991 (void*)APR_OFFSETOF(oidc_cfg, crypto_passphrase),
2992 RSRC_CONF,
2993 "Passphrase used for AES crypto on cookies and state."),
2994 AP_INIT_TAKE1(OIDCClaimDelimiter,
2995 oidc_set_string_slot,
2996 (void*)APR_OFFSETOF(oidc_cfg, claim_delimiter),
2997 RSRC_CONF,
2998 "The delimiter to use when setting multi-valued claims in the HTTP headers."),
2999 AP_INIT_RAW_ARGS(OIDCClaimPrefix,
3000 oidc_cfg_set_claim_prefix,
3001 (void*)APR_OFFSETOF(oidc_cfg, claim_prefix),
3002 RSRC_CONF,
3003 "The prefix to use when setting claims in the HTTP headers."),
3004 AP_INIT_TAKE123(OIDCRemoteUserClaim,
3005 oidc_set_remote_user_claim,
3006 (void*)APR_OFFSETOF(oidc_cfg, remote_user_claim),
3007 RSRC_CONF,
3008 "The claim that is used when setting the REMOTE_USER variable for OpenID Connect protected paths."),
3009 AP_INIT_TAKE123(OIDCPassIDTokenAs,
3010 oidc_set_pass_idtoken_as,
3011 NULL,
3012 RSRC_CONF,
3013 "The format in which the id_token is passed in (a) header(s); must be one or more of: claims|payload|serialized"),
3014 AP_INIT_TAKE123(OIDCPassUserInfoAs,
3015 oidc_set_pass_userinfo_as,
3016 NULL,
3017 RSRC_CONF,
3018 "The format in which the userinfo is passed in (a) header(s); must be one or more of: claims|json|jwt"),
3019
3020 AP_INIT_TAKE1(OIDCOAuthClientID,
3021 oidc_set_string_slot,
3022 (void*)APR_OFFSETOF(oidc_cfg, oauth.client_id),
3023 RSRC_CONF,
3024 "Client identifier used in calls to OAuth 2.0 Authorization server validation calls."),
3025 AP_INIT_TAKE1(OIDCOAuthClientSecret,
3026 oidc_set_string_slot,
3027 (void*)APR_OFFSETOF(oidc_cfg, oauth.client_secret),
3028 RSRC_CONF,
3029 "Client secret used in calls to OAuth 2.0 Authorization server validation calls."),
3030
3031 AP_INIT_TAKE1(OIDCOAuthIntrospectionEndpoint,
3032 oidc_set_https_slot,
3033 (void *)APR_OFFSETOF(oidc_cfg, oauth.introspection_endpoint_url),
3034 RSRC_CONF,
3035 "Define the OAuth AS Introspection Endpoint URL (e.g.: https://localhost:9031/as/token.oauth2)"),
3036 AP_INIT_TAKE1(OIDCOAuthIntrospectionEndpointMethod,
3037 oidc_set_introspection_method,
3038 (void *)APR_OFFSETOF(oidc_cfg, oauth.introspection_endpoint_method),
3039 RSRC_CONF,
3040 "Define the HTTP method to use for the introspection call: one of \"GET\" or \"POST\" (default)"),
3041 AP_INIT_TAKE1(OIDCOAuthIntrospectionEndpointParams,
3042 oidc_set_string_slot,
3043 (void*)APR_OFFSETOF(oidc_cfg, oauth.introspection_endpoint_params),
3044 RSRC_CONF,
3045 "Extra parameters that need to be sent in the token introspection request (must be query-encoded like \"grant_type=urn%3Apingidentity.com%3Aoauth2%3Agrant_type%3Avalidate_bearer\"."),
3046
3047 AP_INIT_TAKE1(OIDCOAuthIntrospectionEndpointAuth,
3048 oidc_set_endpoint_auth_slot,
3049 (void *)APR_OFFSETOF(oidc_cfg, oauth.introspection_endpoint_auth),
3050 RSRC_CONF,
3051 "Specify an authentication method for the OAuth AS Introspection Endpoint (e.g.: client_secret_basic)"),
3052 AP_INIT_RAW_ARGS(OIDCOAuthIntrospectionClientAuthBearerToken,
3053 oidc_set_client_auth_bearer_token,
3054 NULL,
3055 RSRC_CONF,
3056 "Specify a bearer token to authorize against the OAuth AS Introspection Endpoint (e.g.: 55554ee-2491-11e3-be72-001fe2e44345 or empty to use the introspected token itself)"),
3057 AP_INIT_TAKE1(OIDCOAuthIntrospectionEndpointCert,
3058 oidc_set_string_slot,
3059 (void*)APR_OFFSETOF(oidc_cfg, oauth.introspection_endpoint_tls_client_cert),
3060 RSRC_CONF,
3061 "TLS client certificate used for calls to the OAuth 2.0 Authorization server introspection endpoint."),
3062 AP_INIT_TAKE1(OIDCOAuthIntrospectionEndpointKey,
3063 oidc_set_string_slot,
3064 (void*)APR_OFFSETOF(oidc_cfg, oauth.introspection_endpoint_tls_client_key),
3065 RSRC_CONF,
3066 "TLS client certificate private key used for calls to the OAuth 2.0 Authorization server introspection endpoint."),
3067
3068 AP_INIT_TAKE1(OIDCOAuthIntrospectionTokenParamName,
3069 oidc_set_string_slot,
3070 (void*)APR_OFFSETOF(oidc_cfg, oauth.introspection_token_param_name),
3071 RSRC_CONF,
3072 "Name of the parameter whose value carries the access token value in an validation request to the token introspection endpoint."),
3073 AP_INIT_TAKE123(OIDCOAuthTokenExpiryClaim,
3074 oidc_set_token_expiry_claim,
3075 NULL,
3076 RSRC_CONF,
3077 "Name of the claim that carries the token expiry value in the introspection result, optionally followed by absolute|relative, optionally followed by optional|mandatory"),
3078 AP_INIT_TAKE1(OIDCOAuthSSLValidateServer,
3079 oidc_set_ssl_validate_slot,
3080 (void*)APR_OFFSETOF(oidc_cfg, oauth.ssl_validate_server),
3081 RSRC_CONF,
3082 "Require validation of the OAuth 2.0 AS Validation Endpoint SSL server certificate for successful authentication (On or Off)"),
3083 AP_INIT_TAKE123(OIDCOAuthRemoteUserClaim,
3084 oidc_set_remote_user_claim,
3085 (void*)APR_OFFSETOF(oidc_cfg, oauth.remote_user_claim),
3086 RSRC_CONF,
3087 "The claim that is used when setting the REMOTE_USER variable for OAuth 2.0 protected paths."),
3088 AP_INIT_ITERATE(OIDCOAuthVerifyCertFiles,
3089 oidc_set_public_key_files,
3090 (void*)APR_OFFSETOF(oidc_cfg, oauth.verify_public_keys),
3091 RSRC_CONF,
3092 "The fully qualified names of the files that contain the X.509 certificates that contains the RSA public keys that can be used for access token validation."),
3093 AP_INIT_ITERATE(OIDCOAuthVerifySharedKeys,
3094 oidc_set_shared_keys,
3095 (void*)APR_OFFSETOF(oidc_cfg, oauth.verify_shared_keys),
3096 RSRC_CONF,
3097 "Shared secret(s) that is/are used to verify signed JWT access tokens locally."),
3098 AP_INIT_TAKE1(OIDCOAuthVerifyJwksUri,
3099 oidc_set_https_slot,
3100 (void *)APR_OFFSETOF(oidc_cfg, oauth.verify_jwks_uri),
3101 RSRC_CONF,
3102 "The JWKs URL on which the Authorization publishes the keys used to sign its JWT access tokens."),
3103
3104 AP_INIT_TAKE1(OIDCHTTPTimeoutLong,
3105 oidc_set_int_slot,
3106 (void*)APR_OFFSETOF(oidc_cfg, http_timeout_long),
3107 RSRC_CONF,
3108 "Timeout for long duration HTTP calls (default)."),
3109 AP_INIT_TAKE1(OIDCHTTPTimeoutShort,
3110 oidc_set_int_slot,
3111 (void*)APR_OFFSETOF(oidc_cfg, http_timeout_short),
3112 RSRC_CONF,
3113 "Timeout for short duration HTTP calls (registry/discovery)."),
3114 AP_INIT_TAKE1(OIDCStateTimeout,
3115 oidc_set_int_slot,
3116 (void*)APR_OFFSETOF(oidc_cfg, state_timeout),
3117 RSRC_CONF,
3118 "Time to live in seconds for state parameter (cq. interval in which the authorization request and the corresponding response need to be completed)."),
3119 AP_INIT_TAKE12(OIDCStateMaxNumberOfCookies,
3120 oidc_set_max_number_of_state_cookies,
3121 (void*)APR_OFFSETOF(oidc_cfg, max_number_of_state_cookies),
3122 RSRC_CONF,
3123 "Maximun number of parallel state cookies i.e. outstanding authorization requests and whether to delete the oldest cookie(s)."),
3124 AP_INIT_TAKE1(OIDCSessionInactivityTimeout,
3125 oidc_set_session_inactivity_timeout,
3126 (void*)APR_OFFSETOF(oidc_cfg, session_inactivity_timeout),
3127 RSRC_CONF,
3128 "Inactivity interval after which the session is invalidated when no interaction has occurred."),
3129
3130 AP_INIT_TAKE1(OIDCMetadataDir,
3131 oidc_set_dir_slot,
3132 (void*)APR_OFFSETOF(oidc_cfg, metadata_dir),
3133 RSRC_CONF,
3134 "Directory that contains provider and client metadata files."),
3135 AP_INIT_TAKE1(OIDCSessionType,
3136 oidc_set_session_type,
3137 (void*)APR_OFFSETOF(oidc_cfg, session_type),
3138 RSRC_CONF,
3139 "OpenID Connect session storage type (Apache 2.0/2.2 only). Must be one of \"server-cache\" or \"client-cookie\" with an optional suffix \":persistent\"."),
3140 AP_INIT_FLAG(OIDCSessionCacheFallbackToCookie,
3141 oidc_set_flag_slot,
3142 (void*)APR_OFFSETOF(oidc_cfg, session_cache_fallback_to_cookie),
3143 RSRC_CONF,
3144 "Fallback to client-side cookie session storage when server side cache fails."),
3145 AP_INIT_TAKE1(OIDCSessionCookieChunkSize,
3146 oidc_set_int_slot,
3147 (void*)APR_OFFSETOF(oidc_cfg, session_cookie_chunk_size),
3148 RSRC_CONF,
3149 "Chunk size for client-cookie session storage type in bytes. Defaults to 4k. Set 0 to suppress chunking."),
3150
3151 AP_INIT_TAKE1(OIDCCacheType,
3152 oidc_set_cache_type,
3153 (void*)APR_OFFSETOF(oidc_cfg, cache), RSRC_CONF,
3154 "Cache type; must be one of \"file\", \"memcache\" or \"shm\"."),
3155 AP_INIT_FLAG(OIDCCacheEncrypt,
3156 oidc_set_flag_slot,
3157 (void*)APR_OFFSETOF(oidc_cfg, cache_encrypt),
3158 RSRC_CONF,
3159 "Encrypt the data in the cache backend (On or Off)"),
3160 AP_INIT_TAKE1(OIDCCacheDir,
3161 oidc_set_dir_slot,
3162 (void*)APR_OFFSETOF(oidc_cfg, cache_file_dir),
3163 RSRC_CONF,
3164 "Directory used for file-based caching."),
3165 AP_INIT_TAKE1(OIDCCacheFileCleanInterval,
3166 oidc_set_int_slot,
3167 (void*)APR_OFFSETOF(oidc_cfg, cache_file_clean_interval),
3168 RSRC_CONF,
3169 "Cache file clean interval in seconds."),
3170 #ifdef USE_MEMCACHE
3171 AP_INIT_TAKE1(OIDCMemCacheServers,
3172 oidc_set_string_slot,
3173 (void*)APR_OFFSETOF(oidc_cfg, cache_memcache_servers),
3174 RSRC_CONF,
3175 "Memcache servers used for caching (space separated list of <hostname>[:<port>] tuples)"),
3176 #endif
3177 AP_INIT_TAKE1(OIDCCacheShmMax,
3178 oidc_set_int_slot,
3179 (void*)APR_OFFSETOF(oidc_cfg, cache_shm_size_max),
3180 RSRC_CONF,
3181 "Maximum number of cache entries to use for \"shm\" caching."),
3182 AP_INIT_TAKE1(OIDCCacheShmEntrySizeMax,
3183 oidc_set_cache_shm_entry_size_max,
3184 (void*)APR_OFFSETOF(oidc_cfg, cache_shm_entry_size_max),
3185 RSRC_CONF,
3186 "Maximum size of a single cache entry used for \"shm\" caching."),
3187 #ifdef USE_LIBHIREDIS
3188 AP_INIT_TAKE1(OIDCRedisCacheServer,
3189 oidc_set_string_slot,
3190 (void*)APR_OFFSETOF(oidc_cfg, cache_redis_server),
3191 RSRC_CONF,
3192 "Redis server used for caching (<hostname>[:<port>])"),
3193 AP_INIT_TAKE1(OIDCRedisCachePassword,
3194 oidc_set_string_slot,
3195 (void*)APR_OFFSETOF(oidc_cfg, cache_redis_password),
3196 RSRC_CONF,
3197 "Password for authentication to the Redis servers."),
3198 AP_INIT_TAKE1(OIDCRedisCacheDatabase,
3199 oidc_set_int_slot,
3200 (void*)APR_OFFSETOF(oidc_cfg, cache_redis_database),
3201 RSRC_CONF,
3202 "Database for the Redis servers."),
3203 #endif
3204 AP_INIT_TAKE1(OIDCHTMLErrorTemplate,
3205 oidc_set_string_slot,
3206 (void*)APR_OFFSETOF(oidc_cfg, error_template),
3207 RSRC_CONF,
3208 "Name of a HTML error template: needs to contain two \"%s\" characters, one for the error message, one for the description."),
3209
3210 AP_INIT_TAKE1(OIDCDiscoverURL,
3211 oidc_set_relative_or_absolute_url_slot_dir_cfg,
3212 (void *)APR_OFFSETOF(oidc_dir_cfg, discover_url),
3213 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3214 "Defines an external IDP Discovery page"),
3215 AP_INIT_ITERATE(OIDCPassCookies,
3216 oidc_set_cookie_names,
3217 (void *) APR_OFFSETOF(oidc_dir_cfg, pass_cookies),
3218 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3219 "Specify cookies that need to be passed from the browser on to the backend to the OP/AS."),
3220 AP_INIT_ITERATE(OIDCStripCookies,
3221 oidc_set_cookie_names,
3222 (void *) APR_OFFSETOF(oidc_dir_cfg, strip_cookies),
3223 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3224 "Specify cookies that should be stripped from the incoming request before passing it on to the backend."),
3225 AP_INIT_TAKE1(OIDCAuthNHeader,
3226 ap_set_string_slot,
3227 (void *) APR_OFFSETOF(oidc_dir_cfg, authn_header),
3228 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3229 "Specify the HTTP header variable to set with the name of the authenticated user. By default no explicit header is added but Apache's default REMOTE_USER will be set."),
3230 AP_INIT_TAKE1(OIDCCookiePath,
3231 ap_set_string_slot,
3232 (void *) APR_OFFSETOF(oidc_dir_cfg, cookie_path),
3233 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3234 "Define the cookie path for the session cookie."),
3235 AP_INIT_TAKE1(OIDCCookie,
3236 ap_set_string_slot,
3237 (void *) APR_OFFSETOF(oidc_dir_cfg, cookie),
3238 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3239 "Define the cookie name for the session cookie."),
3240 AP_INIT_TAKE12(OIDCUnAuthAction,
3241 oidc_set_unauth_action,
3242 (void *) APR_OFFSETOF(oidc_dir_cfg, unauth_action),
3243 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3244 "Sets the action taken when an unauthenticated request occurs: must be one of \"auth\" (default), \"pass\" , \"401\", \"407\", or \"410\"."),
3245 AP_INIT_TAKE1(OIDCUnAutzAction,
3246 oidc_set_unautz_action,
3247 (void *) APR_OFFSETOF(oidc_dir_cfg, unautz_action),
3248 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3249 "Sets the action taken when an unauthorized request occurs: must be one of \"401\" (default), \"403\" or \"auth\"."),
3250 AP_INIT_TAKE12(OIDCPassClaimsAs,
3251 oidc_set_pass_claims_as, NULL,
3252 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3253 "Specify how claims are passed to the application(s); must be one of \"none\", \"headers\", \"environment\" or \"both\" (default)."),
3254 AP_INIT_ITERATE(OIDCOAuthAcceptTokenAs,
3255 oidc_set_accept_oauth_token_in,
3256 NULL,
3257 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3258 "The method in which an OAuth token can be presented; must be one or more of: header|post|query|cookie"),
3259 AP_INIT_TAKE1(OIDCUserInfoRefreshInterval,
3260 oidc_set_userinfo_refresh_interval,
3261 (void*)APR_OFFSETOF(oidc_cfg, provider.userinfo_refresh_interval),
3262 RSRC_CONF,
3263 "Duration in seconds after which retrieved claims from the userinfo endpoint should be refreshed."),
3264 AP_INIT_TAKE1(OIDCOAuthTokenIntrospectionInterval,
3265 ap_set_int_slot,
3266 (void *) APR_OFFSETOF(oidc_dir_cfg, oauth_token_introspect_interval),
3267 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3268 "Sets the token introspection refresh interval."),
3269 AP_INIT_TAKE1(OIDCPreservePost,
3270 oidc_set_preserve_post,
3271 (void *) APR_OFFSETOF(oidc_dir_cfg, preserve_post),
3272 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3273 "Indicates whether POST parameters will be preserved across authentication requests."),
3274 AP_INIT_FLAG(OIDCPassRefreshToken,
3275 ap_set_flag_slot,
3276 (void*)APR_OFFSETOF(oidc_dir_cfg, pass_refresh_token),
3277 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3278 "Pass the refresh token in a header and/or environment variable (On or Off)"),
3279 AP_INIT_TAKE1(OIDCRequestObject,
3280 oidc_set_string_slot,
3281 (void *)APR_OFFSETOF(oidc_cfg, provider.request_object),
3282 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3283 "The default request object settings"),
3284 AP_INIT_TAKE1(OIDCProviderMetadataRefreshInterval,
3285 oidc_set_int_slot,
3286 (void*)APR_OFFSETOF(oidc_cfg, provider_metadata_refresh_interval),
3287 RSRC_CONF,
3288 "Provider metadata refresh interval in seconds."),
3289 AP_INIT_TAKE1(OIDCProviderAuthRequestMethod,
3290 oidc_set_auth_request_method,
3291 (void*)APR_OFFSETOF(oidc_cfg, provider.auth_request_method),
3292 RSRC_CONF,
3293 "HTTP method used to send the authentication request to the provider (GET or POST)."),
3294 AP_INIT_ITERATE(OIDCInfoHook,
3295 oidc_set_info_hook_data,
3296 (void *)APR_OFFSETOF(oidc_cfg, info_hook_data),
3297 RSRC_CONF,
3298 "The data that will be returned from the info hook."),
3299 AP_INIT_ITERATE(OIDCBlackListedClaims,
3300 oidc_set_filtered_claims,
3301 (void *) APR_OFFSETOF(oidc_cfg, black_listed_claims),
3302 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3303 "Specify claims that should be removed from the userinfo and/or id_token before storing them in the session."),
3304 AP_INIT_ITERATE(OIDCWhiteListedClaims,
3305 oidc_set_filtered_claims,
3306 (void *) APR_OFFSETOF(oidc_cfg, white_listed_claims),
3307 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3308 "Specify claims from the userinfo and/or id_token that should be stored in the session (all other claims will be discarded)."),
3309 AP_INIT_TAKE1(OIDCOAuthServerMetadataURL,
3310 oidc_set_url_slot,
3311 (void*)APR_OFFSETOF(oidc_cfg, oauth.metadata_url),
3312 RSRC_CONF,
3313 "Authorization Server metadata URL."),
3314 AP_INIT_TAKE1(OIDCOAuthAccessTokenBindingPolicy,
3315 oidc_set_token_binding_policy,
3316 (void *)APR_OFFSETOF(oidc_cfg, oauth.access_token_binding_policy),
3317 RSRC_CONF,
3318 "The token binding policy used for access tokens; must be one of [disabled|optional|required|enforced]"),
3319
3320 AP_INIT_TAKE12(OIDCRefreshAccessTokenBeforeExpiry,
3321 oidc_set_refresh_access_token_before_expiry,
3322 (void *)APR_OFFSETOF(oidc_dir_cfg, refresh_access_token_before_expiry),
3323 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3324 "Ensure the access token is valid for at least <x> seconds by refreshing it if required; must be: <x> [logout_on_error]; the logout_on_error performs a logout on refresh error."),
3325
3326 AP_INIT_TAKE1(OIDCStateInputHeaders,
3327 oidc_set_state_input_headers_as,
3328 NULL,
3329 RSRC_CONF,
3330 "Specify header name which is used as the input for calculating the fingerprint of the state during authentication; must be one of \"none\", \"user-agent\", \"x-forwarded-for\" or \"both\" (default)."),
3331
3332 AP_INIT_ITERATE(OIDCRedirectURLsAllowed,
3333 oidc_set_redirect_urls_allowed,
3334 (void *) APR_OFFSETOF(oidc_cfg, redirect_urls_allowed),
3335 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3336 "Specify one or more regular expressions that define URLs allowed for post logout and other redirects."),
3337
3338 AP_INIT_TAKE1(OIDCStateCookiePrefix,
3339 ap_set_string_slot,
3340 (void *) APR_OFFSETOF(oidc_dir_cfg, state_cookie_prefix),
3341 RSRC_CONF|ACCESS_CONF|OR_AUTHCFG,
3342 "Define the cookie prefix for the state cookie."),
3343
3344 AP_INIT_TAKE1(OIDCCABundlePath,
3345 oidc_set_path_slot,
3346 (void *) APR_OFFSETOF(oidc_cfg, ca_bundle_path),
3347 RSRC_CONF,
3348 "Sets the path to the CA bundle to be used by cURL."),
3349
3350 { NULL }
3351 };
3352