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);

Reply via email to