|
37 | 37 |
|
38 | 38 | #include <apr_strings.h> |
39 | 39 |
|
| 40 | +#include <mod_ssl.h> |
| 41 | + |
40 | 42 | OAUTH2_APACHE_LOG(oauth2) |
41 | 43 |
|
42 | 44 | // TODO: move the type into liboauth and use the Apache macro's (as in mod_sts)? |
@@ -85,6 +87,21 @@ static void *oauth2_cfg_dir_merge(apr_pool_t *pool, void *b, void *a) |
85 | 87 |
|
86 | 88 | #define OAUTH2_REQUEST_STATE_KEY_CLAIMS "C" |
87 | 89 |
|
| 90 | +APR_DECLARE_OPTIONAL_FN(int, ssl_is_https, (conn_rec *)); |
| 91 | +APR_DECLARE_OPTIONAL_FN(char *, ssl_var_lookup, |
| 92 | + (apr_pool_t *, server_rec *, conn_rec *, request_rec *, |
| 93 | + char *)); |
| 94 | + |
| 95 | +static APR_OPTIONAL_FN_TYPE(ssl_var_lookup) *oauth2_ssl_val = NULL; |
| 96 | + |
| 97 | +const char *oauth2_conn_ssl_val(apr_pool_t *p, server_rec *s, conn_rec *c, |
| 98 | + request_rec *r, const char *var) |
| 99 | +{ |
| 100 | + return (oauth2_ssl_val != NULL) |
| 101 | + ? (const char *)oauth2_ssl_val(p, s, c, r, (char *)var) |
| 102 | + : NULL; |
| 103 | +} |
| 104 | + |
88 | 105 | static int oauth2_request_handler(oauth2_cfg_source_token_t *cfg, |
89 | 106 | oauth2_cfg_token_verify_t *verify, |
90 | 107 | oauth2_cfg_target_pass_t *target_pass, |
@@ -112,8 +129,9 @@ static int oauth2_request_handler(oauth2_cfg_source_token_t *cfg, |
112 | 129 | goto end; |
113 | 130 | } |
114 | 131 |
|
115 | | - if (oauth2_token_verify(ctx->log, ctx->request, verify, source_token, |
116 | | - &json_token) == false) { |
| 132 | + if (oauth2_token_verify( |
| 133 | + ctx->log, ctx->request, verify, source_token, &json_token, |
| 134 | + &oauth2_apache_server_callback_funcs, ctx->r) == false) { |
117 | 135 | rv = oauth2_apache_return_www_authenticate( |
118 | 136 | cfg, ctx, HTTP_UNAUTHORIZED, OAUTH2_ERROR_INVALID_TOKEN, |
119 | 137 | "Token could not be verified."); |
@@ -180,6 +198,13 @@ static int oauth2_check_user_id_handler(request_rec *r) |
180 | 198 | "incoming request: \"%s?%s\" ap_is_initial_req=%d", |
181 | 199 | r->parsed_uri.path, r->args, ap_is_initial_req(r)); |
182 | 200 |
|
| 201 | + /* workaround because the SSL CGI env var push happens only in the fixup |
| 202 | + * handler */ |
| 203 | + const char *pem = oauth2_conn_ssl_val(r->pool, r->server, r->connection, |
| 204 | + r, "SSL_CLIENT_CERT"); |
| 205 | + oauth2_apache_server_callback_funcs.set(ctx->log, ctx->r, |
| 206 | + "SSL_CLIENT_CERT", pem); |
| 207 | + |
183 | 208 | if (strcasecmp((const char *)ap_auth_type(r), OAUTH2_AUTH_TYPE) == 0) |
184 | 209 | return oauth2_request_handler(cfg->source_token, cfg->verify, |
185 | 210 | cfg->target_pass, ctx, true); |
@@ -244,16 +269,24 @@ static const authz_provider oauth2_authz_claim_provider = { |
244 | 269 |
|
245 | 270 | OAUTH2_APACHE_HANDLERS(oauth2) |
246 | 271 |
|
| 272 | +static apr_status_t oauth2_post_config_wrap(apr_pool_t *pool, apr_pool_t *p1, |
| 273 | + apr_pool_t *p2, server_rec *s) |
| 274 | +{ |
| 275 | + oauth2_ssl_val = APR_RETRIEVE_OPTIONAL_FN(ssl_var_lookup); |
| 276 | + return OAUTH2_APACHE_POST_CONFIG(oauth2)(pool, p1, p2, s); |
| 277 | +} |
| 278 | + |
247 | 279 | static void oauth2_register_hooks(apr_pool_t *p) |
248 | 280 | { |
249 | | - ap_hook_post_config(OAUTH2_APACHE_POST_CONFIG(oauth2), NULL, NULL, |
| 281 | + ap_hook_post_config(oauth2_post_config_wrap, NULL, NULL, |
250 | 282 | APR_HOOK_MIDDLE); |
251 | | - static const char * const authzSucc[] = {"mod_auth_openidc.c", NULL}; |
| 283 | + static const char *const authzSucc[] = {"mod_auth_openidc.c", NULL}; |
252 | 284 | ap_hook_check_authn(oauth2_check_user_id_handler, NULL, authzSucc, |
253 | 285 | APR_HOOK_MIDDLE, AP_AUTH_INTERNAL_PER_CONF); |
254 | 286 | ap_register_auth_provider( |
255 | 287 | p, AUTHZ_PROVIDER_GROUP, OAUTH2_REQUIRE_OAUTH2_CLAIM, "0", |
256 | 288 | &oauth2_authz_claim_provider, AP_AUTH_INTERNAL_PER_CONF); |
| 289 | + |
257 | 290 | // TODO: register content handler for "special" stuff like returning the |
258 | 291 | // JWKs that |
259 | 292 | // the peer may use to encrypt the token and the private key |
|
0 commit comments