From d728b305c8c8e97b4434a75e5b47e73fa287cc51 Mon Sep 17 00:00:00 2001 From: Mathieu Baudier Date: Tue, 13 Nov 2018 12:14:52 +0100 Subject: [PATCH] Make SSL client auth safer --- .../argeo/cms/auth/HttpSessionLoginModule.java | 15 +++++++++------ .../org/argeo/cms/internal/kernel/Activator.java | 4 ++++ .../src/org/argeo/node/NodeConstants.java | 5 +++++ 3 files changed, 18 insertions(+), 6 deletions(-) diff --git a/org.argeo.cms/src/org/argeo/cms/auth/HttpSessionLoginModule.java b/org.argeo.cms/src/org/argeo/cms/auth/HttpSessionLoginModule.java index 48220a868..61268ca34 100644 --- a/org.argeo.cms/src/org/argeo/cms/auth/HttpSessionLoginModule.java +++ b/org.argeo.cms/src/org/argeo/cms/auth/HttpSessionLoginModule.java @@ -21,6 +21,7 @@ import javax.servlet.http.HttpSession; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.argeo.cms.CmsException; +import org.argeo.cms.internal.kernel.Activator; import org.osgi.framework.BundleContext; import org.osgi.framework.FrameworkUtil; import org.osgi.framework.InvalidSyntaxException; @@ -198,16 +199,18 @@ public class HttpSessionLoginModule implements LoginModule { private void extractClientCertificate(HttpServletRequest req) { X509Certificate[] certs = (X509Certificate[]) req.getAttribute("javax.servlet.request.X509Certificate"); - if (null != certs && certs.length > 0) { + if (null != certs && certs.length > 0) {// Servlet container verified the client certificate sharedState.put(CmsAuthUtils.SHARED_STATE_NAME, certs[0].getSubjectX500Principal().getName()); sharedState.put(CmsAuthUtils.SHARED_STATE_CERTIFICATE_CHAIN, certs); - } else { - // When client has been verified by reverse proxy - String certDn = req.getHeader("SSL_CLIENT_S_DN"); + } // Reverse proxy verified the client certificate + String clientDnHttpHeader = Activator.getHttpProxySslHeader(); + if (clientDnHttpHeader != null) { + String certDn = req.getHeader(clientDnHttpHeader); + // TODO retrieve more cf. https://httpd.apache.org/docs/current/mod/mod_ssl.html + // String issuerDn = req.getHeader("SSL_CLIENT_I_DN"); if (certDn != null) { sharedState.put(CmsAuthUtils.SHARED_STATE_NAME, certDn); - String issuerDn = req.getHeader("SSL_CLIENT_I_DN"); - sharedState.put(CmsAuthUtils.SHARED_STATE_CERTIFICATE_CHAIN, issuerDn); + sharedState.put(CmsAuthUtils.SHARED_STATE_CERTIFICATE_CHAIN, ""); } } } diff --git a/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java b/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java index 01e842caa..5ef545e6f 100644 --- a/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java +++ b/org.argeo.cms/src/org/argeo/cms/internal/kernel/Activator.java @@ -169,6 +169,10 @@ public class Activator implements BundleActivator { return (UserAdmin) getNodeUserAdmin(); } + public static String getHttpProxySslHeader() { + return KernelUtils.getFrameworkProp(NodeConstants.HTTP_PROXY_SSL_DN); + } + private static NodeUserAdmin getNodeUserAdmin() { NodeUserAdmin res; try { diff --git a/org.argeo.node.api/src/org/argeo/node/NodeConstants.java b/org.argeo.node.api/src/org/argeo/node/NodeConstants.java index cb87f30b4..31029d991 100644 --- a/org.argeo.node.api/src/org/argeo/node/NodeConstants.java +++ b/org.argeo.node.api/src/org/argeo/node/NodeConstants.java @@ -101,6 +101,11 @@ public interface NodeConstants { // HTTP String HTTP_PORT = "org.osgi.service.http.port"; String HTTP_PORT_SECURE = "org.osgi.service.http.port.secure"; + /** + * The HTTP header used to convey the DN of a client verified by a reverse + * proxy. Typically SSL_CLIENT_S_DN for Apache. + */ + String HTTP_PROXY_SSL_DN = "argeo.http.proxy.ssl.dn"; /* * PIDs -- 2.30.2