Blame SOURCES/0001-Modify-am_handler-setup-to-run-before-mod_proxy.patch

a860d0
From e09a28a30e13e5c22b481010f26b4a7743a09280 Mon Sep 17 00:00:00 2001
a860d0
From: John Dennis <jdennis@redhat.com>
a860d0
Date: Tue, 5 Mar 2019 10:15:48 +0100
a860d0
Subject: [PATCH] Modify am_handler setup to run before mod_proxy
a860d0
a860d0
The way the ECP flow works is that when a client initiates the flow, the
a860d0
SP's response is HTTP 200, but not the requested content, but a signed XML
a860d0
document that contains the "samlp:AuthnRequest" element. The idea is that
a860d0
the ECP client would then determine the IDP and send the document to the
a860d0
IDP, get a samlp:Response and convey that to the SP to get access to the
a860d0
protected resource.
a860d0
a860d0
Internally, the auth check which is normally done with am_check_uid() set to
a860d0
apache's ap_hook_check_user_id() hook, just responds with OK, so it pretends
a860d0
to authenticate the user. Then in the usual flow, the request reaches the
a860d0
ap_hook_handler which handles the request. There in the pipeline, mellon
a860d0
registers functions am_handler() which should run first (APR_HOOK_FIRST),
a860d0
determine that this request is an ECP one and return the ECP AuthnRequest
a860d0
document. But in case the proxy module is also in the picture, the proxy
a860d0
module "races" for who gets to be the first to handle the request in the
a860d0
pipeline and wins. Therefore, the request reaches the protected resource
a860d0
via mod_proxy and returns it.
a860d0
a860d0
This fix modifies the ap_hook_handler() call to explicitly run before
a860d0
handlers from mod_proxy.c
a860d0
a860d0
To reproduce the bug:
a860d0
0) Have a SP with mellon connected to a Keycloak IDP (or any other IDP I
a860d0
   guess). In the example below, my SAML SP is saml.federation.test
a860d0
1) Set a Location protected by mellon that proxies requests to another
a860d0
   URL. For example:
a860d0
a860d0
    ProxyPass         /sp-proxy  http://app.federation.test/example_app/
a860d0
    <Location /sp-proxy>
a860d0
        AuthType Mellon
a860d0
        MellonEnable auth
a860d0
        Require valid-user
a860d0
    </Location>
a860d0
a860d0
2) call:
a860d0
 curl -L -H "Accept: application/vnd.paos+xml" \
a860d0
         -H 'PAOS: ver="urn:liberty:paos:2003-08";"urn:oasis:names:tc:SAML:2.0:profiles:SSO:ecp"' \
a860d0
          http://saml.federation.test/sp-proxy
a860d0
a860d0
Before the patch, you would see whatever is served from the proxied
a860d0
page. With the patch, you should get back a XML document with a
a860d0
samlp:AuthnRequest.
a860d0
---
a860d0
 mod_auth_mellon.c | 8 +++++++-
a860d0
 1 file changed, 7 insertions(+), 1 deletion(-)
a860d0
a860d0
diff --git a/mod_auth_mellon.c b/mod_auth_mellon.c
a860d0
index 74bd328..5330f48 100644
a860d0
--- a/mod_auth_mellon.c
a860d0
+++ b/mod_auth_mellon.c
a860d0
@@ -207,6 +207,12 @@ static int am_create_request(request_rec *r)
a860d0
 
a860d0
 static void register_hooks(apr_pool_t *p)
a860d0
 {
a860d0
+    /* Our handler needs to run before mod_proxy so that it can properly
a860d0
+     * return ECP AuthnRequest messages when running as a reverse proxy.
a860d0
+     * See: https://github.com/Uninett/mod_auth_mellon/pull/196
a860d0
+     */
a860d0
+    static const char * const run_handler_before[]={ "mod_proxy.c", NULL };
a860d0
+
a860d0
     ap_hook_access_checker(am_auth_mellon_user, NULL, NULL, APR_HOOK_MIDDLE);
a860d0
     ap_hook_check_user_id(am_check_uid, NULL, NULL, APR_HOOK_MIDDLE);
a860d0
     ap_hook_post_config(am_global_init, NULL, NULL, APR_HOOK_MIDDLE);
a860d0
@@ -222,7 +228,7 @@ static void register_hooks(apr_pool_t *p)
a860d0
      * Therefore this hook must run before any handler that may check
a860d0
      * r->handler and decide that it is the only handler for this URL.
a860d0
      */
a860d0
-    ap_hook_handler(am_handler, NULL, NULL, APR_HOOK_FIRST);
a860d0
+    ap_hook_handler(am_handler, NULL, run_handler_before, APR_HOOK_FIRST);
a860d0
 
a860d0
 #ifdef ENABLE_DIAGNOSTICS
a860d0
     ap_hook_open_logs(am_diag_log_init,NULL,NULL,APR_HOOK_MIDDLE);
a860d0
-- 
a860d0
2.19.2
a860d0