From 5c77dd3a1c4c5a092839fcc65bc076f18b35336c Mon Sep 17 00:00:00 2001
From: Felix Sidokhine <felix.sidokhine@randstad.ca>
Date: Sat, 30 May 2020 14:04:21 +0300
Subject: [PATCH] upgrade back to tomcat 10M5 - fixed issue with SSL

---
 .../main/java/net/jami/jams/ca/JamsCA.java    |  8 +++++-
 .../jami/jams/ca/workers/crl/CRLWorker.java   |  8 +++++-
 .../src/main/java/launcher/AppStarter.java    |  1 +
 .../java/net/jami/jams/server/Server.java     |  2 +-
 .../server/core/TomcatConnectorFactory.java   | 26 +++++++++----------
 .../jami/jams/server/core/TomcatLauncher.java | 12 ++++++---
 pom.xml                                       |  2 +-
 7 files changed, 38 insertions(+), 21 deletions(-)

diff --git a/jams-ca/src/main/java/net/jami/jams/ca/JamsCA.java b/jams-ca/src/main/java/net/jami/jams/ca/JamsCA.java
index 6755e212..f4daa077 100644
--- a/jams-ca/src/main/java/net/jami/jams/ca/JamsCA.java
+++ b/jams-ca/src/main/java/net/jami/jams/ca/JamsCA.java
@@ -140,7 +140,13 @@ public class JamsCA implements CertificateAuthority {
     @Override
     public boolean shutdownThreads() {
         //Unsafe but acceptable.
-        crlWorker.stop();
+        crlWorker.getStop().set(true);
+        crlWorker.interrupt();
+        Thread.State state = crlWorker.getState();
+        while(!state.equals(Thread.State.TERMINATED)){
+            state = crlWorker.getState();
+        }
+        crlWorker = null;
         ocspWorker.stop();
         return true;
     }
diff --git a/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java b/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java
index 08a08136..5dea7010 100644
--- a/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java
+++ b/jams-ca/src/main/java/net/jami/jams/ca/workers/crl/CRLWorker.java
@@ -23,6 +23,7 @@
 package net.jami.jams.ca.workers.crl;
 
 import lombok.Getter;
+import lombok.Setter;
 import lombok.extern.slf4j.Slf4j;
 import net.jami.jams.ca.JamsCA;
 import net.jami.jams.ca.workers.X509Worker;
@@ -36,6 +37,7 @@ import org.bouncycastle.operator.jcajce.JcaContentSignerBuilder;
 import java.security.PrivateKey;
 import java.security.cert.X509Certificate;
 import java.util.Date;
+import java.util.concurrent.atomic.AtomicBoolean;
 import java.util.concurrent.atomic.AtomicReference;
 
 @Slf4j
@@ -44,6 +46,9 @@ public class CRLWorker extends X509Worker<RevocationRequest> {
     @Getter
     private AtomicReference<X509CRLHolder> existingCRL = null;
 
+    @Getter @Setter
+    private AtomicBoolean stop = new AtomicBoolean(false);
+
     public CRLWorker(PrivateKey privateKey, X509Certificate certificate) {
         super(privateKey, certificate);
         this.setDaemon(true);
@@ -74,7 +79,7 @@ public class CRLWorker extends X509Worker<RevocationRequest> {
     @Override
     public void run() {
         boolean needsRefresh = false;
-        while(true){
+        while(!stop.get()){
             try{
                 while(getInput().isEmpty()){
                     if(needsRefresh){
@@ -97,5 +102,6 @@ public class CRLWorker extends X509Worker<RevocationRequest> {
                 log.error("An error has occured in the CRL signing thread: " + e.toString());
             }
         }
+        log.info("Stopped CRL Worker Thread...");
     }
 }
diff --git a/jams-launcher/src/main/java/launcher/AppStarter.java b/jams-launcher/src/main/java/launcher/AppStarter.java
index d19d7dd1..c91ad52b 100644
--- a/jams-launcher/src/main/java/launcher/AppStarter.java
+++ b/jams-launcher/src/main/java/launcher/AppStarter.java
@@ -87,6 +87,7 @@ public class AppStarter extends Thread {
                 }
                 if(doUpdate.get()){
                     Server.tomcatLauncher.stopTomcat();
+                    LibraryLoader.classLoader.destroy();
                     //This will trigger a force reload of the lib.
                     LibraryLoader.loadlibs(System.getProperty("user.dir"), AppStarter.class);
                     server = ServerLoader.loadServer(appUpdater, Integer.toString(port), serverCertificate, serverPrivateKey);
diff --git a/jams-server/src/main/java/net/jami/jams/server/Server.java b/jams-server/src/main/java/net/jami/jams/server/Server.java
index 536f915d..4d7b439d 100644
--- a/jams-server/src/main/java/net/jami/jams/server/Server.java
+++ b/jams-server/src/main/java/net/jami/jams/server/Server.java
@@ -77,7 +77,7 @@ public class Server {
     }
 
 
-    public static void main(String[] args) {
+    public void main(String[] args) {
         //Start tomcat.
         switch (args.length) {
             case 0:
diff --git a/jams-server/src/main/java/net/jami/jams/server/core/TomcatConnectorFactory.java b/jams-server/src/main/java/net/jami/jams/server/core/TomcatConnectorFactory.java
index cb661365..fc0ba39f 100644
--- a/jams-server/src/main/java/net/jami/jams/server/core/TomcatConnectorFactory.java
+++ b/jams-server/src/main/java/net/jami/jams/server/core/TomcatConnectorFactory.java
@@ -24,6 +24,8 @@ package net.jami.jams.server.core;
 
 import lombok.extern.slf4j.Slf4j;
 import org.apache.catalina.connector.Connector;
+import org.apache.tomcat.util.net.SSLHostConfig;
+import org.apache.tomcat.util.net.SSLHostConfigCertificate;
 
 import java.io.File;
 
@@ -33,25 +35,26 @@ public class TomcatConnectorFactory {
     public static Connector getSSLConnectorWithTrustStore(String certificateFile, String keyFile, int port) {
         log.info(System.getProperty("user.dir") + File.separator + "keystore.jks");
         Connector connector = getSSLConnectorWithoutTrustStore(certificateFile, keyFile, port);
-        connector.setAttribute("truststoreFile", System.getProperty("user.dir") + File.separator + "keystore.jks");
-        connector.setAttribute("clientAuth", "optional");
-        connector.setAttribute("truststorePassword", "changeit");
+        //connector.setAttribute("truststoreFile", System.getProperty("user.dir") + File.separator + "keystore.jks");
+        //connector.setAttribute("clientAuth", "optional");
+        //connector.setAttribute("truststorePassword", "changeit");
         return connector;
     }
 
     public static Connector getSSLConnectorWithoutTrustStore(String certificateFile, String keyFile, int port) {
         //Check if trust store exists or create it if necessary.
         Connector connector = new Connector();
+        SSLHostConfig sslConfig = new SSLHostConfig();
+        SSLHostConfigCertificate sslHostConfigCertificate = new SSLHostConfigCertificate(sslConfig, SSLHostConfigCertificate.Type.RSA);
+        sslHostConfigCertificate.setCertificateFile(System.getProperty("user.dir") + File.separator + certificateFile);
+        sslHostConfigCertificate.setCertificateKeyFile(System.getProperty("user.dir") + File.separator + keyFile);
+        sslConfig.addCertificate(sslHostConfigCertificate);
+        sslConfig.setProtocols("TLSv1.3");
+        connector.addSslHostConfig(sslConfig);
         connector.setPort(port);
         connector.setSecure(true);
         connector.setScheme("https");
-        connector.setAttribute("protocol", "org.apache.coyote.http11.Http11AprProtocol");
-        connector.setAttribute("SSLCertificateFile", System.getProperty("user.dir") + File.separator + certificateFile);
-        connector.setAttribute("SSLCertificateKeyFile", System.getProperty("user.dir") + File.separator + keyFile);
-        connector.setAttribute("protocol", "HTTP/1.1");
-        connector.setAttribute("sslProtocol", "TLS");
-        connector.setAttribute("maxThreads", "200");
-        connector.setAttribute("SSLEnabled", true);
+        connector.setProperty("SSLEnabled", "true");
         return connector;
     }
 
@@ -60,9 +63,6 @@ public class TomcatConnectorFactory {
         Connector connector = new Connector();
         connector.setPort(port);
         connector.setScheme("http");
-        connector.setAttribute("protocol", "org.apache.coyote.http11.Http11NioProtocol");
-        connector.setAttribute("protocol", "HTTP/1.1");
-        connector.setAttribute("maxThreads", "200");
         return connector;
     }
 
diff --git a/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java b/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java
index c3c8b9f9..6d440e06 100644
--- a/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java
+++ b/jams-server/src/main/java/net/jami/jams/server/core/TomcatLauncher.java
@@ -25,10 +25,13 @@ package net.jami.jams.server.core;
 
 import lombok.extern.slf4j.Slf4j;
 import net.jami.jams.ca.JamsCA;
+import net.jami.jams.common.utils.LibraryLoader;
 import net.jami.jams.server.Server;
 import org.apache.catalina.WebResourceRoot;
 import org.apache.catalina.connector.Connector;
 import org.apache.catalina.core.StandardContext;
+import org.apache.catalina.loader.WebappClassLoader;
+import org.apache.catalina.loader.WebappClassLoaderBase;
 import org.apache.catalina.startup.Tomcat;
 import org.apache.catalina.webresources.DirResourceSet;
 import org.apache.catalina.webresources.JarResourceSet;
@@ -48,9 +51,9 @@ import static net.jami.jams.server.Server.certificateAuthority;
 @Slf4j
 public class TomcatLauncher {
 
-    private Tomcat tomcat = new Tomcat();
-    private static Connector connector;
-    private static StandardContext context;
+    private final Tomcat tomcat = new Tomcat();
+    private Connector connector;
+    private StandardContext context;
 
     public TomcatLauncher(int port) {
         tomcat.getService().addConnector(TomcatConnectorFactory.getNoSSLConnector(port));
@@ -122,8 +125,9 @@ public class TomcatLauncher {
             synchronized (tomcat) {
                 certificateAuthority.shutdownThreads();
                 tomcat.stop();
-                tomcat.destroy();
                 context.destroy();
+                tomcat.destroy();
+                LibraryLoader.classLoader.destroy();
             }
         } catch (Exception e) {
             log.info("Failed to stop tomcat server with error {}", e.getMessage());
diff --git a/pom.xml b/pom.xml
index bfce65ea..556e86bd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -34,7 +34,7 @@
         <lombok.version>1.18.12</lombok.version>
         <log4j.version>1.7.30</log4j.version>
         <jupiter.api.version>5.7.0-M1</jupiter.api.version>
-        <tomcat.version>9.0.35</tomcat.version>
+        <tomcat.version>10.0.0-M5</tomcat.version>
         <map.struct.version>1.3.0.Final</map.struct.version>
         <maven.surefire.version>2.19.1</maven.surefire.version>
         <junit.surefire.version>1.1.0</junit.surefire.version>
-- 
GitLab