This is an automated email from the ASF dual-hosted git repository. jleroux pushed a commit to branch trunk in repository https://gitbox.apache.org/repos/asf/ofbiz-framework.git
The following commit(s) were added to refs/heads/trunk by this push: new 921c0b82c1 Fixed: Support SSLHostConfig in CatalinaContainer (OFBIZ-12835) (#649) 921c0b82c1 is described below commit 921c0b82c1a3bc8088434194b82d8ef261170fb6 Author: Danny Trunk <dtrun...@gmail.com> AuthorDate: Fri Aug 4 17:09:57 2023 +0200 Fixed: Support SSLHostConfig in CatalinaContainer (OFBIZ-12835) (#649) Co-authored-by: Danny Trunk <d...@zyres.com> --- framework/catalina/ofbiz-component.xml | 40 +++++++----- .../catalina/container/CatalinaContainer.java | 75 +++++++++++++++++++++- 2 files changed, 99 insertions(+), 16 deletions(-) diff --git a/framework/catalina/ofbiz-component.xml b/framework/catalina/ofbiz-component.xml index c3712b7426..c15c2acf86 100644 --- a/framework/catalina/ofbiz-component.xml +++ b/framework/catalina/ofbiz-component.xml @@ -157,17 +157,22 @@ under the License. <property name="compressibleMimeType" value="text/html,text/xml,text/plain,text/css,application/javascript,application/json"/> <!-- SSL connector attributes --> <property name="sslImplementationName" value="org.apache.tomcat.util.net.jsse.JSSEImplementation"/> - <property name="algorithm" value="SunX509"/> - <!-- the clientAuth to "want" in order to receive certs from the client; - note that this isn't set this way by default because with certain browsers - (like Safari) it breaks access via HTTPS, so until that problem is fixed - the default will be false - <property name="clientAuth" value="false"/> - --> - <property name="keystoreFile" value="framework/base/config/ofbizssl.jks"/> - <property name="keystoreType" value="JKS"/> - <property name="keyAlias" value="ofbiz"/> - <property name="keyPass" value="changeit"/> + <property name="default" value="sslHostConfig"> + <property name="keyManagerAlgorithm" value="SunX509"/> + <!-- the certificateVerification to "want" in order to receive certs from the client; + note that this isn't set this way by default because with certain browsers + (like Safari) it breaks access via HTTPS, so until that problem is fixed + the default will be false + <property name="certificateVerification" value="false"/> + --> + <property name="default" value="certificate"> + <property name="certificateType" value="RSA"/> + <property name="certificateKeystoreFile" value="framework/base/config/ofbizssl.jks"/> + <property name="certificateKeystoreType" value="JKS"/> + <property name="certificateKeyAlias" value="ofbiz"/> + <property name="certificateKeyPassword" value="changeit"/> + </property> + </property> </property> </container> <container name="catalina-container-test" loaders="test" class="org.apache.ofbiz.catalina.container.CatalinaContainer"> @@ -225,10 +230,15 @@ under the License. <property name="compression" value="on"/> <property name="compressibleMimeType" value="text/html,text/xml,text/plain,text/css,application/javascript,application/json"/> <property name="sslImplementationName" value="org.apache.tomcat.util.net.jsse.JSSEImplementation"/> - <property name="algorithm" value="SunX509"/> - <property name="keystoreFile" value="framework/base/config/ofbizssl.jks"/> - <property name="keystorePass" value="changeit"/> - <property name="keystoreType" value="JKS"/> + <property name="default" value="sslHostConfig"> + <property name="keyManagerAlgorithm" value="SunX509"/> + <property name="default" value="certificate"> + <property name="certificateType" value="RSA"/> + <property name="certificateKeystoreFile" value="framework/base/config/ofbizssl.jks"/> + <property name="certificateKeystorePassword" value="changeit"/> + <property name="certificateKeystoreType" value="JKS"/> + </property> + </property> </property> </container> <!-- diff --git a/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java b/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java index 06e4929fa4..d439d50d79 100644 --- a/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java +++ b/framework/catalina/src/main/java/org/apache/ofbiz/catalina/container/CatalinaContainer.java @@ -77,6 +77,8 @@ import org.apache.tomcat.JarScanner; import org.apache.tomcat.util.IntrospectionUtils; import org.apache.tomcat.util.descriptor.web.FilterDef; import org.apache.tomcat.util.descriptor.web.FilterMap; +import org.apache.tomcat.util.net.SSLHostConfig; +import org.apache.tomcat.util.net.SSLHostConfigCertificate; import org.apache.tomcat.util.scan.StandardJarScanner; import org.xml.sax.SAXException; @@ -431,7 +433,8 @@ public class CatalinaContainer implements Container { connectorProp.properties().values().stream() .filter(prop -> { String name = prop.name(); - return !"protocol".equals(name) && !"upgradeProtocol".equals(name) && !"port".equals(name); + String value = prop.value(); + return !"protocol".equals(name) && !"upgradeProtocol".equals(name) && !"port".equals(name) && !"sslHostConfig".equals(value); }) .forEach(prop -> { String name = prop.name(); @@ -447,9 +450,79 @@ public class CatalinaContainer implements Container { Debug.logWarning("Tomcat " + connector + ": ignored parameter " + name, MODULE); } }); + prepareSslHostConfigs(connector, connectorProp).forEach(connector::addSslHostConfig); return connector; } + private static List<SSLHostConfig> prepareSslHostConfigs(Connector connector, Configuration.Property connectorProp) { + return connectorProp.getPropertiesWithValue("sslHostConfig").stream() + .filter(sslHostConfigProp -> UtilValidate.isNotEmpty(sslHostConfigProp.properties())) + .map(sslHostConfigProp -> prepareSslHostConfig(connector, sslHostConfigProp)) + .collect(Collectors.toList()); + } + + private static SSLHostConfig prepareSslHostConfig(Connector connector, Configuration.Property sslHostConfigProp) { + SSLHostConfig sslHostConfig = new SSLHostConfig(); + sslHostConfigProp.properties().values().stream() + .filter(prop -> { + String value = prop.value(); + return !"certificate".equals(value); + }) + .forEach(prop -> { + String name = prop.name(); + String value = prop.value(); + if (IntrospectionUtils.setProperty(sslHostConfig, name, value)) { + if (name.indexOf("Pass") != -1) { + // this property may be a password, do not include its value in the logs + Debug.logInfo("Tomcat " + connector + " " + sslHostConfig.getHostName() + ": set " + name, MODULE); + } else { + Debug.logInfo("Tomcat " + connector + " " + sslHostConfig.getHostName() + ": set " + name + "=" + value, MODULE); + } + } else { + Debug.logWarning("Tomcat " + connector + " " + sslHostConfig.getHostName() + ": ignored parameter " + name, MODULE); + } + }); + prepareSslHostConfigCerts(connector, sslHostConfig, sslHostConfigProp).forEach(sslHostConfig::addCertificate); + return sslHostConfig; + } + + private static List<SSLHostConfigCertificate> prepareSslHostConfigCerts(Connector connector, SSLHostConfig sslHostConfig, + Configuration.Property sslHostConfigProp) { + return sslHostConfigProp.getPropertiesWithValue("certificate").stream() + .filter(certProp -> UtilValidate.isNotEmpty(certProp.properties())) + .map(certProp -> prepareSslHostConfigCert(connector, sslHostConfig, certProp)) + .collect(Collectors.toList()); + } + + private static SSLHostConfigCertificate prepareSslHostConfigCert(Connector connector, SSLHostConfig sslHostConfig, + Configuration.Property certProp) { + String certificateType = ContainerConfig.getPropertyValue(certProp, "certificateType", SSLHostConfigCertificate.DEFAULT_TYPE.name()); + SSLHostConfigCertificate sslHostConfigCert = new SSLHostConfigCertificate(sslHostConfig, + SSLHostConfigCertificate.Type.valueOf(certificateType)); + certProp.properties().values().stream() + .filter(prop -> { + String name = prop.name(); + return !"certificateType".equals(name); + }) + .forEach(prop -> { + String name = prop.name(); + String value = prop.value(); + if (IntrospectionUtils.setProperty(sslHostConfigCert, name, value)) { + if (name.indexOf("Pass") != -1) { + // this property may be a password, do not include its value in the logs + Debug.logInfo("Tomcat " + connector + " " + sslHostConfig.getHostName() + " certificate: set " + name, MODULE); + } else { + Debug.logInfo("Tomcat " + connector + " " + sslHostConfig.getHostName() + " certificate: set " + name + "=" + value, + MODULE); + } + } else { + Debug.logWarning("Tomcat " + connector + " " + sslHostConfig.getHostName() + " certificate: ignored parameter " + name, + MODULE); + } + }); + return sslHostConfigCert; + } + private static void loadWebapps(Tomcat tomcat, Configuration configuration, Configuration.Property clusterProp) { ScheduledExecutorService executor = ExecutionPool.getScheduledExecutor(new ThreadGroup(MODULE), "catalina-startup", Runtime.getRuntime().availableProcessors(), 0, true);