From dc222394a1426870395cfb5fede758a5f64e4116 Mon Sep 17 00:00:00 2001 From: Simon Brandhof Date: Sun, 1 Feb 2015 20:03:19 +0100 Subject: [PATCH] SONAR-6139 Upgrade Tomcat from 7.0.54 to 8.0.18 SONAR-6141 apply Mozilla recommandations for default ciphers (Intermediate Compatibility) --- pom.xml | 2 +- .../java/org/sonar/server/app/Connectors.java | 22 +++++++++++----- .../org/sonar/server/app/NullJarScanner.java | 17 +++++++++++-- .../org/sonar/server/app/StartupLogs.java | 17 +++++-------- .../java/org/sonar/server/app/Webapp.java | 3 --- .../sonar/server/app/NullJarScannerTest.java | 15 +++++++---- .../org/sonar/server/app/StartupLogsTest.java | 25 +++++++------------ .../src/main/assembly/conf/sonar.properties | 5 ++-- 8 files changed, 60 insertions(+), 46 deletions(-) diff --git a/pom.xml b/pom.xml index ee6a3b39404..e9d376243c1 100644 --- a/pom.xml +++ b/pom.xml @@ -74,7 +74,7 @@ 8.1.12.v20130726 1.0.13 1.7.5 - 7.0.57 + 8.0.18 1.4.2 UTF-8 3.0.5 diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/Connectors.java b/server/sonar-server/src/main/java/org/sonar/server/app/Connectors.java index ff6557bcfc1..83554f58773 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/Connectors.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/Connectors.java @@ -37,15 +37,25 @@ import java.util.Set; */ class Connectors { - private static final int DISABLED_PORT = -1; - static final String HTTP_PROTOCOL = "HTTP/1.1"; - static final String AJP_PROTOCOL = "AJP/1.3"; + public static final String PROP_HTTPS_CIPHERS = "sonar.web.https.ciphers"; + + /** + * Removes the weak ciphers that are provided by default in JVM + * We follow the recommendations from Mozilla (Intermediate Compatibility) + * https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29 + */ + public static final String DEFVAL_HTTPS_CIPHERS = "ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES256-GCM-SHA384:ECDHE-ECDSA-AES256-GCM-SHA384:DHE-RSA-AES128-GCM-SHA256:DHE-DSS-AES128-GCM-SHA256:kEDH+AESGCM:ECDHE-RSA-AES128-SHA256:ECDHE-ECDSA-AES128-SHA256:ECDHE-RSA-AES128-SHA:ECDHE-ECDSA-AES128-SHA:ECDHE-RSA-AES256-SHA384:ECDHE-ECDSA-AES256-SHA384:ECDHE-RSA-AES256-SHA:ECDHE-ECDSA-AES256-SHA:DHE-RSA-AES128-SHA256:DHE-RSA-AES128-SHA:DHE-DSS-AES128-SHA256:DHE-RSA-AES256-SHA256:DHE-DSS-AES256-SHA:DHE-RSA-AES256-SHA:AES128-GCM-SHA256:AES256-GCM-SHA384:AES128-SHA256:AES256-SHA256:AES128-SHA:AES256-SHA:AES:CAMELLIA:DES-CBC3-SHA:!aNULL:!eNULL:!EXPORT:!DES:!RC4:!MD5:!PSK:!aECDH:!EDH-DSS-DES-CBC3-SHA:!EDH-RSA-DES-CBC3-SHA:!KRB5-DES-CBC3-SHA"; + + public static final int DISABLED_PORT = -1; + public static final String HTTP_PROTOCOL = "HTTP/1.1"; + public static final String AJP_PROTOCOL = "AJP/1.3"; private Connectors() { + // only static stuff } static void configure(Tomcat tomcat, Props props) { - List connectors = new ArrayList(); + List connectors = new ArrayList<>(); connectors.addAll(Arrays.asList(newHttpConnector(props), newAjpConnector(props), newHttpsConnector(props))); connectors.removeAll(Collections.singleton(null)); @@ -61,7 +71,7 @@ class Connectors { if (connectors.isEmpty()) { throw new IllegalStateException("HTTP connectors are disabled"); } - Set ports = new HashSet(); + Set ports = new HashSet<>(); for (Connector connector : connectors) { int port = connector.getPort(); if (ports.contains(port)) { @@ -115,7 +125,7 @@ class Connectors { setConnectorAttribute(connector, "truststoreType", props.value("sonar.web.https.truststoreType", "JKS")); setConnectorAttribute(connector, "truststoreProvider", props.value("sonar.web.https.truststoreProvider")); setConnectorAttribute(connector, "clientAuth", props.value("sonar.web.https.clientAuth", "false")); - setConnectorAttribute(connector, "ciphers", props.value("sonar.web.https.ciphers")); + setConnectorAttribute(connector, "ciphers", props.value(PROP_HTTPS_CIPHERS, DEFVAL_HTTPS_CIPHERS)); // SSLv3 must not be enable because of Poodle vulnerability // See https://jira.codehaus.org/browse/SONAR-5860 setConnectorAttribute(connector, "sslEnabledProtocols", "TLSv1,TLSv1.1,TLSv1.2"); diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/NullJarScanner.java b/server/sonar-server/src/main/java/org/sonar/server/app/NullJarScanner.java index 4f8ac9e5312..db06ae1315f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/NullJarScanner.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/NullJarScanner.java @@ -19,18 +19,31 @@ */ package org.sonar.server.app; +import org.apache.tomcat.JarScanFilter; +import org.apache.tomcat.JarScanType; import org.apache.tomcat.JarScanner; import org.apache.tomcat.JarScannerCallback; import javax.servlet.ServletContext; -import java.util.Set; /** * Disable taglib and web-fragment.xml scanning of Tomcat. Should speed up startup. */ + class NullJarScanner implements JarScanner { + @Override - public void scan(ServletContext context, ClassLoader classloader, JarScannerCallback callback, Set jarsToSkip) { + public void scan(JarScanType jarScanType, ServletContext servletContext, JarScannerCallback jarScannerCallback) { // doing nothing is fast! } + + @Override + public JarScanFilter getJarScanFilter() { + return null; + } + + @Override + public void setJarScanFilter(JarScanFilter jarScanFilter) { + + } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/StartupLogs.java b/server/sonar-server/src/main/java/org/sonar/server/app/StartupLogs.java index 2e94f2c2d99..cec1a2ea69a 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/StartupLogs.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/StartupLogs.java @@ -58,17 +58,12 @@ class StartupLogs { } private void logHttps(Connector connector) { - StringBuilder additional = new StringBuilder(); + StringBuilder sb = new StringBuilder(); + sb.append("HTTPS connector enabled on port ").append(connector.getPort()); + ProtocolHandler protocol = connector.getProtocolHandler(); - if (protocol instanceof AbstractHttp11JsseProtocol) { - additional.append("| ciphers="); - String ciphers = ((AbstractHttp11JsseProtocol) protocol).getCiphers(); - if (StringUtils.isBlank(ciphers)) { - additional.append("JVM defaults"); - } else { - additional.append(ciphers); - } - } - log.info(String.format("HTTPS connector enabled on port %d %s", connector.getPort(), additional)); + String[] ciphers = ((AbstractHttp11JsseProtocol) protocol).getCiphersUsed(); + sb.append(" | ciphers=").append(StringUtils.join(ciphers, ",")); + log.info(sb.toString()); } } diff --git a/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java b/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java index e31e3a0e0c9..b32b009896f 100644 --- a/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java +++ b/server/sonar-server/src/main/java/org/sonar/server/app/Webapp.java @@ -51,12 +51,9 @@ class Webapp { context.setClearReferencesStopTimerThreads(false); context.setClearReferencesStopTimerThreads(false); context.setAntiResourceLocking(false); - context.setAntiJARLocking(false); context.setReloadable(false); context.setUseHttpOnly(true); - context.setProcessTlds(false); context.setTldValidation(false); - context.setTldNamespaceAware(false); context.setXmlValidation(false); context.setXmlNamespaceAware(false); context.setUseNaming(false); diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/NullJarScannerTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/NullJarScannerTest.java index 8977185a40e..5f24561f22b 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/app/NullJarScannerTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/app/NullJarScannerTest.java @@ -39,13 +39,14 @@ */ package org.sonar.server.app; +import org.apache.tomcat.JarScanFilter; +import org.apache.tomcat.JarScanType; import org.apache.tomcat.JarScannerCallback; import org.junit.Test; import javax.servlet.ServletContext; -import java.util.HashSet; - +import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.verifyZeroInteractions; @@ -53,9 +54,13 @@ public class NullJarScannerTest { @Test public void does_nothing() { ServletContext context = mock(ServletContext.class); - ClassLoader classloader = mock(ClassLoader.class); JarScannerCallback callback = mock(JarScannerCallback.class); - new NullJarScanner().scan(context, classloader, callback, new HashSet()); - verifyZeroInteractions(context, classloader, callback); + + NullJarScanner scanner = new NullJarScanner(); + + scanner.scan(JarScanType.PLUGGABILITY, context, callback); + verifyZeroInteractions(context, callback); + scanner.setJarScanFilter(mock(JarScanFilter.class)); + assertThat(scanner.getJarScanFilter()).isNull(); } } diff --git a/server/sonar-server/src/test/java/org/sonar/server/app/StartupLogsTest.java b/server/sonar-server/src/test/java/org/sonar/server/app/StartupLogsTest.java index 03bbbc06085..0fed81db6b5 100644 --- a/server/sonar-server/src/test/java/org/sonar/server/app/StartupLogsTest.java +++ b/server/sonar-server/src/test/java/org/sonar/server/app/StartupLogsTest.java @@ -21,7 +21,7 @@ package org.sonar.server.app; import org.apache.catalina.connector.Connector; import org.apache.catalina.startup.Tomcat; -import org.apache.coyote.http11.Http11Protocol; +import org.apache.coyote.http11.AbstractHttp11JsseProtocol; import org.junit.Test; import org.mockito.Mockito; import org.slf4j.Logger; @@ -58,22 +58,15 @@ public class StartupLogsTest { } @Test - public void logHttps_default_ciphers() throws Exception { - Connector connector = newConnector("HTTP/1.1", "https"); - when(tomcat.getService().findConnectors()).thenReturn(new Connector[] {connector}); - - sut.log(tomcat); - - verify(logger).info("HTTPS connector enabled on port 1234 | ciphers=JVM defaults"); - verifyNoMoreInteractions(logger); - } - - @Test - public void logHttps_overridden_ciphers() throws Exception { - Connector connector = newConnector("HTTP/1.1", "https"); - connector.setProtocolHandlerClassName("org.apache.coyote.http11.Http11Protocol"); - ((Http11Protocol) connector.getProtocolHandler()).setCiphers("SSL_RSA,TLS_RSA_WITH_RC4"); + public void logHttps() throws Exception { + Connector connector = mock(Connector.class, Mockito.RETURNS_DEEP_STUBS); when(tomcat.getService().findConnectors()).thenReturn(new Connector[] {connector}); + when(connector.getScheme()).thenReturn("https"); + when(connector.getProtocol()).thenReturn("HTTP/1.1"); + when(connector.getPort()).thenReturn(1234); + AbstractHttp11JsseProtocol protocol = mock(AbstractHttp11JsseProtocol.class); + when(connector.getProtocolHandler()).thenReturn(protocol); + when(protocol.getCiphersUsed()).thenReturn(new String[] {"SSL_RSA", "TLS_RSA_WITH_RC4"}); sut.log(tomcat); diff --git a/sonar-application/src/main/assembly/conf/sonar.properties b/sonar-application/src/main/assembly/conf/sonar.properties index 84feed3c14e..abc68188936 100644 --- a/sonar-application/src/main/assembly/conf/sonar.properties +++ b/sonar-application/src/main/assembly/conf/sonar.properties @@ -156,10 +156,11 @@ # HTTPS - comma separated list of encryption ciphers to support for HTTPS connections. # If specified, only the ciphers that are listed and supported by the SSL implementation will be used. -# By default, the default ciphers for the JVM will be used. Note that this usually means that the weak -# export grade ciphers will be included in the list of available ciphers. # The ciphers are specified using the JSSE cipher naming convention (see # https://www.openssl.org/docs/apps/ciphers.html) +# By default, the Mozilla recommendations are followed (Intermediate Compatibility). See +# https://wiki.mozilla.org/Security/Server_Side_TLS#Intermediate_compatibility_.28default.29 +# # Example: sonar.web.https.ciphers=TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 #sonar.web.https.ciphers= -- 2.39.5