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 2021-07-23 23:41:20
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/apache2-mod_auth_openidc (Old)
 and      /work/SRC/openSUSE:Factory/.apache2-mod_auth_openidc.new.1899 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "apache2-mod_auth_openidc"

Fri Jul 23 23:41:20 2021 rev:19 rq:907973 version:2.4.9

Changes:
--------
--- 
/work/SRC/openSUSE:Factory/apache2-mod_auth_openidc/apache2-mod_auth_openidc.changes
        2021-05-19 17:49:25.813522031 +0200
+++ 
/work/SRC/openSUSE:Factory/.apache2-mod_auth_openidc.new.1899/apache2-mod_auth_openidc.changes
      2021-07-23 23:41:43.913791464 +0200
@@ -1,0 +2,48 @@
+Fri Jul 23 07:46:56 UTC 2021 - Michael Str??der <[email protected]>
+
+- Update to version 2.4.9
+  * Security
+    - use redisvCommand to avoid crash with crafted key when using Redis 
+      without encryption; thanks @thomas-chauchefoin-sonarsource
+    - replace potentially harmful backslashes with forward slashes when 
+      validating redirection URLs; thanks @thomas-chauchefoin-sonarsource
+    - avoid XSS vulnerability when using OIDCPreservePost On and supplying 
+      URLs that contain single quotes; thanks @oss-aimoto
+    - return OK in the content handler for calls to the redirect URI and when 
+      preserving POST data; prevent (intermittent) disclosure of content 
+      hosted at a (non-vanity) redirect URI location
+    - use encrypted JWTs for storing encrypted cache contents and
+      avoid using static AAD/IV; thanks @niebardzo
+  * Bugfixes
+    - verify that alg is not none in logout_token explicitly
+    - don't clear POST params authn on token revocation; thanks @iainh
+    - fix a problem where the host and port are calculated incorrectly when 
using literal ipv6 address.
+  * Other
+    - make session not found on backchannel logout produce a log warning 
instead of error
+    - handle discovery in the content handler
+    - strip A256GCM JWT header from encrypted JWTs used for state cookies, 
+      cache encryption and by-value session cookies resulting in smaller 
+      cookies and reduced cache content size
+- Fix CVE-2021-32785 format string bug via hiredis
+  (CVE-2021-32785, bsc#1188638)
+- Fix CVE-2021-32786 open redirect in logout functionality
+  (CVE-2021-32786, bsc#1188639)
+
+-------------------------------------------------------------------
+Wed Jun  2 19:04:56 UTC 2021 - Michael Str??der <[email protected]>
+
+- Use autogen.sh to generate missing configure script
+- Update to version 2.4.8.4
+  * Bugfixes
+    - do not send state timeout HTML document when OIDCDefaultURL is set;
+      this can be overridden by using e.g.:
+      SetEnvIfExpr true OIDC_NO_DEFAULT_URL_ON_STATE_TIMEOUT=true
+    - avoid Apache 2.4 appending 400/302(200/404) HTML document text to 
+      state timeout HTML info page see also f5959d7 and #484; at least Debian 
+      Buster was affected
+  * Other
+    - make error "session corrupted: no issuer found in session" a warning 
+      only so a logout call for a non-existing session no longer produces 
+      error messages
+
+-------------------------------------------------------------------

Old:
----
  mod_auth_openidc-2.4.8.2.tar.gz

New:
----
  mod_auth_openidc-2.4.9.tar.gz

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ apache2-mod_auth_openidc.spec ++++++
--- /var/tmp/diff_new_pack.S0cbAC/_old  2021-07-23 23:41:44.373790876 +0200
+++ /var/tmp/diff_new_pack.S0cbAC/_new  2021-07-23 23:41:44.373790876 +0200
@@ -17,7 +17,7 @@
 
 
 Name:           apache2-mod_auth_openidc
-Version:        2.4.8.2
+Version:        2.4.9
 Release:        0
 Summary:        Apache2.x module for an OpenID Connect enabled Identity 
Provider
 License:        Apache-2.0
@@ -26,6 +26,8 @@
 Source:         
https://github.com/zmartzone/mod_auth_openidc/releases/download/v%{version}/mod_auth_openidc-%{version}.tar.gz
 BuildRequires:  apache-rpm-macros
 BuildRequires:  apache2-devel
+BuildRequires:  autoconf
+BuildRequires:  automake
 BuildRequires:  pkgconfig
 BuildRequires:  pkgconfig(cjose) >= 0.5.1
 BuildRequires:  pkgconfig(jansson) >= 2.0
@@ -45,6 +47,7 @@
 %setup -q -n mod_auth_openidc-%{version}
 
 %build
+./autogen.sh
 %configure \
 %if 0%{?is_opensuse} > 0
   %{?_with_hiredis}    \

++++++ mod_auth_openidc-2.4.8.2.tar.gz -> mod_auth_openidc-2.4.9.tar.gz ++++++
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mod_auth_openidc-2.4.8.2/AUTHORS 
new/mod_auth_openidc-2.4.9/AUTHORS
--- old/mod_auth_openidc-2.4.8.2/AUTHORS        2021-05-12 11:00:34.000000000 
+0200
+++ new/mod_auth_openidc-2.4.9/AUTHORS  2021-07-22 18:30:00.000000000 +0200
@@ -70,3 +70,7 @@
        Harri Rautila <https://github.com/hrautila>
        Tatsuhiko Yasumatsu <https://github.com/ty60>
        Adam Stadler <https://github.com/tzfx>
+       Steffen Greber <https://github.com/codemaker219>
+       Iain Heggie <https://github.com/iainh>
+
+
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mod_auth_openidc-2.4.8.2/ChangeLog 
new/mod_auth_openidc-2.4.9/ChangeLog
--- old/mod_auth_openidc-2.4.8.2/ChangeLog      2021-05-13 09:30:00.000000000 
+0200
+++ new/mod_auth_openidc-2.4.9/ChangeLog        2021-07-22 18:30:21.000000000 
+0200
@@ -1,3 +1,48 @@
+07/22/2021
+- use redisvCommand to avoid crash with crafted key when using Redis without 
encryption; thanks @thomas-chauchefoin-sonarsource
+- replace potentially harmful backslashes with forward slashes when validating 
redirection URLs; thanks @thomas-chauchefoin-sonarsource
+- release 2.4.9
+
+07/15/2021
+- verify that "alg" is not none in logout_token explicitly
+- make session not found on backchannel logout produce a log warning instead 
of error
+- don't clear POST params authn on token revocation; thanks @iainh
+- bump to 2.4.9rc0
+
+closes #626
+07/02/2021
+- handle discovery in the content handler
+- return OK in the content handler for calls to the redirect URI and when 
preserving POST data
+
+06/25/2021
+- avoid XSS vulnerability when using OIDCPreservePost On and supplying URLs 
that contain single quotes
+  thanks @oss-aimoto
+
+06/21/2021
+- strip A256GCM JWT header from encrypted JWTS used for state cookies, cache 
encryption and by-value session cookies
+  resulting in smaller cookies and reduced cache content size
+
+06/10/2021
+- use encrypted JWTs for storing encrypted cache contents and avoid using 
static AAD/IV; thanks @niebardzo
+- bump to 2.4.9-dev
+
+06/04/2021
+- fix a problem where the host and port are calculated incorrectly, when you 
use literal ipv6 address.
+
+06/02/2021
+- do not send state timeout HTML document when OIDCDefaultURL is set; this can 
be overridden by using e.g.:
+  SetEnvIfExpr true OIDC_NO_DEFAULT_URL_ON_STATE_TIMEOUT=true 
+- release 2.4.8.4
+
+06/01/2021
+- avoid Apache 2.4 appending 400/302(200/404) HTML document text to state 
timeout HTML info page
+  see also f5959d767b0eec4856d561cbaa6d2262a52da551 and #484; at least Debian 
Buster was affected
+- release 2.4.8.3
+
+05/18/2021
+- make error "session corrupted: no issuer found in session" a warning only so 
a logout call for a
+  non-existing session no longer produces error messages
+
 05/08/2021
 - store timestamps in session in seconds to avoid string conversion problems 
on some (libapr-1)
   platform build/run combinations, causing "maximum session duration exceeded" 
errors
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mod_auth_openidc-2.4.8.2/auth_openidc.conf 
new/mod_auth_openidc-2.4.9/auth_openidc.conf
--- old/mod_auth_openidc-2.4.8.2/auth_openidc.conf      2021-05-07 
16:02:08.000000000 +0200
+++ new/mod_auth_openidc-2.4.9/auth_openidc.conf        2021-07-22 
18:30:00.000000000 +0200
@@ -585,8 +585,7 @@
 #  c) validated OAuth 2.0 tokens
 #  d) JWK sets that have been retrieved from jwk_uri's
 #  e) resolved OP metadata when using OIDCProviderMetadataUrl
-#  f) JWT ID claims (jti) when using OP-init-SSO
-#  g) temporary state associated with Request URI's
+#  f) temporary state associated with Request URI's
 # must be one of \"shm\", \"memcache\", \"file\" or, if Redis support is 
compiled in, \"redis\" 
 # When not defined, "shm" (shared memory) is used.
 #OIDCCacheType [shm|memcache|file[|redis]]
@@ -678,10 +677,16 @@
 # When not defined a bare-bones internal template is used.
 #OIDCHTMLErrorTemplate <filename>
 
-# Defines a default URL to be used in case of 3rd-party or OP initiated
-# SSO when no explicit target_link_uri has been provided. The user is also
-# sent to this URL is in case an invalid authorization response was received.
-# When not defined, 3rd-party SSO must be done with a specified 
\"target_link_uri\" parameter.
+# Defines a default URL to be used in case of 3rd-party-init-SSO when no 
explicit target_link_uri
+# has been provided. The user is also redirected to this URL in case an 
invalid authorization
+# response was received.
+#
+# By default, when no OIDCDefaultURL is set, an expired state cookie will lead 
to an HTML error page
+# being sent to the browser explaining what happened. To copy that (legacy) 
behaviour when OIDCDefaultURL is set,
+# so that the browser is no longer redirected to the OIDCDefaultURL in case of 
state cookie expiry, use:
+#   SetEnvIfExpr true OIDC_NO_DEFAULT_URL_ON_STATE_TIMEOUT=true 
+#
+# The default is to not redirect the browser to any URL but return an 
HTTP/HTML error to the user.
 #OIDCDefaultURL <default-url>
 
 # Defines a default URL where the user is sent to after logout, which may be 
overridden explicitly during logout.
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mod_auth_openidc-2.4.8.2/configure 
new/mod_auth_openidc-2.4.9/configure
--- old/mod_auth_openidc-2.4.8.2/configure      2021-05-18 07:51:25.000000000 
+0200
+++ new/mod_auth_openidc-2.4.9/configure        2021-07-22 18:41:17.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.8.2.
+# Generated by GNU Autoconf 2.71 for mod_auth_openidc 2.4.9.
 #
 # Report bugs to <[email protected]>.
 #
@@ -610,8 +610,8 @@
 # Identity of this package.
 PACKAGE_NAME='mod_auth_openidc'
 PACKAGE_TARNAME='mod_auth_openidc'
-PACKAGE_VERSION='2.4.8.2'
-PACKAGE_STRING='mod_auth_openidc 2.4.8.2'
+PACKAGE_VERSION='2.4.9'
+PACKAGE_STRING='mod_auth_openidc 2.4.9'
 PACKAGE_BUGREPORT='[email protected]'
 PACKAGE_URL=''
 
@@ -1301,7 +1301,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.8.2 to adapt to many kinds of 
systems.
+\`configure' configures mod_auth_openidc 2.4.9 to adapt to many kinds of 
systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1364,7 +1364,7 @@
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of mod_auth_openidc 2.4.8.2:";;
+     short | recursive ) echo "Configuration of mod_auth_openidc 2.4.9:";;
    esac
   cat <<\_ACEOF
 
@@ -1478,7 +1478,7 @@
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-mod_auth_openidc configure 2.4.8.2
+mod_auth_openidc configure 2.4.9
 generated by GNU Autoconf 2.71
 
 Copyright (C) 2021 Free Software Foundation, Inc.
@@ -1634,7 +1634,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.8.2, which was
+It was created by mod_auth_openidc $as_me 2.4.9, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   $ $0$ac_configure_args_raw
@@ -2292,7 +2292,7 @@
 
 
 
-NAMEVER=mod_auth_openidc-2.4.8.2
+NAMEVER=mod_auth_openidc-2.4.9
 
 
 # This section defines the --with-apxs2 option.
@@ -4952,7 +4952,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.8.2, which was
+This file was extended by mod_auth_openidc $as_me 2.4.9, which was
 generated by GNU Autoconf 2.71.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -5007,7 +5007,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.8.2
+mod_auth_openidc config.status 2.4.9
 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.8.2/configure.ac 
new/mod_auth_openidc-2.4.9/configure.ac
--- old/mod_auth_openidc-2.4.8.2/configure.ac   2021-05-13 09:30:00.000000000 
+0200
+++ new/mod_auth_openidc-2.4.9/configure.ac     2021-07-22 18:30:33.000000000 
+0200
@@ -1,4 +1,4 @@
-AC_INIT([mod_auth_openidc],[2.4.8.2],[[email protected]])
+AC_INIT([mod_auth_openidc],[2.4.9],[[email protected]])
 
 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.8.2/src/cache/common.c 
new/mod_auth_openidc-2.4.9/src/cache/common.c
--- old/mod_auth_openidc-2.4.8.2/src/cache/common.c     2021-05-07 
23:27:25.000000000 +0200
+++ new/mod_auth_openidc-2.4.9/src/cache/common.c       2021-07-22 
18:30:00.000000000 +0200
@@ -244,325 +244,59 @@
        return rv;
 }
 
-#define oidc_cache_crypto_openssl_error(r, fmt, ...) \
-               oidc_error(r, "%s: %s", apr_psprintf(r->pool, fmt, 
##__VA_ARGS__), ERR_error_string(ERR_get_error(), NULL))
-
-#define OIDC_CACHE_CIPHER                                                      
EVP_aes_256_gcm()
-#define OIDC_CACHE_TAG_LEN                                                     
16
-
-#if (OPENSSL_VERSION_NUMBER >= 0x10100005L && 
!defined(LIBRESSL_VERSION_NUMBER))
-#define OIDC_CACHE_CRYPTO_GET_TAG                                      
EVP_CTRL_AEAD_GET_TAG
-#define OIDC_CACHE_CRYPTO_SET_TAG                                      
EVP_CTRL_AEAD_SET_TAG
-#define OIDC_CACHE_CRYPTO_SET_IVLEN                                    
EVP_CTRL_AEAD_SET_IVLEN
-#else
-#define OIDC_CACHE_CRYPTO_GET_TAG                                      
EVP_CTRL_GCM_GET_TAG
-#define OIDC_CACHE_CRYPTO_SET_TAG                                      
EVP_CTRL_GCM_SET_TAG
-#define OIDC_CACHE_CRYPTO_SET_IVLEN                                    
EVP_CTRL_GCM_SET_IVLEN
-#endif
-
-/*
- * AES GCM encrypt
- */
-static int oidc_cache_crypto_encrypt_impl(request_rec *r,
-               unsigned char *plaintext, int plaintext_len, const unsigned 
char *aad,
-               int aad_len, unsigned char *key, const unsigned char *iv, int 
iv_len,
-               unsigned char *ciphertext, const unsigned char *tag, int 
tag_len) {
-       EVP_CIPHER_CTX *ctx;
-
-       int len;
-
-       int ciphertext_len;
-
-       /* create and initialize the context */
-       if (!(ctx = EVP_CIPHER_CTX_new())) {
-               oidc_cache_crypto_openssl_error(r, "EVP_CIPHER_CTX_new");
-               return -1;
-       }
-
-       /* initialize the encryption cipher */
-       if (!EVP_EncryptInit_ex(ctx, OIDC_CACHE_CIPHER, NULL, NULL, NULL)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_EncryptInit_ex");
-               return -1;
-       }
-
-       /* set IV length */
-       if (!EVP_CIPHER_CTX_ctrl(ctx, OIDC_CACHE_CRYPTO_SET_IVLEN, iv_len, 
NULL)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_CIPHER_CTX_ctrl");
-               return -1;
-       }
-
-       /* initialize key and IV */
-       if (!EVP_EncryptInit_ex(ctx, NULL, NULL, key, iv)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_EncryptInit_ex");
-               return -1;
-       }
-
-       /* provide AAD data */
-       if (!EVP_EncryptUpdate(ctx, NULL, &len, aad, aad_len)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_DecryptUpdate aad: 
aad_len=%d",
-                               aad_len);
-               return -1;
-       }
-
-       /* provide the message to be encrypted and obtain the encrypted output 
*/
-       if (!EVP_EncryptUpdate(ctx, ciphertext, &len, plaintext, 
plaintext_len)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_EncryptUpdate 
ciphertext");
-               return -1;
-       }
-       ciphertext_len = len;
-
-       /*
-        * finalize the encryption; normally ciphertext bytes may be written at
-        * this stage, but this does not occur in GCM mode
-        */
-       if (!EVP_EncryptFinal_ex(ctx, ciphertext + len, &len)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_EncryptFinal_ex");
-               return -1;
-       }
-       ciphertext_len += len;
-
-       /* get the tag */
-       if (!EVP_CIPHER_CTX_ctrl(ctx, OIDC_CACHE_CRYPTO_GET_TAG, tag_len,
-                       (void *) tag)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_CIPHER_CTX_ctrl");
-               return -1;
-       }
-
-       /* clean up */
-       EVP_CIPHER_CTX_free(ctx);
-
-       return ciphertext_len;
-}
-
-/*
- * AES GCM decrypt
- */
-static int oidc_cache_crypto_decrypt_impl(request_rec *r,
-               unsigned char *ciphertext, int ciphertext_len, const unsigned 
char *aad,
-               int aad_len, const unsigned char *tag, int tag_len, unsigned 
char *key,
-               const unsigned char *iv, int iv_len, unsigned char *plaintext) {
-       EVP_CIPHER_CTX *ctx;
-       int len;
-       int plaintext_len;
-       int ret;
-
-       /* create and initialize the context */
-       if (!(ctx = EVP_CIPHER_CTX_new())) {
-               oidc_cache_crypto_openssl_error(r, "EVP_CIPHER_CTX_new");
-               return -1;
-       }
-
-       /* initialize the decryption cipher */
-       if (!EVP_DecryptInit_ex(ctx, OIDC_CACHE_CIPHER, NULL, NULL, NULL)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_DecryptInit_ex");
-               return -1;
-       }
-
-       /* set IV length */
-       if (!EVP_CIPHER_CTX_ctrl(ctx, OIDC_CACHE_CRYPTO_SET_IVLEN, iv_len, 
NULL)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_CIPHER_CTX_ctrl");
-               return -1;
-       }
-
-       /* initialize key and IV */
-       if (!EVP_DecryptInit_ex(ctx, NULL, NULL, key, iv)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_DecryptInit_ex");
-               return -1;
-       }
-
-       /* provide AAD data */
-       if (!EVP_DecryptUpdate(ctx, NULL, &len, aad, aad_len)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_DecryptUpdate aad: 
aad_len=%d",
-                               aad_len);
-               return -1;
-       }
-
-       /* provide the message to be decrypted and obtain the plaintext output 
*/
-       if (!EVP_DecryptUpdate(ctx, plaintext, &len, ciphertext, 
ciphertext_len)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_DecryptUpdate 
ciphertext");
-               return -1;
-       }
-       plaintext_len = len;
-
-       /* set expected tag value; works in OpenSSL 1.0.1d and later */
-       if (!EVP_CIPHER_CTX_ctrl(ctx, OIDC_CACHE_CRYPTO_SET_TAG, tag_len,
-                       (void *) tag)) {
-               oidc_cache_crypto_openssl_error(r, "EVP_CIPHER_CTX_ctrl");
-               return -1;
-       }
-
-       /*
-        * finalize the decryption; a positive return value indicates success,
-        * anything else is a failure - the plaintext is not trustworthy
-        */
-       ret = EVP_DecryptFinal_ex(ctx, plaintext + len, &len);
-
-       /* clean up */
-       EVP_CIPHER_CTX_free(ctx);
-
-       if (ret > 0) {
-               /* success */
-               plaintext_len += len;
-               return plaintext_len;
-       } else {
-               /* verify failed */
-               oidc_cache_crypto_openssl_error(r, "EVP_DecryptFinal_ex");
-               return -1;
-       }
-}
-
-/*
- * static AAD value for encryption/decryption
- */
-static const unsigned char OIDC_CACHE_CRYPTO_GCM_AAD[] = { 0x4d, 0x23, 0xc3,
-               0xce, 0xc3, 0x34, 0xb4, 0x9b, 0xdb, 0x37, 0x0c, 0x43, 0x7f, 
0xec, 0x78,
-               0xde };
+#define OIDC_CACHE_CRYPTO_JSON_KEY "c"
 
 /*
- * static IV value for encryption/decryption
+ * AES GCM encrypt using the crypto passphrase as symmetric key
  */
-static const unsigned char OIDC_CACHE_CRYPTO_GCM_IV[] = { 0x00, 0x01, 0x02,
-               0x03, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x0b, 0x0c, 
0x0d, 0x0e,
-               0x0f };
+static apr_byte_t oidc_cache_crypto_encrypt(request_rec *r, const char 
*plaintext, const char *key,
+               char **result) {
+       apr_byte_t rv = FALSE;
+       json_t *json = NULL;
 
-/*
- * AES GCM encrypt using the static AAD and IV
- */
-static int oidc_cache_crypto_encrypt(request_rec *r, const char *plaintext,
-               unsigned char *key, char **result) {
-       char *encoded = NULL, *p = NULL, *e_tag = NULL;
-       unsigned char *ciphertext = NULL;
-       int plaintext_len, ciphertext_len, encoded_len, e_tag_len;
-       unsigned char tag[OIDC_CACHE_TAG_LEN];
-
-       /* allocate space for the ciphertext */
-       plaintext_len = strlen(plaintext) + 1;
-       ciphertext = apr_pcalloc(r->pool,
-                       (plaintext_len + 
EVP_CIPHER_block_size(OIDC_CACHE_CIPHER)));
-
-       ciphertext_len = oidc_cache_crypto_encrypt_impl(r,
-                       (unsigned char *) plaintext, plaintext_len,
-                       OIDC_CACHE_CRYPTO_GCM_AAD, 
sizeof(OIDC_CACHE_CRYPTO_GCM_AAD), key,
-                       OIDC_CACHE_CRYPTO_GCM_IV, 
sizeof(OIDC_CACHE_CRYPTO_GCM_IV),
-                       ciphertext, tag, sizeof(tag));
-
-       /* base64url encode the resulting ciphertext */
-       encoded_len = oidc_base64url_encode(r, &encoded, (const char *) 
ciphertext,
-                       ciphertext_len, 1);
-       if (encoded_len > 0) {
-               p = encoded;
-
-               /* base64url encode the tag */
-               e_tag_len = oidc_base64url_encode(r, &e_tag, (const char *) tag,
-                               OIDC_CACHE_TAG_LEN, 1);
-
-               /* now allocated space for the concatenated base64url encoded 
ciphertext and tag */
-               encoded = apr_pcalloc(r->pool, encoded_len + 1 + e_tag_len + 1);
-               memcpy(encoded, p, encoded_len);
-               p = encoded + encoded_len;
-               *p = OIDC_CHAR_DOT;
-               p++;
-
-               /* append the tag in the buffer */
-               memcpy(p, e_tag, e_tag_len);
-               encoded_len += e_tag_len + 1;
+       json = json_object();
+       json_object_set_new(json, OIDC_CACHE_CRYPTO_JSON_KEY, 
json_string(plaintext));
 
-               /* make sure the result is \0 terminated */
-               encoded[encoded_len] = '\0';
+       rv = oidc_util_jwt_create(r, (const char*) key, json, result, TRUE);
 
-               *result = encoded;
-       }
+       if (json)
+               json_decref(json);
 
-       return encoded_len;
+       return rv;
 }
 
 /*
- * AES GCM decrypt using the static AAD and IV
+ * AES GCM decrypt using the crypto passphrase as symmetric key
  */
-static int oidc_cache_crypto_decrypt(request_rec *r, const char *cache_value,
-               unsigned char *key, unsigned char **plaintext) {
+static apr_byte_t oidc_cache_crypto_decrypt(request_rec *r, const char 
*cache_value,
+               const char *key, char **plaintext) {
 
-       int len = -1;
+       apr_byte_t rv = FALSE;
+       json_t *json = NULL;
 
-       /* grab the base64url-encoded tag after the "." */
-       char *encoded_tag = strstr(cache_value, ".");
-       if (encoded_tag == NULL) {
-               oidc_error(r,
-                               "corrupted cache value: no tag separator found 
in encrypted value");
-               return FALSE;
-       }
+       rv = oidc_util_jwt_verify(r, (const char*) key, cache_value, &json, 
TRUE);
+       if (rv == FALSE)
+               goto end;
 
-       /* make sure we don't modify the original string since it may be just a 
pointer into the cache (shm) */
-       cache_value = apr_pstrmemdup(r->pool, cache_value,
-                       strlen(cache_value) - strlen(encoded_tag));
-       encoded_tag++;
-
-       /* base64url decode the ciphertext */
-       char *d_bytes = NULL;
-       int d_len = oidc_base64url_decode(r->pool, &d_bytes, cache_value);
-
-       /* base64url decode the tag */
-       char *t_bytes = NULL;
-       int t_len = oidc_base64url_decode(r->pool, &t_bytes, encoded_tag);
-
-       /* see if we're still good to go */
-       if ((d_len > 0) && (t_len > 0)) {
-
-               /* allocated space for the plaintext */
-               *plaintext = apr_pcalloc(r->pool,
-                               (d_len + 
EVP_CIPHER_block_size(OIDC_CACHE_CIPHER) - 1));
-
-               /* decrypt the ciphertext providing the tag value */
-
-               len = oidc_cache_crypto_decrypt_impl(r, (unsigned char *) 
d_bytes,
-                               d_len, OIDC_CACHE_CRYPTO_GCM_AAD,
-                               sizeof(OIDC_CACHE_CRYPTO_GCM_AAD), (unsigned 
char *) t_bytes,
-                               t_len, key, OIDC_CACHE_CRYPTO_GCM_IV,
-                               sizeof(OIDC_CACHE_CRYPTO_GCM_IV), *plaintext);
-
-               /* check the result and make sure it is \0 terminated */
-               if (len > -1) {
-                       (*plaintext)[len] = '\0';
-               } else {
-                       *plaintext = NULL;
-               }
+       rv = oidc_json_object_get_string(r->pool, json, 
OIDC_CACHE_CRYPTO_JSON_KEY, plaintext, NULL);
 
-       }
+end:
 
-       return len;
-}
+       if (json)
+               json_decref(json);
 
-/*
- * hash the crypto passhphrase so it has enough key length for AES GCM 256
- */
-static unsigned char *oidc_cache_hash_passphrase(request_rec *r,
-               const char *passphrase) {
-
-       unsigned char *key = NULL;
-       unsigned int key_len = 0;
-       oidc_jose_error_t err;
-
-       if (oidc_jose_hash_bytes(r->pool, OIDC_JOSE_ALG_SHA256,
-                       (const unsigned char *) passphrase, strlen(passphrase), 
&key,
-                       &key_len, &err) == FALSE) {
-               oidc_error(r, "oidc_jose_hash_bytes returned an error: %s", 
err.text);
-               return NULL;
-       }
-
-       return key;
+       return rv;
 }
 
 /*
  * hash a cache key and a crypto passphrase so the result is suitable as an 
randomized cache key
  */
-static char *oidc_cache_get_hashed_key(request_rec *r, const char *passphrase,
-               const char *key) {
+static char* oidc_cache_get_hashed_key(request_rec *r, const char *passphrase, 
const char *key) {
        char *input = apr_psprintf(r->pool, "%s:%s", passphrase, key);
        char *output = NULL;
-       if (oidc_util_hash_string_and_base64url_encode(r, OIDC_JOSE_ALG_SHA256,
-                       input, &output) == FALSE) {
-               oidc_error(r,
-                               "oidc_util_hash_string_and_base64url_encode 
returned an error");
+       if (oidc_util_hash_string_and_base64url_encode(r, OIDC_JOSE_ALG_SHA256, 
input, &output)
+                       == FALSE) {
+               oidc_error(r, "oidc_util_hash_string_and_base64url_encode 
returned an error");
                return NULL;
        }
        return output;
@@ -604,9 +338,7 @@
                goto out;
        }
 
-       rc = (oidc_cache_crypto_decrypt(r, cache_value,
-                       oidc_cache_hash_passphrase(r, cfg->crypto_passphrase),
-                       (unsigned char **) value) > 0);
+       rc = oidc_cache_crypto_decrypt(r, cache_value, cfg->crypto_passphrase, 
value);
 
 out:
        /* log the result */
@@ -650,9 +382,7 @@
                        goto out;
 
                if (value != NULL) {
-                       if (oidc_cache_crypto_encrypt(r, value,
-                                       oidc_cache_hash_passphrase(r, 
cfg->crypto_passphrase),
-                                       &encoded) <= 0)
+                       if (oidc_cache_crypto_encrypt(r, value, 
cfg->crypto_passphrase, &encoded) == FALSE)
                                goto out;
                        value = encoded;
                }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mod_auth_openidc-2.4.8.2/src/cache/redis.c 
new/mod_auth_openidc-2.4.9/src/cache/redis.c
--- old/mod_auth_openidc-2.4.8.2/src/cache/redis.c      2021-05-13 
09:30:00.000000000 +0200
+++ new/mod_auth_openidc-2.4.9/src/cache/redis.c        2021-07-22 
18:30:06.000000000 +0200
@@ -265,10 +265,12 @@
  * execute Redis command and deal with return value
  */
 static redisReply* oidc_cache_redis_command(request_rec *r,
-               oidc_cache_cfg_redis_t *context, const char *command) {
+               oidc_cache_cfg_redis_t *context, const char *format, ...) {
 
        redisReply *reply = NULL;
        int i = 0;
+       va_list ap;
+       va_start(ap, format);
 
        /* try to execute a command at max 2 times while reconnecting */
        for (i = 0; i < OIDC_REDIS_MAX_TRIES; i++) {
@@ -278,7 +280,7 @@
                        break;
 
                /* execute the actual command */
-               reply = redisCommand(context->ctx, command);
+               reply = redisvCommand(context->ctx, format, ap);
 
                /* check for errors, need to return error replies for cache 
miss case REDIS_REPLY_NIL */
                if ((reply != NULL) && (reply->type != REDIS_REPLY_ERROR))
@@ -298,6 +300,8 @@
                oidc_cache_redis_free(context);
        }
 
+       va_end(ap);
+
        return reply;
 }
 
@@ -318,9 +322,8 @@
                return FALSE;
 
        /* get */
-       reply = oidc_cache_redis_command(r, context,
-                       apr_psprintf(r->pool, "GET %s",
-                                       oidc_cache_redis_get_key(r->pool, 
section, key)));
+       reply =
+                       oidc_cache_redis_command(r, context, "GET %s", 
oidc_cache_redis_get_key(r->pool, section, key));
 
        if (reply == NULL)
                goto end;
@@ -384,9 +387,8 @@
        if (value == NULL) {
 
                /* delete it */
-               reply = oidc_cache_redis_command(r, context,
-                               apr_psprintf(r->pool, "DEL %s",
-                                               
oidc_cache_redis_get_key(r->pool, section, key)));
+               reply =
+                               oidc_cache_redis_command(r, context, "DEL %s", 
oidc_cache_redis_get_key(r->pool, section, key));
 
        } else {
 
@@ -394,10 +396,8 @@
                timeout = apr_time_sec(expiry - apr_time_now());
 
                /* store it */
-               reply = oidc_cache_redis_command(r, context,
-                               apr_psprintf(r->pool, "SETEX %s %d %s",
-                                               
oidc_cache_redis_get_key(r->pool, section, key),
-                                               timeout, value));
+               reply =
+                               oidc_cache_redis_command(r, context, "SETEX %s 
%d %s", oidc_cache_redis_get_key(r->pool, section, key), timeout, value);
 
        }
 
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mod_auth_openidc-2.4.8.2/src/mod_auth_openidc.c 
new/mod_auth_openidc-2.4.9/src/mod_auth_openidc.c
--- old/mod_auth_openidc-2.4.8.2/src/mod_auth_openidc.c 2021-05-07 
23:27:25.000000000 +0200
+++ new/mod_auth_openidc-2.4.9/src/mod_auth_openidc.c   2021-07-22 
18:30:06.000000000 +0200
@@ -468,7 +468,7 @@
                                        "    </script>\n", jmethod, json,
                                        location ?
                                                        apr_psprintf(r->pool, 
"window.location='%s';\n",
-                                                                       
location) :
+                                                                       
oidc_util_javascript_escape(r->pool, location)) :
                                                                        "");
        if (location == NULL) {
                if (javascript_method)
@@ -513,10 +513,10 @@
                                        "          input.type = \"hidden\";\n"
                                        "          
document.forms[0].appendChild(input);\n"
                                        "        }\n"
-                                       "        document.forms[0].action = 
'%s';\n"
+                                       "        document.forms[0].action = 
\"%s\";\n"
                                        "        document.forms[0].submit();\n"
                                        "      }\n"
-                                       "    </script>\n", method, 
original_url);
+                                       "    </script>\n", method, 
oidc_util_javascript_escape(r->pool, original_url));
 
        const char *body = "    <p>Restoring...</p>\n"
                        "    <form method=\"post\"></form>\n";
@@ -688,16 +688,16 @@
        /* check that the timestamp is not beyond the valid interval */
        if (apr_time_now() > ts + apr_time_from_sec(c->state_timeout)) {
                oidc_error(r, "state has expired");
-               /*
-                * note that this overrides redirection to the OIDCDefaultURL 
as done later...
-                * see: 
https://groups.google.com/forum/?utm_medium=email&utm_source=footer#!msg/mod_auth_openidc/L4JFBw-XCNU/BWi2Fmk2AwAJ
-                */
-               oidc_util_html_send_error(r, c->error_template,
-                               "Invalid Authentication Response",
-                               apr_psprintf(r->pool,
-                                               "This is due to a timeout; 
please restart your authentication session by re-entering the URL/bookmark you 
originally wanted to access: %s",
-                                               
oidc_proto_state_get_original_url(*proto_state)),
-                                               OK);
+               if ((c->default_sso_url == NULL)
+                               || (apr_table_get(r->subprocess_env, 
"OIDC_NO_DEFAULT_URL_ON_STATE_TIMEOUT") != NULL)) {
+                       oidc_util_html_send_error(r, c->error_template, 
"Invalid Authentication Response", apr_psprintf(r->pool, "This is due to a 
timeout; please restart your authentication session by re-entering the 
URL/bookmark you originally wanted to access: %s", 
oidc_proto_state_get_original_url(*proto_state)),
+                                                                         OK);
+                       /*
+                        * a hack for Apache 2.4 to prevent it from writing its 
own 500/400/302 HTML document
+                        * text by making ap_send_error_response in 
http_protocol.c return early...
+                        */
+                       r->header_only = 1;
+               }
                oidc_proto_state_destroy(*proto_state);
                return FALSE;
        }
@@ -992,7 +992,7 @@
        /* get the issuer value from the session state */
        const char *issuer = oidc_session_get_issuer(r, session);
        if (issuer == NULL) {
-               oidc_error(r, "session corrupted: no issuer found in session");
+               oidc_warn(r, "empty or invalid session: no issuer found");
                return FALSE;
        }
 
@@ -1553,7 +1553,7 @@
        char *java_script = apr_psprintf(r->pool,
                        "    <script type=\"text/javascript\">\n"
                        "      window.top.location.href = 
'%s?session=logout';\n"
-                       "    </script>\n", oidc_get_redirect_uri(r, c));
+                       "    </script>\n", oidc_util_javascript_escape(r->pool, 
oidc_get_redirect_uri(r, c)));
 
        return oidc_util_html_send(r, "Redirecting...", java_script, NULL, NULL,
                        OK);
@@ -1912,6 +1912,7 @@
                                        "invalid authorization response state; 
a default SSO URL is set, sending the user there: %s",
                                        c->default_sso_url);
                        oidc_util_hdr_out_location_set(r, c->default_sso_url);
+                       //oidc_util_hdr_err_out_add(r, "Location", 
c->default_sso_url));
                        return HTTP_MOVED_TEMPORARILY;
                }
                oidc_error(r,
@@ -2251,8 +2252,17 @@
        if (provider == NULL) {
 
                // TODO: should we use an explicit redirect to the discovery 
endpoint (maybe a "discovery" param to the redirect_uri)?
-               if (c->metadata_dir != NULL)
-                       return oidc_discovery(r, c);
+               if (c->metadata_dir != NULL) {
+                       /*
+                        * Will be handled in the content handler; avoid:
+                        * No authentication done but request not allowed 
without authentication
+                        * by setting r->user
+                        */
+                       oidc_debug(r, "defer discovery to the content handler");
+                       oidc_request_state_set(r, 
OIDC_REQUEST_STATE_KEY_DISCOVERY, "");
+                       r->user = "";
+                       return OK;
+               }
 
                /* we're not using multiple OP's configured in a metadata 
directory, pick the statically configured OP */
                if (oidc_provider_static_config(r, c, &provider) == FALSE)
@@ -2620,8 +2630,8 @@
        // TODO: use oauth.ssl_validate_server ...
        token = oidc_session_get_refresh_token(r, session);
        if (token != NULL) {
-               apr_table_addn(params, "token_type_hint", "refresh_token");
-               apr_table_addn(params, "token", token);
+               apr_table_setn(params, OIDC_PROTO_TOKEN_TYPE_HINT, 
OIDC_PROTO_REFRESH_TOKEN);
+               apr_table_setn(params, OIDC_PROTO_TOKEN, token);
 
                if (oidc_util_http_post_form(r, 
provider->revocation_endpoint_url,
                                params, basic_auth, bearer_auth, 
c->oauth.ssl_validate_server,
@@ -2630,13 +2640,14 @@
                                NULL, NULL) == FALSE) {
                        oidc_warn(r, "revoking refresh token failed");
                }
-               apr_table_clear(params);
+               apr_table_unset(params, OIDC_PROTO_TOKEN_TYPE_HINT);
+               apr_table_unset(params, OIDC_PROTO_TOKEN);
        }
 
        token = oidc_session_get_access_token(r, session);
        if (token != NULL) {
-               apr_table_addn(params, "token_type_hint", "access_token");
-               apr_table_addn(params, "token", token);
+               apr_table_setn(params, OIDC_PROTO_TOKEN_TYPE_HINT, 
OIDC_PROTO_ACCESS_TOKEN);
+               apr_table_setn(params, OIDC_PROTO_TOKEN, token);
 
                if (oidc_util_http_post_form(r, 
provider->revocation_endpoint_url,
                                params, basic_auth, bearer_auth, 
c->oauth.ssl_validate_server,
@@ -2686,16 +2697,14 @@
                const char *accept = oidc_util_hdr_in_accept_get(r);
                if ((apr_strnatcmp(url, OIDC_IMG_STYLE_LOGOUT_PARAM_VALUE) == 0)
                                || ((accept) && strstr(accept, 
OIDC_CONTENT_TYPE_IMAGE_PNG))) {
-                       // terminate with DONE instead of OK
-                       // to avoid Apache returning auth/authz error 401 for 
the redirect URI
                        return oidc_util_http_send(r, (const char*) 
&oidc_transparent_pixel,
                                        sizeof(oidc_transparent_pixel), 
OIDC_CONTENT_TYPE_IMAGE_PNG,
-                                       DONE);
+                                       OK);
                }
 
                /* standard HTTP based logout: should be called in an iframe 
from the OP */
                return oidc_util_html_send(r, "Logged Out", NULL, NULL,
-                               "<p>Logged Out</p>", DONE);
+                               "<p>Logged Out</p>", OK);
        }
 
        /* see if we don't need to go somewhere special after killing the 
session locally */
@@ -2751,6 +2760,11 @@
                goto out;
        }
 
+       if ((jwt->header.alg == NULL) || (strcmp(jwt->header.alg, "none") == 
0)) {
+               oidc_error(r, "logout token is not signed");
+               goto out;
+       }
+
        provider = oidc_get_provider_for_issuer(r, cfg, jwt->payload.iss, 
FALSE);
        if (provider == NULL) {
                oidc_error(r, "no provider found for issuer: %s", 
jwt->payload.iss);
@@ -2864,12 +2878,12 @@
        sid = oidc_make_sid_iss_unique(r, sid, provider->issuer);
        oidc_cache_get_sid(r, sid, &uuid);
        if (uuid == NULL) {
-               oidc_error(r,
-                               "could not find session based on sid/sub 
provided in logout token: %s",
+               // 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);
-               // return HTTP 200 according to (new?) spec and terminate early
-               // to avoid Apache returning auth/authz error 500 for the 
redirect URI
-               rc = DONE;
+               r->user = "";
+               rc = OK;
                goto out;
        }
 
@@ -2884,9 +2898,8 @@
        oidc_cache_set_sid(r, sid, NULL, 0);
        oidc_cache_set_session(r, uuid, NULL, 0);
 
-       // terminate with DONE instead of OK
-       // to avoid Apache returning auth/authz error 500 for the redirect URI
-       rc = DONE;
+       r->user = "";
+       rc = OK;
 
 out:
 
@@ -2907,12 +2920,21 @@
        return rc;
 }
 
+#define OIDC_MAX_URL_LENGTH DEFAULT_LIMIT_REQUEST_LINE * 2
+
 static apr_byte_t oidc_validate_redirect_url(request_rec *r, oidc_cfg *c,
-               const char *url, apr_byte_t restrict_to_host, char **err_str,
+               const char *redirect_to_url, apr_byte_t restrict_to_host, char 
**err_str,
                char **err_desc) {
        apr_uri_t uri;
        const char *c_host = NULL;
        apr_hash_index_t *hi = NULL;
+       size_t i = 0;
+       char *url = apr_pstrndup(r->pool, redirect_to_url, OIDC_MAX_URL_LENGTH);
+
+       // replace potentially harmful backslashes with forward slashes
+       for (i = 0; i < strlen(url); i++)
+               if (url[i] == '\\')
+                       url[i] = '/';
 
        if (apr_uri_parse(r->pool, url, &uri) != APR_SUCCESS) {
                *err_str = apr_pstrdup(r->pool, "Malformed URL");
@@ -3051,6 +3073,9 @@
                                                                        
OIDC_STR_QUERY,
                                                                        
oidc_util_escape_string(r, url));
                }
+               //char *state = NULL;
+               //oidc_proto_generate_nonce(r, &state, 8);
+               //url = apr_psprintf(r->pool, "%s&state=%s", logout_request, 
state);
                url = logout_request;
        }
 
@@ -3706,7 +3731,7 @@
                //              oidc_util_get_request_parameter(r, 
"error_description", &descr);
                //
                //              /* send user facing error to browser */
-               //              return oidc_util_html_send_error(r, error, 
descr, DONE);
+               //              return oidc_util_html_send_error(r, error, 
descr, OK);
                return oidc_handle_redirect_authorization_response(r, c, 
session);
        }
 
@@ -4136,27 +4161,43 @@
        apr_byte_t needs_save = FALSE;
        oidc_session_t *session = NULL;
 
-       if (oidc_enabled(r)
-                       && oidc_util_request_matches_url(r, 
oidc_get_redirect_uri(r, c))) {
+       if (oidc_enabled(r) == TRUE) {
+
+               if (oidc_util_request_matches_url(r, oidc_get_redirect_uri(r, 
c)) == TRUE) {
+
+                       if (oidc_util_request_has_parameter(r,
+                                       OIDC_REDIRECT_URI_REQUEST_INFO)) {
+
+                               oidc_session_load(r, &session);
+
+                               rc = oidc_handle_existing_session(r, c, 
session, &needs_save);
+                               if (rc == OK)
+                                       /* handle request for session info */
+                                       rc = oidc_handle_info_request(r, c, 
session, needs_save);
+
+                               /* free resources allocated for the session */
+                               oidc_session_free(r, session);
+
+                       } else if (oidc_util_request_has_parameter(r,
+                                       OIDC_REDIRECT_URI_REQUEST_JWKS)) {
+
+                               /* handle JWKs request */
+                               rc = oidc_handle_jwks(r, c);
 
-               if (oidc_util_request_has_parameter(r,
-                               OIDC_REDIRECT_URI_REQUEST_INFO)) {
+                       } else {
+
+                               rc = OK;
+
+                       }
 
-                       oidc_session_load(r, &session);
+               } else if (oidc_request_state_get(r, 
OIDC_REQUEST_STATE_KEY_DISCOVERY) != NULL) {
 
-                       rc = oidc_handle_existing_session(r, c, session, 
&needs_save);
-                       if (rc == OK)
-                               /* handle request for session info */
-                               rc = oidc_handle_info_request(r, c, session, 
needs_save);
+                       rc = oidc_discovery(r, c);
 
-                       /* free resources allocated for the session */
-                       oidc_session_free(r, session);
+               } else if (oidc_request_state_get(r, 
OIDC_REQUEST_STATE_KEY_AUTHN) != NULL) {
 
-               } else if (oidc_util_request_has_parameter(r,
-                               OIDC_REDIRECT_URI_REQUEST_JWKS)) {
+                       rc = OK;
 
-                       /* handle JWKs request */
-                       rc = oidc_handle_jwks(r, c);
                }
 
        }
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mod_auth_openidc-2.4.8.2/src/mod_auth_openidc.h 
new/mod_auth_openidc-2.4.9/src/mod_auth_openidc.h
--- old/mod_auth_openidc-2.4.8.2/src/mod_auth_openidc.h 2021-05-13 
09:30:00.000000000 +0200
+++ new/mod_auth_openidc-2.4.9/src/mod_auth_openidc.h   2021-07-22 
18:30:00.000000000 +0200
@@ -87,6 +87,8 @@
 /* keys for storing info in the request state */
 #define OIDC_REQUEST_STATE_KEY_IDTOKEN "i"
 #define OIDC_REQUEST_STATE_KEY_CLAIMS  "c"
+#define OIDC_REQUEST_STATE_KEY_DISCOVERY  "d"
+#define OIDC_REQUEST_STATE_KEY_AUTHN  "a"
 
 /* parameter name of the callback URL in the discovery response */
 #define OIDC_DISC_CB_PARAM "oidc_callback"
@@ -478,6 +480,8 @@
 #define OIDC_PROTO_SCOPE                 "scope"
 #define OIDC_PROTO_REFRESH_TOKEN         "refresh_token"
 #define OIDC_PROTO_TOKEN_TYPE            "token_type"
+#define OIDC_PROTO_TOKEN_TYPE_HINT       "token_type_hint"
+#define OIDC_PROTO_TOKEN                 "token"
 #define OIDC_PROTO_EXPIRES_IN            "expires_in"
 #define OIDC_PROTO_RESPONSE_TYPE         "response_type"
 #define OIDC_PROTO_RESPONSE_MODE         "response_mode"
@@ -776,6 +780,7 @@
 apr_byte_t oidc_json_object_get_int(apr_pool_t *pool, json_t *json, const char 
*name, int *value, const int default_value);
 apr_byte_t oidc_json_object_get_bool(apr_pool_t *pool, json_t *json, const 
char *name, int *value, const int default_value);
 char *oidc_util_html_escape(apr_pool_t *pool, const char *input);
+char *oidc_util_javascript_escape(apr_pool_t *pool, const char *input);
 void oidc_util_table_add_query_encoded_params(apr_pool_t *pool, apr_table_t 
*table, const char *params);
 apr_hash_t * oidc_util_merge_key_sets(apr_pool_t *pool, apr_hash_t *k1, const 
apr_array_header_t *k2);
 apr_hash_t * oidc_util_merge_key_sets_hash(apr_pool_t *pool, apr_hash_t *k1, 
apr_hash_t *k2);
@@ -784,8 +789,8 @@
 apr_byte_t oidc_util_json_merge(request_rec *r, json_t *src, json_t *dst);
 int oidc_util_cookie_domain_valid(const char *hostname, char *cookie_domain);
 apr_byte_t oidc_util_hash_string_and_base64url_encode(request_rec *r, const 
char *openssl_hash_algo, const char *input, char **output);
-apr_byte_t oidc_util_jwt_create(request_rec *r, const char *secret, json_t 
*payload, char **compact_encoded_jwt);
-apr_byte_t oidc_util_jwt_verify(request_rec *r, const char *secret, const char 
*compact_encoded_jwt, json_t **result);
+apr_byte_t oidc_util_jwt_create(request_rec *r, const char *secret, json_t 
*payload, char **compact_encoded_jwt, apr_byte_t strip_header);
+apr_byte_t oidc_util_jwt_verify(request_rec *r, const char *secret, const char 
*compact_encoded_jwt, json_t **result, apr_byte_t stripped_header);
 char *oidc_util_get_chunked_cookie(request_rec *r, const char *cookieName, int 
cookie_chunk_size);
 void oidc_util_set_chunked_cookie(request_rec *r, const char *cookieName, 
const char *cookieValue, apr_time_t expires, int chunkSize, const char *ext);
 apr_byte_t oidc_util_create_symmetric_key(request_rec *r, const char 
*client_secret, unsigned int r_key_len, const char *hash_algo, apr_byte_t 
set_kid, oidc_jwk_t **jwk);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mod_auth_openidc-2.4.8.2/src/proto.c 
new/mod_auth_openidc-2.4.9/src/proto.c
--- old/mod_auth_openidc-2.4.8.2/src/proto.c    2021-05-07 23:27:25.000000000 
+0200
+++ new/mod_auth_openidc-2.4.9/src/proto.c      2021-07-22 18:30:00.000000000 
+0200
@@ -758,7 +758,16 @@
 
                        /* and tell Apache to return an HTTP Redirect (302) 
message */
                        rv = HTTP_MOVED_TEMPORARILY;
+
+               } else {
+
+                       /* signal this to the content handler */
+                       oidc_request_state_set(r, OIDC_REQUEST_STATE_KEY_AUTHN, 
"");
+                       r->user = "";
+                       rv = OK;
+
                }
+
        } else {
                oidc_error(r, "provider->auth_request_method set to wrong 
value: %d",
                                provider->auth_request_method);
@@ -962,16 +971,16 @@
 oidc_proto_state_t* oidc_proto_state_from_cookie(request_rec *r, oidc_cfg *c,
                const char *cookieValue) {
        json_t *result = NULL;
-       oidc_util_jwt_verify(r, c->crypto_passphrase, cookieValue, &result);
+       oidc_util_jwt_verify(r, c->crypto_passphrase, cookieValue, &result, 
TRUE);
        return result;
 }
 
-char* oidc_proto_state_to_cookie(request_rec *r, oidc_cfg *c,
-               oidc_proto_state_t *proto_state) {
+char* oidc_proto_state_to_cookie(request_rec *r, oidc_cfg *c, 
oidc_proto_state_t *proto_state) {
        char *cookieValue = NULL;
-       oidc_util_jwt_create(r, c->crypto_passphrase, proto_state, 
&cookieValue);
+       oidc_util_jwt_create(r, c->crypto_passphrase, proto_state, 
&cookieValue, TRUE);
        return cookieValue;
 }
+
 char* oidc_proto_state_to_string(request_rec *r,
                oidc_proto_state_t *proto_state) {
        return oidc_util_encode_json_object(r, proto_state, JSON_COMPACT);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mod_auth_openidc-2.4.8.2/src/session.c 
new/mod_auth_openidc-2.4.9/src/session.c
--- old/mod_auth_openidc-2.4.8.2/src/session.c  2021-05-11 17:51:42.000000000 
+0200
+++ new/mod_auth_openidc-2.4.9/src/session.c    2021-07-22 18:30:00.000000000 
+0200
@@ -66,32 +66,29 @@
 /* the name of the sid attribute in the session */
 #define OIDC_SESSION_SID_KEY                      "sid"
 
-static apr_byte_t oidc_session_encode(request_rec *r, oidc_cfg *c,
-               oidc_session_t *z, char **s_value, apr_byte_t encrypt) {
+static apr_byte_t oidc_session_encode(request_rec *r, oidc_cfg *c, 
oidc_session_t *z,
+               char **s_value, apr_byte_t encrypt) {
 
        if (encrypt == FALSE) {
                *s_value = oidc_util_encode_json_object(r, z->state, 
JSON_COMPACT);
                return (*s_value != NULL);
        }
 
-       if (oidc_util_jwt_create(r, c->crypto_passphrase, z->state,
-                       s_value) == FALSE)
+       if (oidc_util_jwt_create(r, c->crypto_passphrase, z->state, s_value, 
TRUE) == FALSE)
                return FALSE;
 
        return TRUE;
 }
 
-static apr_byte_t oidc_session_decode(request_rec *r, oidc_cfg *c,
-               oidc_session_t *z, const char *s_json, apr_byte_t encrypt) {
+static apr_byte_t oidc_session_decode(request_rec *r, oidc_cfg *c, 
oidc_session_t *z,
+               const char *s_json, apr_byte_t encrypt) {
 
        if (encrypt == FALSE) {
                return oidc_util_decode_json_object(r, s_json, &z->state);
        }
 
-       if (oidc_util_jwt_verify(r, c->crypto_passphrase, s_json,
-                       &z->state) == FALSE) {
-               oidc_error(r,
-                               "could not verify secure JWT: cache value 
possibly corrupted");
+       if (oidc_util_jwt_verify(r, c->crypto_passphrase, s_json, &z->state, 
TRUE) == FALSE) {
+               oidc_error(r, "could not verify secure JWT: cache value 
possibly corrupted");
                return FALSE;
        }
        return TRUE;
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mod_auth_openidc-2.4.8.2/src/util.c 
new/mod_auth_openidc-2.4.9/src/util.c
--- old/mod_auth_openidc-2.4.8.2/src/util.c     2021-05-07 23:27:25.000000000 
+0200
+++ new/mod_auth_openidc-2.4.9/src/util.c       2021-07-22 18:30:00.000000000 
+0200
@@ -132,8 +132,10 @@
        return apr_base64_decode(*dst, dec);
 }
 
-apr_byte_t oidc_util_jwt_create(request_rec *r, const char *secret,
-               json_t *payload, char **compact_encoded_jwt) {
+#define OIDC_JWT_HDR_DIR_A256GCM 
"eyJhbGciOiAiZGlyIiwgImVuYyI6ICJBMjU2R0NNIn0.."
+
+apr_byte_t oidc_util_jwt_create(request_rec *r, const char *secret, json_t 
*payload,
+               char **compact_encoded_jwt, apr_byte_t strip_header) {
 
        apr_byte_t rv = FALSE;
        oidc_jose_error_t err;
@@ -142,8 +144,7 @@
        oidc_jwt_t *jwt = NULL;
        oidc_jwt_t *jwe = NULL;
 
-       if (oidc_util_create_symmetric_key(r, secret, 0, OIDC_JOSE_ALG_SHA256,
-                       FALSE, &jwk) == FALSE)
+       if (oidc_util_create_symmetric_key(r, secret, 0, OIDC_JOSE_ALG_SHA256, 
FALSE, &jwk) == FALSE)
                goto end;
 
        jwt = oidc_jwt_new(r->pool, TRUE, FALSE);
@@ -170,12 +171,14 @@
        jwe->header.enc = apr_pstrdup(r->pool, CJOSE_HDR_ENC_A256GCM);
 
        const char *cser = oidc_jwt_serialize(r->pool, jwt, &err);
-       if (oidc_jwt_encrypt(r->pool, jwe, jwk, cser, compact_encoded_jwt, &err)
-                       == FALSE) {
+       if (oidc_jwt_encrypt(r->pool, jwe, jwk, cser, compact_encoded_jwt, 
&err) == FALSE) {
                oidc_error(r, "encrypting JWT failed: %s", 
oidc_jose_e2s(r->pool, err));
                goto end;
        }
 
+       if (strip_header == TRUE)
+               *compact_encoded_jwt += strlen(OIDC_JWT_HDR_DIR_A256GCM);
+
        rv = TRUE;
 
 end:
@@ -192,11 +195,10 @@
        return rv;
 }
 
-apr_byte_t oidc_util_jwt_verify(request_rec *r, const char *secret,
-               const char *compact_encoded_jwt, json_t **result) {
+apr_byte_t oidc_util_jwt_verify(request_rec *r, const char *secret, const char 
*compact_encoded_jwt,
+               json_t **result, apr_byte_t stripped_header) {
 
-       oidc_debug(r, "enter: JWT header=%s",
-                       oidc_proto_peek_jwt_header(r, compact_encoded_jwt, 
NULL));
+       oidc_debug(r, "enter: JWT header=%s", oidc_proto_peek_jwt_header(r, 
compact_encoded_jwt, NULL));
 
        apr_byte_t rv = FALSE;
        oidc_jose_error_t err;
@@ -204,15 +206,17 @@
        oidc_jwk_t *jwk = NULL;
        oidc_jwt_t *jwt = NULL;
 
-       if (oidc_util_create_symmetric_key(r, secret, 0, OIDC_JOSE_ALG_SHA256,
-                       FALSE, &jwk) == FALSE)
+       if (oidc_util_create_symmetric_key(r, secret, 0, OIDC_JOSE_ALG_SHA256, 
FALSE, &jwk) == FALSE)
                goto end;
 
        apr_hash_t *keys = apr_hash_make(r->pool);
        apr_hash_set(keys, "", APR_HASH_KEY_STRING, jwk);
 
-       if (oidc_jwt_parse(r->pool, compact_encoded_jwt, &jwt, keys, &err)
-                       == FALSE) {
+       if (stripped_header == TRUE)
+               compact_encoded_jwt =
+                               apr_pstrcat(r->pool, OIDC_JWT_HDR_DIR_A256GCM, 
compact_encoded_jwt, NULL);
+
+       if (oidc_jwt_parse(r->pool, compact_encoded_jwt, &jwt, keys, &err) == 
FALSE) {
                oidc_error(r, "parsing JWT failed: %s", oidc_jose_e2s(r->pool, 
err));
                goto end;
        }
@@ -363,6 +367,87 @@
 }
 
 /*
+ * JavaScript escape a string
+ */
+char* oidc_util_javascript_escape(apr_pool_t *pool, const char *s) {
+    const char *cp;
+    char *output;
+    size_t outputlen;
+    int i;
+
+    if (s == NULL) {
+        return NULL;
+    }
+
+    outputlen = 0;
+    for (cp = s; *cp; cp++) {
+        switch (*cp) {
+        case '\'':
+        case '"':
+        case '\\':
+        case '/':
+        case 0x0D:
+        case 0x0A:
+            outputlen += 2;
+            break;
+        case '<':
+        case '>':
+            outputlen += 4;
+            break;
+        default:
+            outputlen += 1;
+            break;
+        }
+    }
+
+    i = 0;
+    output = apr_palloc(pool, outputlen + 1);
+    for (cp = s; *cp; cp++) {
+        switch (*cp) {
+        case '\'':
+            (void)strcpy(&output[i], "\\'");
+            i += 2;
+            break;
+        case '"':
+            (void)strcpy(&output[i], "\\\"");
+            i += 2;
+            break;
+        case '\\':
+            (void)strcpy(&output[i], "\\\\");
+            i += 2;
+            break;
+        case '/':
+            (void)strcpy(&output[i], "\\/");
+            i += 2;
+            break;
+        case 0x0D:
+            (void)strcpy(&output[i], "\\r");
+            i += 2;
+            break;
+        case 0x0A:
+            (void)strcpy(&output[i], "\\n");
+            i += 2;
+            break;
+        case '<':
+            (void)strcpy(&output[i], "\\x3c");
+            i += 4;
+            break;
+        case '>':
+            (void)strcpy(&output[i], "\\x3e");
+            i += 4;
+            break;
+        default:
+            output[i] = *cp;
+            i += 1;
+            break;
+        }
+    }
+    output[i] = '\0';
+    return output;
+}
+
+
+/*
  * get the URL scheme that is currently being accessed
  */
 static const char* oidc_get_current_url_scheme(const request_rec *r) {
@@ -388,6 +473,27 @@
 }
 
 /*
+ * get the Port part that is currently being accessed
+ */
+static const char* oidc_get_port_from_host(    const char *host_hdr){
+       char *p = NULL;
+       char *i = NULL;
+
+       if (host_hdr) {
+               if (host_hdr[0]=='[') {
+                       i = strchr(host_hdr, ']');
+                       p = strchr(i, OIDC_CHAR_COLON);
+               } else {
+                       p = strchr(host_hdr, OIDC_CHAR_COLON);
+               }
+       }
+       if (p)
+               return p;
+       else
+               return NULL;
+}
+
+/*
  * get the URL port that is currently being accessed
  */
 static const char* oidc_get_current_url_port(const request_rec *r,
@@ -407,7 +513,7 @@
         */
        const char *host_hdr = oidc_util_hdr_in_x_forwarded_host_get(r);
        if (host_hdr) {
-               port_str = strchr(host_hdr, OIDC_CHAR_COLON);
+               port_str = oidc_get_port_from_host(host_hdr);
                if (port_str)
                        port_str++;
                return port_str;
@@ -419,7 +525,7 @@
         */
        host_hdr = oidc_util_hdr_in_host_get(r);
        if (host_hdr) {
-               port_str = strchr(host_hdr, OIDC_CHAR_COLON);
+               port_str = oidc_get_port_from_host(host_hdr);
                if (port_str) {
                        port_str++;
                        return port_str;
@@ -452,13 +558,22 @@
  */
 const char* oidc_get_current_url_host(request_rec *r) {
        const char *host_str = oidc_util_hdr_in_x_forwarded_host_get(r);
+    char *p = NULL;
+       char *i = NULL;
        if (host_str == NULL)
                host_str = oidc_util_hdr_in_host_get(r);
        if (host_str) {
                host_str = apr_pstrdup(r->pool, host_str);
-               char *p = strchr(host_str, OIDC_CHAR_COLON);
-               if (p != NULL)
-                       *p = '\0';
+
+               if (host_str[0] == '[') {
+                       i= strchr(host_str, ']');
+                       p = strchr(i, OIDC_CHAR_COLON);
+               } else {
+                       p = strchr(host_str, OIDC_CHAR_COLON);
+               }
+
+       if (p != NULL)
+               *p = '\0';
        } else {
                /* no Host header, HTTP 1.0 */
                host_str = ap_get_server_name(r);
diff -urN '--exclude=CVS' '--exclude=.cvsignore' '--exclude=.svn' 
'--exclude=.svnignore' old/mod_auth_openidc-2.4.8.2/test/test.c 
new/mod_auth_openidc-2.4.9/test/test.c
--- old/mod_auth_openidc-2.4.8.2/test/test.c    2021-05-07 16:06:34.000000000 
+0200
+++ new/mod_auth_openidc-2.4.9/test/test.c      2021-07-22 18:30:00.000000000 
+0200
@@ -1285,6 +1285,16 @@
        TST_ASSERT_STR("test_current_url (8)", url,
                        
"http://remotehost:8380/private/?foo=bar&param1=value1";);
 
+       apr_table_set(r->headers_in, "Host", 
"[fd04:41b1:1170:28:16b0:446b:9fb7:7118]:8380");
+       url = oidc_get_current_url(r);
+       TST_ASSERT_STR("test_current_url (9)", url,
+                       
"http://[fd04:41b1:1170:28:16b0:446b:9fb7:7118]:8380/private/?foo=bar&param1=value1";);
+
+       apr_table_set(r->headers_in, "Host", 
"[fd04:41b1:1170:28:16b0:446b:9fb7:7118]");
+       url = oidc_get_current_url(r);
+       TST_ASSERT_STR("test_current_url (10)", url,
+                       
"http://[fd04:41b1:1170:28:16b0:446b:9fb7:7118]/private/?foo=bar&param1=value1";);
+
        return 0;
 }
 

Reply via email to