From 5af61cfc389987ac420e8b5af1b4cbafa4de0b1e Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 6 Jul 2016 11:55:41 +1000 Subject: [PATCH 1/5] fix #685 SecureRequestCustomizer SslSession attribute --- .../jetty/server/SecureRequestCustomizer.java | 2 +- .../jetty/server/HttpServerTestFixture.java | 10 +-- .../ssl/SelectChannelServerSslTest.java | 89 ++++++++++++++++++- 3 files changed, 92 insertions(+), 9 deletions(-) diff --git a/jetty-server/src/main/java/org/eclipse/jetty/server/SecureRequestCustomizer.java b/jetty-server/src/main/java/org/eclipse/jetty/server/SecureRequestCustomizer.java index 7b90e9d66cc..806c4768d07 100644 --- a/jetty-server/src/main/java/org/eclipse/jetty/server/SecureRequestCustomizer.java +++ b/jetty-server/src/main/java/org/eclipse/jetty/server/SecureRequestCustomizer.java @@ -266,7 +266,7 @@ public class SecureRequestCustomizer implements HttpConfiguration.Customizer request.setAttribute("javax.servlet.request.key_size",keySize); request.setAttribute("javax.servlet.request.ssl_session_id", idStr); String sessionAttribute = getSslSessionAttribute(); - if (sessionAttribute != null && sessionAttribute.isEmpty()) + if (sessionAttribute != null && !sessionAttribute.isEmpty()) request.setAttribute(sessionAttribute, sslSession); } catch (Exception e) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java index 333ebad8d98..2f8ae4e808d 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/HttpServerTestFixture.java @@ -35,6 +35,7 @@ import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.server.handler.HandlerWrapper; +import org.eclipse.jetty.server.handler.HotSwapHandler; import org.eclipse.jetty.toolchain.test.PropertyFlag; import org.eclipse.jetty.util.IO; import org.eclipse.jetty.util.thread.QueuedThreadPool; @@ -71,7 +72,7 @@ public class HttpServerTestFixture protected void startServer(ServerConnector connector) throws Exception { - startServer(connector,new HandlerWrapper()); + startServer(connector,new HotSwapHandler()); } protected void startServer(ServerConnector connector, Handler handler) throws Exception @@ -96,10 +97,9 @@ public class HttpServerTestFixture protected void configureServer(Handler handler) throws Exception { - HandlerWrapper current = (HandlerWrapper)_server.getHandler(); - current.stop(); - current.setHandler(handler); - current.start(); + HotSwapHandler swapper = (HotSwapHandler)_server.getHandler(); + swapper.setHandler(handler); + handler.start(); } diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java index eb68ed42bdf..c0431dc1f23 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ssl/SelectChannelServerSslTest.java @@ -18,21 +18,33 @@ package org.eclipse.jetty.server.ssl; +import static org.hamcrest.Matchers.containsString; +import static org.hamcrest.Matchers.is; +import static org.hamcrest.Matchers.isEmptyOrNullString; +import static org.hamcrest.Matchers.not; import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; -import java.io.FileInputStream; +import java.io.IOException; import java.io.InputStream; import java.io.OutputStream; import java.net.Socket; import java.net.SocketException; import java.net.URI; +import java.nio.charset.StandardCharsets; import java.security.KeyStore; import java.util.Arrays; import java.util.concurrent.Executor; +import java.util.regex.Matcher; +import java.util.regex.Pattern; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManagerFactory; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.io.ByteBufferPool; import org.eclipse.jetty.io.LeakTrackingByteBufferPool; @@ -41,11 +53,16 @@ import org.eclipse.jetty.io.ssl.SslConnection; import org.eclipse.jetty.server.AbstractConnectionFactory; import org.eclipse.jetty.server.HttpConnectionFactory; import org.eclipse.jetty.server.HttpServerTestBase; +import org.eclipse.jetty.server.Request; +import org.eclipse.jetty.server.SecureRequestCustomizer; import org.eclipse.jetty.server.ServerConnector; +import org.eclipse.jetty.server.handler.AbstractHandler; import org.eclipse.jetty.toolchain.test.OS; import org.eclipse.jetty.util.log.Log; import org.eclipse.jetty.util.ssl.SslContextFactory; import org.eclipse.jetty.util.thread.Scheduler; +import org.hamcrest.Matchers; +import org.junit.Assert; import org.junit.Assume; import org.junit.Before; import org.junit.Ignore; @@ -122,8 +139,12 @@ public class SelectChannelServerSslTest extends HttpServerTestBase sslContextFactory.setTrustStorePath(keystorePath); sslContextFactory.setTrustStorePassword("storepwd"); ByteBufferPool pool = new LeakTrackingByteBufferPool(new MappedByteBufferPool.Tagged()); - ServerConnector connector = new ServerConnector(_server,(Executor)null,(Scheduler)null,pool, 1, 1, AbstractConnectionFactory.getFactories(sslContextFactory,new HttpConnectionFactory())); - + + HttpConnectionFactory httpConnectionFactory = new HttpConnectionFactory(); + ServerConnector connector = new ServerConnector(_server,(Executor)null,(Scheduler)null,pool, 1, 1, AbstractConnectionFactory.getFactories(sslContextFactory,httpConnectionFactory)); + SecureRequestCustomizer secureRequestCustomer = new SecureRequestCustomizer(); + secureRequestCustomer.setSslSessionAttribute("SSL_SESSION"); + httpConnectionFactory.getHttpConfiguration().addCustomizer(secureRequestCustomer); startServer(connector); @@ -223,5 +244,67 @@ public class SelectChannelServerSslTest extends HttpServerTestBase { } + @Test + public void testSecureRequestCustomizer() throws Exception + { + configureServer(new SecureRequestHandler()); + try (Socket client = newSocket(_serverURI.getHost(), _serverURI.getPort())) + { + OutputStream os = client.getOutputStream(); + + os.write("GET / HTTP/1.0\r\n\r\n".getBytes(StandardCharsets.ISO_8859_1)); + os.flush(); + + // Read the response. + String response = readResponse(client); + + System.err.println(response); + + assertThat(response, containsString("HTTP/1.1 200 OK")); + assertThat(response, containsString("Hello world")); + assertThat(response, containsString("scheme='https'")); + assertThat(response, containsString("isSecure='true'")); + assertThat(response, containsString("X509Certificate='null'")); + + Matcher matcher=Pattern.compile("cipher_suite='([^']*)'").matcher(response); + matcher.find(); + assertThat(matcher.group(1), Matchers.allOf(not(isEmptyOrNullString()),not(is("null")))); + + matcher=Pattern.compile("key_size='([^']*)'").matcher(response); + matcher.find(); + assertThat(matcher.group(1), Matchers.allOf(not(isEmptyOrNullString()),not(is("null")))); + + matcher=Pattern.compile("ssl_session_id='([^']*)'").matcher(response); + matcher.find(); + assertThat(matcher.group(1), Matchers.allOf(not(isEmptyOrNullString()),not(is("null")))); + + matcher=Pattern.compile("ssl_session='([^']*)'").matcher(response); + matcher.find(); + assertThat(matcher.group(1), Matchers.allOf(not(isEmptyOrNullString()),not(is("null")))); + } + } + + public static class SecureRequestHandler extends AbstractHandler + { + + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + baseRequest.setHandled(true); + response.setStatus(200); + response.getOutputStream().println("Hello world"); + response.getOutputStream().println("scheme='"+request.getScheme()+"'"); + response.getOutputStream().println("isSecure='"+request.isSecure()+"'"); + response.getOutputStream().println("X509Certificate='"+request.getAttribute("javax.servlet.request.X509Certificate")+"'"); + response.getOutputStream().println("cipher_suite='"+request.getAttribute("javax.servlet.request.cipher_suite")+"'"); + response.getOutputStream().println("key_size='"+request.getAttribute("javax.servlet.request.key_size")+"'"); + response.getOutputStream().println("ssl_session_id='"+request.getAttribute("javax.servlet.request.ssl_session_id")+"'"); + SSLSession sslSession=(SSLSession)request.getAttribute("SSL_SESSION"); + response.getOutputStream().println("ssl_session='"+sslSession+"'"); + + } + + } + } From 0d0b1ace5c0859d8cf680f994280e481033be514 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 6 Jul 2016 12:05:03 +1000 Subject: [PATCH 2/5] Issue #658 Print out the memcached host and port being used. --- .../gcloud/memcached/session/GCloudMemcachedSessionManager.java | 2 ++ 1 file changed, 2 insertions(+) diff --git a/jetty-gcloud/jetty-gcloud-memcached-session-manager/src/main/java/org/eclipse/jetty/gcloud/memcached/session/GCloudMemcachedSessionManager.java b/jetty-gcloud/jetty-gcloud-memcached-session-manager/src/main/java/org/eclipse/jetty/gcloud/memcached/session/GCloudMemcachedSessionManager.java index a44edfa1bf2..5d97e599466 100644 --- a/jetty-gcloud/jetty-gcloud-memcached-session-manager/src/main/java/org/eclipse/jetty/gcloud/memcached/session/GCloudMemcachedSessionManager.java +++ b/jetty-gcloud/jetty-gcloud-memcached-session-manager/src/main/java/org/eclipse/jetty/gcloud/memcached/session/GCloudMemcachedSessionManager.java @@ -217,6 +217,8 @@ public class GCloudMemcachedSessionManager extends GCloudSessionManager { if (StringUtil.isBlank(_host) || StringUtil.isBlank(_port)) throw new IllegalStateException("Memcached host and/or port not configured"); + + LOG.info("Memcached host {} port {}", _host, _port); XMemcachedClientBuilder builder = new XMemcachedClientBuilder(_host+":"+_port); _client = builder.build(); From f058054cbe61a9b5e35a01d505cead6ec2a7df7a Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 6 Jul 2016 12:14:22 +1000 Subject: [PATCH 3/5] Issue #644 Modules for logging Added slf4j-jul --- jetty-util/src/main/config/modules/slf4j-jcl.mod | 3 --- jetty-util/src/main/config/modules/slf4j-jul.mod | 15 +++++++++++++++ .../src/main/config/modules/slf4j-simple.mod | 3 --- 3 files changed, 15 insertions(+), 6 deletions(-) create mode 100644 jetty-util/src/main/config/modules/slf4j-jul.mod diff --git a/jetty-util/src/main/config/modules/slf4j-jcl.mod b/jetty-util/src/main/config/modules/slf4j-jcl.mod index 8ff9cdd7ded..6a9773a048c 100644 --- a/jetty-util/src/main/config/modules/slf4j-jcl.mod +++ b/jetty-util/src/main/config/modules/slf4j-jcl.mod @@ -15,6 +15,3 @@ maven://org.slf4j/slf4j-jcl/${slf4j.version}|lib/slf4j/slf4j-jcl-${slf4j.version [lib] lib/slf4j/slf4j-jcl-${slf4j.version}.jar - -[exec] --Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog diff --git a/jetty-util/src/main/config/modules/slf4j-jul.mod b/jetty-util/src/main/config/modules/slf4j-jul.mod new file mode 100644 index 00000000000..fc858778d2f --- /dev/null +++ b/jetty-util/src/main/config/modules/slf4j-jul.mod @@ -0,0 +1,15 @@ +[description] +Provides a SLF4J implementation that logs to the Java Util Logging API. +To receive jetty logs enable the jetty-slf4j module. + +[depend] +slf4j-api + +[provide] +slf4j-impl + +[files] +maven://org.slf4j/slf4j-jdk14/${slf4j.version}|lib/slf4j/slf4j-jdk14-${slf4j.version}.jar + +[lib] +lib/slf4j/slf4j-jdk14-${slf4j.version}.jar diff --git a/jetty-util/src/main/config/modules/slf4j-simple.mod b/jetty-util/src/main/config/modules/slf4j-simple.mod index 9bdf38c6df0..804cde01a03 100644 --- a/jetty-util/src/main/config/modules/slf4j-simple.mod +++ b/jetty-util/src/main/config/modules/slf4j-simple.mod @@ -13,6 +13,3 @@ maven://org.slf4j/slf4j-simple/${slf4j.version}|lib/slf4j/slf4j-simple-${slf4j.v [lib] lib/slf4j/slf4j-simple-${slf4j.version}.jar - -[exec] --Dorg.eclipse.jetty.util.log.class=org.eclipse.jetty.util.log.Slf4jLog From cc842aff2b77fc642dd51246ac095b8823ed8fd0 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Wed, 6 Jul 2016 13:17:50 +1000 Subject: [PATCH 4/5] Issue #689 disable http2 draft versions --- .../AbstractHTTP2ServerConnectionFactory.java | 5 +++- .../server/HTTP2CServerConnectionFactory.java | 10 +++++++- .../http2/server/HTTP2ServerConnection.java | 25 +++++++++++++++++++ .../server/HTTP2ServerConnectionFactory.java | 3 +-- 4 files changed, 39 insertions(+), 4 deletions(-) diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java index 0a5b1f85281..dca0334d49c 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/AbstractHTTP2ServerConnectionFactory.java @@ -53,12 +53,15 @@ public abstract class AbstractHTTP2ServerConnectionFactory extends AbstractConne public AbstractHTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration) { - this(httpConfiguration,"h2","h2-17","h2-16","h2-15","h2-14"); + this(httpConfiguration,"h2"); } protected AbstractHTTP2ServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration, String... protocols) { super(protocols); + for (String p:protocols) + if (!HTTP2ServerConnection.isSupportedProtocol(p)) + throw new IllegalArgumentException("Unsupported HTTP2 Protocol variant: "+p); this.httpConfiguration = Objects.requireNonNull(httpConfiguration); addBean(httpConfiguration); } diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2CServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2CServerConnectionFactory.java index 874e4ea360b..676ce9b88fd 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2CServerConnectionFactory.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2CServerConnectionFactory.java @@ -51,7 +51,15 @@ public class HTTP2CServerConnectionFactory extends HTTP2ServerConnectionFactory public HTTP2CServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration) { - super(httpConfiguration,"h2c","h2c-17","h2c-16","h2c-15","h2c-14"); + this(httpConfiguration,"h2c"); + } + + public HTTP2CServerConnectionFactory(@Name("config") HttpConfiguration httpConfiguration, String... protocols) + { + super(httpConfiguration,protocols); + for (String p:protocols) + if (!HTTP2ServerConnection.isSupportedProtocol(p)) + throw new IllegalArgumentException("Unsupported HTTP2 Protocol variant: "+p); } @Override diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java index a2429a12919..a7e745fb537 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnection.java @@ -58,6 +58,31 @@ import org.eclipse.jetty.util.thread.ExecutionStrategy; public class HTTP2ServerConnection extends HTTP2Connection implements Connection.UpgradeTo { + + /** + * @param protocol A HTTP2 protocol variant + * @return True if the protocol version is supported + */ + public static boolean isSupportedProtocol(String protocol) + { + switch(protocol) + { + case "h2": + case "h2-17": + case "h2-16": + case "h2-15": + case "h2-14": + case "h2c": + case "h2c-17": + case "h2c-16": + case "h2c-15": + case "h2c-14": + return true; + default: + return false; + } + } + private final Queue channels = new ConcurrentArrayQueue<>(); private final ServerSessionListener listener; private final HttpConfiguration httpConfig; diff --git a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java index 301431c9980..e69ef2efaa8 100644 --- a/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java +++ b/jetty-http2/http2-server/src/main/java/org/eclipse/jetty/http2/server/HTTP2ServerConnectionFactory.java @@ -64,8 +64,7 @@ public class HTTP2ServerConnectionFactory extends AbstractHTTP2ServerConnectionF @Override public boolean isAcceptable(String protocol, String tlsProtocol, String tlsCipher) { - // TODO remove this draft 14 protection - // Implement 9.2.2 + // Implement 9.2.2 for draft 14 boolean acceptable = "h2-14".equals(protocol) || !(HTTP2Cipher.isBlackListProtocol(tlsProtocol) && HTTP2Cipher.isBlackListCipher(tlsCipher)); if (LOG.isDebugEnabled()) LOG.debug("proto={} tls={} cipher={} 9.2.2-acceptable={}",protocol,tlsProtocol,tlsCipher,acceptable); From c913bc7150a0d227dbe8ff8601b25f429af26ba1 Mon Sep 17 00:00:00 2001 From: Jan Bartel Date: Wed, 6 Jul 2016 13:41:59 +1000 Subject: [PATCH 5/5] Issue #690 --- .../org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java | 1 + 1 file changed, 1 insertion(+) diff --git a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java index 181b40be618..b5bb983d2df 100644 --- a/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java +++ b/jetty-maven-plugin/src/main/java/org/eclipse/jetty/maven/plugin/JettyEffectiveWebXml.java @@ -86,6 +86,7 @@ public class JettyEffectiveWebXml extends JettyRunMojo applyJettyXml (); ServerSupport.configureHandlers(server, null); + ServerSupport.configureDefaultConfigurationClasses(server); //ensure config of the webapp based on settings in plugin configureWebApplication();