Script 'mail_helper' called by obssrc Hello community, here is the log from the commit of package apache2-mod_auth_openidc for openSUSE:Factory checked in at 2022-08-24 15:10:56 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Comparing /work/SRC/openSUSE:Factory/apache2-mod_auth_openidc (Old) and /work/SRC/openSUSE:Factory/.apache2-mod_auth_openidc.new.2083 (New) ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Package is "apache2-mod_auth_openidc" Wed Aug 24 15:10:56 2022 rev:25 rq:998851 version:2.4.11.3 Changes: -------- --- /work/SRC/openSUSE:Factory/apache2-mod_auth_openidc/apache2-mod_auth_openidc.changes 2022-07-28 20:59:41.091760191 +0200 +++ /work/SRC/openSUSE:Factory/.apache2-mod_auth_openidc.new.2083/apache2-mod_auth_openidc.changes 2022-08-24 15:11:12.044506698 +0200 @@ -1,0 +2,14 @@ +Tue Aug 23 13:51:51 UTC 2022 - Michael Str??der <mich...@stroeder.com> + +- update to 2.4.11.3 + * Bugfixes + - avoid memory leak when using PCRE2 regular expressions with + array matching; closes #902 + - avoid memory leak when cjose_jws_get_plaintext fails; closes #903 + - fix handling of IPv6 based logout URLs + * Features + - Use optionally provided sid and iss request parameters during + front channel logout; see #855 + - support Forwarded header in addition to X-Forwarded-*; see #853 + +------------------------------------------------------------------- Old: ---- mod_auth_openidc-2.4.11.2.tar.gz New: ---- mod_auth_openidc-2.4.11.3.tar.gz ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ Other differences: ------------------ ++++++ apache2-mod_auth_openidc.spec ++++++ --- /var/tmp/diff_new_pack.LAxFv2/_old 2022-08-24 15:11:12.524507162 +0200 +++ /var/tmp/diff_new_pack.LAxFv2/_new 2022-08-24 15:11:12.532507170 +0200 @@ -17,7 +17,7 @@ Name: apache2-mod_auth_openidc -Version: 2.4.11.2 +Version: 2.4.11.3 Release: 0 Summary: Apache2.x module for an OpenID Connect enabled Identity Provider License: Apache-2.0 ++++++ mod_auth_openidc-2.4.11.2.tar.gz -> mod_auth_openidc-2.4.11.3.tar.gz ++++++ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/AUTHORS new/mod_auth_openidc-2.4.11.3/AUTHORS --- old/mod_auth_openidc-2.4.11.2/AUTHORS 2022-04-22 19:17:17.000000000 +0200 +++ new/mod_auth_openidc-2.4.11.3/AUTHORS 2022-08-22 12:50:22.000000000 +0200 @@ -83,3 +83,4 @@ Daan Bakker <https://github.com/dbakker> smanolache <https://github.com/smanolache> blackwhiser1 <https://github.com/blackwhiser1> + Ruediger Pluem <https://github.com/rpluem-vf> diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/ChangeLog new/mod_auth_openidc-2.4.11.3/ChangeLog --- old/mod_auth_openidc-2.4.11.2/ChangeLog 2022-05-05 09:42:54.000000000 +0200 +++ new/mod_auth_openidc-2.4.11.3/ChangeLog 2022-08-23 12:56:31.000000000 +0200 @@ -1,3 +1,23 @@ +08/22/2022 +- release 2.4.11.3 + +08/15/2022 +- avoid memory leak when using PCRE2 regular expressions with array matching; closes #902; thanks @smanolache +- avoid memory leak when cjose_jws_get_plaintext fails; closes #903; thanks @smanolache +- bump to 2.4.11.3rc4 + +05/20/2022 +- fix handling of IPv6 based logout URLs; thanks @@codemaker219 +- bump to 2.4.11.3rc1 + +05/16/2022 +- Use optionally provided sid and iss request parameters during front channel + logout; see #855; thanks @rpluem-vf + +05/06/2022 +- support Forwarded header in addition to X-Forwarded-*; see #853; thanks @studersi +- bump to 2.4.11.3rc0 + 05/05/2022 - release 2.4.11.2 diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/auth_openidc.conf new/mod_auth_openidc-2.4.11.3/auth_openidc.conf --- old/mod_auth_openidc-2.4.11.2/auth_openidc.conf 2022-05-03 22:21:07.000000000 +0200 +++ new/mod_auth_openidc-2.4.11.3/auth_openidc.conf 2022-08-22 12:50:22.000000000 +0200 @@ -944,9 +944,9 @@ # other redirects such as the "return_to" value on refresh token requests, the "login_uri" value # on session management based logins through the OP iframe, and the "target_link_uri" parameter in # 3rd-party initiated logins, e.g.: -# OIDCRedirectURLsAllowed ^https://www.example.com ^https://(\w+).example.org ^https://example.net/app +# OIDCRedirectURLsAllowed ^https://www\.example\.com ^https://(\w+)\.example\.org ^https://example\.net/app # or: -# OIDCRedirectURLsAllowed ^https://www.example.com/logout$ ^https://www.example.com/app/return_to$ +# OIDCRedirectURLsAllowed ^https://www\.example\.com/logout$ ^https://www\.example\.com/app/return_to$ # When not defined, the default is to match the hostname in the URL redirected to against # the hostname in the current request. #OIDCRedirectURLsAllowed [<regexp>]+ @@ -960,10 +960,11 @@ # When not defined the default is "DENY". #OIDCLogoutXFrameOptions <value> -# Define the X-Forwarded-* headers that will be taken into account as set by a reverse proxy +# Define the X-Forwarded-* or Forwarded headers that will be taken into account as set by a reverse proxy # in front of mod_auth_openidc. Must be one or more of: # X-Forwarded-Host # X-Forwarded-Port # X-Forwarded-Proto +# Forwarded # When not defined, such headers will be ignored. #OIDCXForwardedHeaders <header>+ diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/configure new/mod_auth_openidc-2.4.11.3/configure --- old/mod_auth_openidc-2.4.11.2/configure 2022-05-05 09:43:13.000000000 +0200 +++ new/mod_auth_openidc-2.4.11.3/configure 2022-08-23 12:58:11.000000000 +0200 @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for mod_auth_openidc 2.4.11.2. +# Generated by GNU Autoconf 2.71 for mod_auth_openidc 2.4.11.3. # # Report bugs to <hans.zandb...@zmartzone.eu>. # @@ -621,8 +621,8 @@ # Identity of this package. PACKAGE_NAME='mod_auth_openidc' PACKAGE_TARNAME='mod_auth_openidc' -PACKAGE_VERSION='2.4.11.2' -PACKAGE_STRING='mod_auth_openidc 2.4.11.2' +PACKAGE_VERSION='2.4.11.3' +PACKAGE_STRING='mod_auth_openidc 2.4.11.3' PACKAGE_BUGREPORT='hans.zandb...@zmartzone.eu' PACKAGE_URL='' @@ -1406,7 +1406,7 @@ # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures mod_auth_openidc 2.4.11.2 to adapt to many kinds of systems. +\`configure' configures mod_auth_openidc 2.4.11.3 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1478,7 +1478,7 @@ if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of mod_auth_openidc 2.4.11.2:";; + short | recursive ) echo "Configuration of mod_auth_openidc 2.4.11.3:";; esac cat <<\_ACEOF @@ -1620,7 +1620,7 @@ test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -mod_auth_openidc configure 2.4.11.2 +mod_auth_openidc configure 2.4.11.3 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -1838,7 +1838,7 @@ This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by mod_auth_openidc $as_me 2.4.11.2, which was +It was created by mod_auth_openidc $as_me 2.4.11.3, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -2594,7 +2594,7 @@ -NAMEVER=mod_auth_openidc-2.4.11.2 +NAMEVER=mod_auth_openidc-2.4.11.3 am__api_version='1.16' @@ -3111,7 +3111,7 @@ # Define the identity of the package. PACKAGE='mod_auth_openidc' - VERSION='2.4.11.2' + VERSION='2.4.11.3' printf "%s\n" "#define PACKAGE \"$PACKAGE\"" >>confdefs.h @@ -14594,7 +14594,7 @@ # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by mod_auth_openidc $as_me 2.4.11.2, which was +This file was extended by mod_auth_openidc $as_me 2.4.11.3, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -14662,7 +14662,7 @@ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -mod_auth_openidc config.status 2.4.11.2 +mod_auth_openidc config.status 2.4.11.3 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/configure.ac new/mod_auth_openidc-2.4.11.3/configure.ac --- old/mod_auth_openidc-2.4.11.2/configure.ac 2022-05-05 09:43:01.000000000 +0200 +++ new/mod_auth_openidc-2.4.11.3/configure.ac 2022-08-23 12:56:44.000000000 +0200 @@ -1,4 +1,4 @@ -AC_INIT([mod_auth_openidc],[2.4.11.2],[hans.zandb...@zmartzone.eu]) +AC_INIT([mod_auth_openidc],[2.4.11.3],[hans.zandb...@zmartzone.eu]) AC_SUBST(NAMEVER, AC_PACKAGE_TARNAME()-AC_PACKAGE_VERSION()) diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/src/authz.c new/mod_auth_openidc-2.4.11.3/src/authz.c --- old/mod_auth_openidc-2.4.11.2/src/authz.c 2022-03-21 19:31:03.000000000 +0100 +++ new/mod_auth_openidc-2.4.11.3/src/authz.c 2022-08-22 12:50:22.000000000 +0200 @@ -165,6 +165,7 @@ rc = TRUE; goto end; } else if (error_str) { + oidc_pcre_free_match(preg); oidc_debug(r, "pcre error (array): %s", error_str); } } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/src/config.c new/mod_auth_openidc-2.4.11.3/src/config.c --- old/mod_auth_openidc-2.4.11.2/src/config.c 2022-05-04 09:41:48.000000000 +0200 +++ new/mod_auth_openidc-2.4.11.3/src/config.c 2022-08-22 12:50:22.000000000 +0200 @@ -1294,6 +1294,7 @@ oidc_check_x_forwarded_hdr(r, x_forwarded_headers, OIDC_HDR_X_FORWARDED_HOST, OIDC_HTTP_HDR_X_FORWARDED_HOST, oidc_util_hdr_in_x_forwarded_host_get); oidc_check_x_forwarded_hdr(r, x_forwarded_headers, OIDC_HDR_X_FORWARDED_PORT, OIDC_HTTP_HDR_X_FORWARDED_PORT, oidc_util_hdr_in_x_forwarded_port_get); oidc_check_x_forwarded_hdr(r, x_forwarded_headers, OIDC_HDR_X_FORWARDED_PROTO, OIDC_HTTP_HDR_X_FORWARDED_PROTO, oidc_util_hdr_in_x_forwarded_proto_get); + oidc_check_x_forwarded_hdr(r, x_forwarded_headers, OIDC_HDR_FORWARDED, OIDC_HTTP_HDR_FORWARDED, oidc_util_hdr_in_forwarded_get); } static const char* oidc_set_redirect_urls_allowed(cmd_parms *cmd, void *m, diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/src/jose.c new/mod_auth_openidc-2.4.11.3/src/jose.c --- old/mod_auth_openidc-2.4.11.2/src/jose.c 2022-03-23 18:12:08.000000000 +0100 +++ new/mod_auth_openidc-2.4.11.3/src/jose.c 2022-08-22 12:50:22.000000000 +0200 @@ -835,6 +835,8 @@ size_t plaintext_len = 0; if (cjose_jws_get_plaintext(jwt->cjose_jws, &plaintext, &plaintext_len, &cjose_err) == FALSE) { + oidc_jwt_destroy(jwt); + *j_jwt = NULL; oidc_jose_error(err, "cjose_jws_get_plaintext failed: %s", oidc_cjose_e2s(pool, cjose_err)); return FALSE; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/src/mod_auth_openidc.c new/mod_auth_openidc-2.4.11.3/src/mod_auth_openidc.c --- old/mod_auth_openidc-2.4.11.2/src/mod_auth_openidc.c 2022-04-22 19:15:28.000000000 +0200 +++ new/mod_auth_openidc-2.4.11.3/src/mod_auth_openidc.c 2022-08-22 12:50:22.000000000 +0200 @@ -1776,13 +1776,18 @@ char *sid = NULL; oidc_debug(r, "provider->backchannel_logout_supported=%d", provider->backchannel_logout_supported); - if (provider->backchannel_logout_supported > 0) { - oidc_jose_get_string(r->pool, id_token_jwt->payload.value.json, - OIDC_CLAIM_SID, FALSE, &sid, NULL); - if (sid == NULL) - sid = id_token_jwt->payload.sub; - session->sid = oidc_make_sid_iss_unique(r, sid, provider->issuer); - } + /* + * Storing the sid in the session makes sense even if no backchannel logout + * is supported as the front channel logout as specified in + * "OpenID Connect Front-Channel Logout 1.0 - draft 05" at + * https://openid.net/specs/openid-connect-frontchannel-1_0.html + * might deliver a sid during front channel logout. + */ + oidc_jose_get_string(r->pool, id_token_jwt->payload.value.json, + OIDC_CLAIM_SID, FALSE, &sid, NULL); + if (sid == NULL) + sid = id_token_jwt->payload.sub; + session->sid = oidc_make_sid_iss_unique(r, sid, provider->issuer); /* store the session */ return oidc_session_save(r, session, TRUE); @@ -2450,6 +2455,7 @@ apr_hash_index_t *hi = NULL; size_t i = 0; char *url = apr_pstrndup(r->pool, redirect_to_url, OIDC_MAX_URL_LENGTH); + char *url_ipv6_aware = NULL; // replace potentially harmful backslashes with forward slashes for (i = 0; i < strlen(url); i++) @@ -2482,8 +2488,15 @@ } } else if ((uri.hostname != NULL) && (restrict_to_host == TRUE)) { c_host = oidc_get_current_url_host(r, c->x_forwarded_headers); - if ((strstr(c_host, uri.hostname) == NULL) - || (strstr(uri.hostname, c_host) == NULL)) { + + if (strchr(uri.hostname, ':')) { /* v6 literal */ + url_ipv6_aware = apr_pstrcat(r->pool, "[", uri.hostname, "]", NULL); + } else { + url_ipv6_aware = uri.hostname; + } + + if ((strstr(c_host, url_ipv6_aware) == NULL) + || (strstr(url_ipv6_aware, c_host) == NULL)) { *err_str = apr_pstrdup(r->pool, "Invalid Request"); *err_desc = apr_psprintf(r->pool, @@ -2787,17 +2800,62 @@ oidc_debug(r, "leave"); } +static apr_byte_t oidc_cleanup_by_sid(request_rec *r, char *sid, oidc_cfg *cfg, + oidc_provider_t *provider) { + + char *uuid = NULL; + oidc_session_t session; + + oidc_debug(r, "enter (sid=%s,iss=%s)", sid, provider->issuer); + + // TODO: when dealing with sub instead of a true sid, we'll be killing all sessions for + // a specific user, across hosts that share the *same* cache backend + // if those hosts haven't been configured with a different OIDCCryptoPassphrase + // - perhaps that's even acceptable since non-memory caching is encrypted by default + // and memory-based caching doesn't suffer from this (different shm segments)? + // - it will result in 400 errors returned from backchannel logout calls to the other hosts... + + sid = oidc_make_sid_iss_unique(r, sid, provider->issuer); + oidc_cache_get_sid(r, sid, &uuid); + if (uuid == NULL) { + // this may happen when we are the caller + oidc_warn(r, + "could not (or no longer) find a session based on sid/sub provided in logout token / parameter: %s", + sid); + r->user = ""; + return TRUE; + } + + // revoke tokens if we can get a handle on those + if (cfg->session_type != OIDC_SESSION_TYPE_CLIENT_COOKIE) { + if (oidc_session_load_cache_by_uuid(r, cfg, uuid, &session) != FALSE) + if (oidc_session_extract(r, &session) != FALSE) + oidc_revoke_tokens(r, cfg, &session); + } + + // clear the session cache + oidc_cache_set_sid(r, sid, NULL, 0); + oidc_cache_set_session(r, uuid, NULL, 0); + + r->user = ""; + return FALSE; +} + /* * handle a local logout */ static int oidc_handle_logout_request(request_rec *r, oidc_cfg *c, oidc_session_t *session, const char *url) { + int no_session_provided = 1; + oidc_debug(r, "enter (url=%s)", url); /* if there's no remote_user then there's no (stored) session to kill */ - if (session->remote_user != NULL) + if (session->remote_user != NULL) { + no_session_provided = 0; oidc_revoke_tokens(r, c, session); + } /* * remove session state (cq. cache entry and cookie) @@ -2809,6 +2867,42 @@ /* see if this is the OP calling us */ if (oidc_is_front_channel_logout(url)) { + /* + * If no session was provided look for the sid and iss parameters in + * the request as specified in + * "OpenID Connect Front-Channel Logout 1.0 - draft 05" at + * https://openid.net/specs/openid-connect-frontchannel-1_0.html + * and try to clear the session based on sid / iss like in the + * backchannel logout case. + */ + if (no_session_provided) { + char *sid, *iss; + oidc_provider_t *provider = NULL; + + if (oidc_util_get_request_parameter(r, OIDC_REDIRECT_URI_REQUEST_SID, + &sid) != FALSE) { + + if (oidc_util_get_request_parameter(r, OIDC_REDIRECT_URI_REQUEST_ISS, + &iss) != FALSE) { + provider = oidc_get_provider_for_issuer(r, c, iss, FALSE); + } else { + /* + * Azure AD seems to such a non spec compliant provider. + * In this case try our luck with the static config if + * possible. + */ + oidc_debug(r, "OP did not provide an iss as parameter"); + if (oidc_provider_static_config(r, c, &provider) == FALSE) + provider = NULL; + } + if (provider) { + oidc_cleanup_by_sid(r, sid, c, provider); + } else { + oidc_info(r, "No provider for front channel logout found"); + } + } + } + /* set recommended cache control headers */ oidc_util_hdr_err_out_add(r, OIDC_HTTP_HDR_CACHE_CONTROL, "no-cache, no-store"); @@ -2861,8 +2955,7 @@ oidc_jose_error_t err; oidc_jwk_t *jwk = NULL; oidc_provider_t *provider = NULL; - char *sid = NULL, *uuid = NULL; - oidc_session_t session; + char *sid = NULL; int rc = HTTP_BAD_REQUEST; apr_table_t *params = apr_table_make(r->pool, 8); @@ -2997,37 +3090,8 @@ goto out; } - // TODO: when dealing with sub instead of a true sid, we'll be killing all sessions for - // a specific user, across hosts that share the *same* cache backend - // if those hosts haven't been configured with a different OIDCCryptoPassphrase - // - perhaps that's even acceptable since non-memory caching is encrypted by default - // and memory-based caching doesn't suffer from this (different shm segments)? - // - it will result in 400 errors returned from backchannel logout calls to the other hosts... - - sid = oidc_make_sid_iss_unique(r, sid, provider->issuer); - oidc_cache_get_sid(r, sid, &uuid); - if (uuid == NULL) { - // this may happen when we are the caller - oidc_warn(r, - "could not (or no longer) find a session based on sid/sub provided in logout token: %s", - sid); - r->user = ""; - rc = OK; - goto out; - } - - // revoke tokens if we can get a handle on those - if (cfg->session_type != OIDC_SESSION_TYPE_CLIENT_COOKIE) { - if (oidc_session_load_cache_by_uuid(r, cfg, uuid, &session) != FALSE) - if (oidc_session_extract(r, &session) != FALSE) - oidc_revoke_tokens(r, cfg, &session); - } - - // clear the session cache - oidc_cache_set_sid(r, sid, NULL, 0); - oidc_cache_set_session(r, uuid, NULL, 0); + oidc_cleanup_by_sid(r, sid, cfg, provider); - r->user = ""; rc = OK; out: diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/src/mod_auth_openidc.h new/mod_auth_openidc-2.4.11.3/src/mod_auth_openidc.h --- old/mod_auth_openidc-2.4.11.2/src/mod_auth_openidc.h 2022-05-04 13:09:46.000000000 +0200 +++ new/mod_auth_openidc-2.4.11.3/src/mod_auth_openidc.h 2022-08-22 12:50:22.000000000 +0200 @@ -253,6 +253,7 @@ #define OIDC_HDR_X_FORWARDED_HOST 1 #define OIDC_HDR_X_FORWARDED_PORT 2 #define OIDC_HDR_X_FORWARDED_PROTO 4 +#define OIDC_HDR_FORWARDED 8 typedef apr_byte_t (*oidc_proto_pkce_state)(request_rec *r, char **state); typedef apr_byte_t (*oidc_proto_pkce_challenge)(request_rec *r, const char *state, char **code_challenge); @@ -481,6 +482,8 @@ #define OIDC_REDIRECT_URI_REQUEST_REMOVE_AT_CACHE "remove_at_cache" #define OIDC_REDIRECT_URI_REQUEST_REVOKE_SESSION "revoke_session" #define OIDC_REDIRECT_URI_REQUEST_REQUEST_URI "request_uri" +#define OIDC_REDIRECT_URI_REQUEST_SID "sid" +#define OIDC_REDIRECT_URI_REQUEST_ISS "iss" // oidc_oauth int oidc_oauth_check_userid(request_rec *r, oidc_cfg *c, const char *access_token); @@ -843,6 +846,7 @@ #define OIDC_HTTP_HDR_X_FORWARDED_PROTO "X-Forwarded-Proto" #define OIDC_HTTP_HDR_X_FORWARDED_PORT "X-Forwarded-Port" #define OIDC_HTTP_HDR_X_FORWARDED_HOST "X-Forwarded-Host" +#define OIDC_HTTP_HDR_FORWARDED "Forwarded" #define OIDC_HTTP_HDR_HOST "Host" #define OIDC_HTTP_HDR_LOCATION "Location" #define OIDC_HTTP_HDR_CACHE_CONTROL "Cache-Control" @@ -872,6 +876,7 @@ const char *oidc_util_hdr_in_x_forwarded_proto_get(const request_rec *r); const char *oidc_util_hdr_in_x_forwarded_port_get(const request_rec *r); const char *oidc_util_hdr_in_x_forwarded_host_get(const request_rec *r); +const char* oidc_util_hdr_in_forwarded_get(const request_rec *r); const char *oidc_util_hdr_in_host_get(const request_rec *r); void oidc_util_hdr_out_location_set(const request_rec *r, const char *value); const char *oidc_util_hdr_out_location_get(const request_rec *r); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/src/parse.c new/mod_auth_openidc-2.4.11.3/src/parse.c --- old/mod_auth_openidc-2.4.11.2/src/parse.c 2022-03-29 20:39:43.000000000 +0200 +++ new/mod_auth_openidc-2.4.11.3/src/parse.c 2022-08-22 12:50:22.000000000 +0200 @@ -1362,6 +1362,7 @@ OIDC_HTTP_HDR_X_FORWARDED_HOST, OIDC_HTTP_HDR_X_FORWARDED_PORT, OIDC_HTTP_HDR_X_FORWARDED_PROTO, + OIDC_HTTP_HDR_FORWARDED, NULL }; const char *rv = oidc_valid_string_option(pool, arg, options); if (rv != NULL) @@ -1373,6 +1374,8 @@ *x_forwarded_headers |= OIDC_HDR_X_FORWARDED_PORT; } else if (apr_strnatcmp(arg, OIDC_HTTP_HDR_X_FORWARDED_PROTO) == 0) { *x_forwarded_headers |= OIDC_HDR_X_FORWARDED_PROTO; + } else if (apr_strnatcmp(arg, OIDC_HTTP_HDR_FORWARDED) == 0) { + *x_forwarded_headers |= OIDC_HDR_FORWARDED; } return NULL; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/src/pcre_subst.c new/mod_auth_openidc-2.4.11.3/src/pcre_subst.c --- old/mod_auth_openidc-2.4.11.2/src/pcre_subst.c 2022-03-21 19:31:03.000000000 +0100 +++ new/mod_auth_openidc-2.4.11.3/src/pcre_subst.c 2022-08-22 12:50:22.000000000 +0200 @@ -236,6 +236,15 @@ #endif } +void oidc_pcre_free_match(struct oidc_pcre *pcre) { +#ifdef HAVE_LIBPCRE2 + if (pcre->match_data) { + pcre2_match_data_free(pcre->match_data); + pcre->match_data = NULL; + } +#endif +} + int oidc_pcre_get_substring(apr_pool_t *pool, const struct oidc_pcre *pcre, const char *input, int rc, char **sub_str, char **error_str) { int rv = 0; diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/src/pcre_subst.h new/mod_auth_openidc-2.4.11.3/src/pcre_subst.h --- old/mod_auth_openidc-2.4.11.2/src/pcre_subst.h 2022-03-21 19:31:03.000000000 +0100 +++ new/mod_auth_openidc-2.4.11.3/src/pcre_subst.h 2022-08-22 12:50:22.000000000 +0200 @@ -47,6 +47,7 @@ char* oidc_pcre_subst(apr_pool_t *pool, const struct oidc_pcre*, const char*, int, const char*); int oidc_pcre_exec(apr_pool_t*, struct oidc_pcre*, const char*, int, char**); void oidc_pcre_free(struct oidc_pcre*); +void oidc_pcre_free_match(struct oidc_pcre*); int oidc_pcre_get_substring(apr_pool_t *pool, const struct oidc_pcre*, const char *input, int rc, char **sub_str, char **error_str); diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/src/util.c new/mod_auth_openidc-2.4.11.3/src/util.c --- old/mod_auth_openidc-2.4.11.2/src/util.c 2022-03-29 20:39:33.000000000 +0200 +++ new/mod_auth_openidc-2.4.11.3/src/util.c 2022-08-22 12:50:22.000000000 +0200 @@ -434,6 +434,23 @@ return output; } +static const char* oidc_util_hdr_forwarded_get(const request_rec *r, const char *elem) { + const char *value = NULL; + char *ptr = NULL; + const char *item = apr_psprintf(r->pool, "%s=", elem); + value = oidc_util_hdr_in_forwarded_get(r); + value = strcasestr(value, item); + if (value) { + value += strlen(item); + ptr = strstr(value, ";"); + if (ptr) + *ptr = '\0'; + ptr = strstr(value, " "); + if (ptr) + *ptr = '\0'; + } + return apr_pstrdup(r->pool, value); +} /* * get the URL scheme that is currently being accessed @@ -443,7 +460,9 @@ /* first see if there's a proxy/load-balancer in front of us */ const char *scheme_str = NULL; - if (x_forwarded_headers & OIDC_HDR_X_FORWARDED_PROTO) + if ((x_forwarded_headers & OIDC_HDR_FORWARDED)) + scheme_str = oidc_util_hdr_forwarded_get(r, "proto"); + else if (x_forwarded_headers & OIDC_HDR_X_FORWARDED_PROTO) scheme_str = oidc_util_hdr_in_x_forwarded_proto_get(r); /* if not we'll determine the scheme used to connect to this server */ @@ -505,11 +524,13 @@ return port_str; /* - * see if we can get the port from the "X-Forwarded-Host" header + * see if we can get the port from the "X-Forwarded-Host" or "Forwarded" header * and if that header was set we'll assume defaults */ - if (x_forwarded_headers & OIDC_HDR_X_FORWARDED_HOST) + if (x_forwarded_headers & OIDC_HDR_FORWARDED) + host_hdr = oidc_util_hdr_forwarded_get(r, "host"); + else if (x_forwarded_headers & OIDC_HDR_X_FORWARDED_HOST) host_hdr = oidc_util_hdr_in_x_forwarded_host_get(r); if (host_hdr) { @@ -541,6 +562,13 @@ return NULL; /* + * do the same for the Forwarded: proto= header + */ + if (x_forwarded_headers & OIDC_HDR_FORWARDED) + if (oidc_util_hdr_forwarded_get(r, "proto")) + return NULL; + + /* * if no port was set in the Host header and no X-Forwarded-Proto was set, we'll * determine the port locally and don't print it when it's the default for the protocol */ @@ -562,7 +590,9 @@ char *p = NULL; char *i = NULL; - if (x_forwarded_headers & OIDC_HDR_X_FORWARDED_HOST) + if (x_forwarded_headers & OIDC_HDR_FORWARDED) + host_str = oidc_util_hdr_forwarded_get(r, "host"); + else if (x_forwarded_headers & OIDC_HDR_X_FORWARDED_HOST) host_str = oidc_util_hdr_in_x_forwarded_host_get(r); if (host_str == NULL) @@ -2629,6 +2659,11 @@ OIDC_HTTP_HDR_X_FORWARDED_HOST, OIDC_STR_COMMA OIDC_STR_SPACE); } +const char* oidc_util_hdr_in_forwarded_get(const request_rec *r) { + return oidc_util_hdr_in_get_left_most_only(r, + OIDC_HTTP_HDR_FORWARDED, OIDC_STR_COMMA); +} + const char* oidc_util_hdr_in_host_get(const request_rec *r) { return oidc_util_hdr_in_get(r, OIDC_HTTP_HDR_HOST); } diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' '--exclude=.svnignore' old/mod_auth_openidc-2.4.11.2/test/test.c new/mod_auth_openidc-2.4.11.3/test/test.c --- old/mod_auth_openidc-2.4.11.2/test/test.c 2022-03-29 20:39:33.000000000 +0200 +++ new/mod_auth_openidc-2.4.11.3/test/test.c 2022-08-22 12:50:22.000000000 +0200 @@ -1313,6 +1313,36 @@ TST_ASSERT_STR("test_current_url (10)", url, "http://[fd04:41b1:1170:28:16b0:446b:9fb7:7118]/private/?foo=bar¶m1=value1"); + apr_table_unset(r->headers_in, "X-Forwarded-Proto"); + apr_table_unset(r->headers_in, "Host"); + + apr_table_set(r->headers_in, "Forwarded", "host=www.outer.com"); + url = oidc_get_current_url(r, OIDC_HDR_FORWARDED); + TST_ASSERT_STR("test_current_url (11)", url, + "https://www.outer.com/private/?foo=bar¶m1=value1"); + + apr_table_set(r->headers_in, "Forwarded", "proto=http"); + url = oidc_get_current_url(r, OIDC_HDR_FORWARDED); + TST_ASSERT_STR("test_current_url (12)", url, + "http://www.example.com/private/?foo=bar¶m1=value1"); + + apr_table_set(r->headers_in, "Forwarded", "host=www.outer.com:8443"); + url = oidc_get_current_url(r, OIDC_HDR_FORWARDED); + TST_ASSERT_STR("test_current_url (13)", url, + "https://www.outer.com:8443/private/?foo=bar¶m1=value1"); + + apr_table_set(r->headers_in, "Forwarded", "proto=http; host=www.outer.com:8080"); + url = oidc_get_current_url(r, OIDC_HDR_FORWARDED); + TST_ASSERT_STR("test_current_url (14)", url, + "http://www.outer.com:8080/private/?foo=bar¶m1=value1"); + + apr_table_set(r->headers_in, "Forwarded", "host=www.outer.com:8080; proto=http"); + url = oidc_get_current_url(r, OIDC_HDR_FORWARDED); + TST_ASSERT_STR("test_current_url (15)", url, + "http://www.outer.com:8080/private/?foo=bar¶m1=value1"); + + apr_table_unset(r->headers_in, "Forwarded"); + apr_table_set(r->headers_in, "Host", "www.example.com"); return 0;