Return-Path: X-Original-To: apmail-cxf-commits-archive@www.apache.org Delivered-To: apmail-cxf-commits-archive@www.apache.org Received: from mail.apache.org (hermes.apache.org [140.211.11.3]) by minotaur.apache.org (Postfix) with SMTP id 2E40A17725 for ; Mon, 20 Oct 2014 15:45:39 +0000 (UTC) Received: (qmail 26290 invoked by uid 500); 20 Oct 2014 15:45:39 -0000 Delivered-To: apmail-cxf-commits-archive@cxf.apache.org Received: (qmail 26212 invoked by uid 500); 20 Oct 2014 15:45:39 -0000 Mailing-List: contact commits-help@cxf.apache.org; run by ezmlm Precedence: bulk List-Help: List-Unsubscribe: List-Post: List-Id: Reply-To: dev@cxf.apache.org Delivered-To: mailing list commits@cxf.apache.org Received: (qmail 26082 invoked by uid 99); 20 Oct 2014 15:45:38 -0000 Received: from tyr.zones.apache.org (HELO tyr.zones.apache.org) (140.211.11.114) by apache.org (qpsmtpd/0.29) with ESMTP; Mon, 20 Oct 2014 15:45:38 +0000 Received: by tyr.zones.apache.org (Postfix, from userid 65534) id B5EC79B1D36; Mon, 20 Oct 2014 15:45:38 +0000 (UTC) Content-Type: text/plain; charset="us-ascii" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit From: coheigea@apache.org To: commits@cxf.apache.org Date: Mon, 20 Oct 2014 15:45:39 -0000 Message-Id: In-Reply-To: References: X-Mailer: ASF-Git Admin Mailer Subject: [2/3] git commit: Disallow SSLv3 by default in Jetty Disallow SSLv3 by default in Jetty Conflicts: rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java Project: http://git-wip-us.apache.org/repos/asf/cxf/repo Commit: http://git-wip-us.apache.org/repos/asf/cxf/commit/fd04a6e2 Tree: http://git-wip-us.apache.org/repos/asf/cxf/tree/fd04a6e2 Diff: http://git-wip-us.apache.org/repos/asf/cxf/diff/fd04a6e2 Branch: refs/heads/3.0.x-fixes Commit: fd04a6e2d35b227899e7b0beb4abc173ee8ed037 Parents: f56f167 Author: Colm O hEigeartaigh Authored: Mon Oct 20 12:13:25 2014 +0100 Committer: Colm O hEigeartaigh Committed: Mon Oct 20 16:45:30 2014 +0100 ---------------------------------------------------------------------- .../http_jetty/JettyHTTPServerEngine.java | 237 +++++++++++++++++++ .../org/apache/cxf/systest/ws/ssl/SSLTest.java | 142 +++++++++++ .../org/apache/cxf/systest/ws/ssl/Server.java | 47 ++++ .../apache/cxf/systest/ws/ssl/DoubleItSSL.wsdl | 109 +++++++++ .../org/apache/cxf/systest/ws/ssl/client.xml | 34 +++ .../org/apache/cxf/systest/ws/ssl/server.xml | 69 ++++++ 6 files changed, 638 insertions(+) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/cxf/blob/fd04a6e2/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java ---------------------------------------------------------------------- diff --git a/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java b/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java index 011f937..929e932 100644 --- a/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java +++ b/rt/transports/http-jetty/src/main/java/org/apache/cxf/transport/http_jetty/JettyHTTPServerEngine.java @@ -477,6 +477,243 @@ public class JettyHTTPServerEngine ++servantCount; } +<<<<<<< HEAD +======= + private void addServerMBean() { + if (mBeanContainer == null) { + return; + } + + try { + Object o = getContainer(server); + o.getClass().getMethod("addEventListener", Container.Listener.class).invoke(o, mBeanContainer); + if (Server.getVersion().startsWith("8")) { + return; + } + mBeanContainer.getClass().getMethod("beanAdded", Container.class, Object.class) + .invoke(mBeanContainer, null, server); + } catch (RuntimeException rex) { + throw rex; + } catch (Exception r) { + throw new RuntimeException(r); + } + } + private void removeServerMBean() { + try { + mBeanContainer.getClass().getMethod("beanRemoved", Container.class, Object.class) + .invoke(mBeanContainer, null, server); + } catch (RuntimeException rex) { + throw rex; + } catch (Exception r) { + throw new RuntimeException(r); + } + } + + private Connector createConnector(String hosto, int porto) { + // now we just use the SelectChannelConnector as the default connector + SslContextFactory sslcf = null; + if (tlsServerParameters != null) { + sslcf = new SslContextFactory() { + protected void doStart() throws Exception { + setSslContext(createSSLContext(this)); + super.doStart(); + } + public void checkKeyStore() { + //we'll handle this later + } + }; + decorateCXFJettySslSocketConnector(sslcf); + } + AbstractConnector result = null; + if (!Server.getVersion().startsWith("8")) { + result = createConnectorJetty9(sslcf, hosto, porto); + } else { + result = createConnectorJetty8(sslcf, hosto, porto); + } + + try { + result.getClass().getMethod("setPort", Integer.TYPE).invoke(result, porto); + if (hosto != null) { + result.getClass().getMethod("setHost", String.class).invoke(result, hosto); + } + result.getClass().getMethod("setReuseAddress", Boolean.TYPE).invoke(result, isReuseAddress()); + } catch (RuntimeException rex) { + throw rex; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + + return result; + } + + AbstractConnector createConnectorJetty9(SslContextFactory sslcf, String hosto, int porto) { + //Jetty 9 + AbstractConnector result = null; + try { + Class configClass = ClassLoaderUtils.loadClass("org.eclipse.jetty.server.HttpConfiguration", + Server.class); + Object httpConfig = configClass.newInstance(); + httpConfig.getClass().getMethod("setSendServerVersion", Boolean.TYPE) + .invoke(httpConfig, getSendServerVersion()); + + Object httpFactory = ClassLoaderUtils.loadClass("org.eclipse.jetty.server.HttpConnectionFactory", + Server.class) + .getConstructor(configClass).newInstance(httpConfig); + + Collection connectionFactories = new ArrayList(); + result = (AbstractConnector)ClassLoaderUtils.loadClass("org.eclipse.jetty.server.ServerConnector", + Server.class) + .getConstructor(Server.class) + .newInstance(server); + + if (tlsServerParameters != null) { + Class src = ClassLoaderUtils.loadClass("org.eclipse.jetty.server.SecureRequestCustomizer", + Server.class); + httpConfig.getClass().getMethod("addCustomizer", src.getInterfaces()[0]) + .invoke(httpConfig, src.newInstance()); + Object scf = ClassLoaderUtils.loadClass("org.eclipse.jetty.server.SslConnectionFactory", + Server.class).getConstructor(SslContextFactory.class, + String.class) + .newInstance(sslcf, "HTTP/1.1"); + connectionFactories.add(scf); + result.getClass().getMethod("setDefaultProtocol", String.class).invoke(result, "SSL-HTTP/1.1"); + } + connectionFactories.add(httpFactory); + result.getClass().getMethod("setConnectionFactories", Collection.class) + .invoke(result, connectionFactories); + + if (getMaxIdleTime() > 0) { + result.getClass().getMethod("setIdleTimeout", Long.TYPE).invoke(result, new Long(getMaxIdleTime())); + } + + } catch (RuntimeException rex) { + throw rex; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + return result; + } + AbstractConnector createConnectorJetty8(SslContextFactory sslcf, String hosto, int porto) { + //Jetty 8 + AbstractConnector result = null; + try { + if (sslcf == null) { + result = (AbstractConnector)ClassLoaderUtils + .loadClass("org.eclipse.jetty.server.nio.SelectChannelConnector", + Server.class).newInstance(); + } else { + result = (AbstractConnector)ClassLoaderUtils + .loadClass("org.eclipse.jetty.server.ssl.SslSelectChannelConnector", + Server.class).getConstructor(SslContextFactory.class) + .newInstance(sslcf); + } + Server.class.getMethod("setSendServerVersion", Boolean.TYPE).invoke(server, getSendServerVersion()); + if (getMaxIdleTime() > 0) { + result.getClass().getMethod("setMaxIdleTime", Integer.TYPE).invoke(result, getMaxIdleTime()); + } + } catch (RuntimeException rex) { + throw rex; + } catch (Exception ex) { + throw new RuntimeException(ex); + } + return result; + } + + + protected SSLContext createSSLContext(SslContextFactory scf) throws Exception { + String proto = tlsServerParameters.getSecureSocketProtocol() == null + ? "TLS" : tlsServerParameters.getSecureSocketProtocol(); + + if (!"SSLv3".equals(proto)) { + scf.addExcludeProtocols("SSLv3"); + } + + SSLContext context = tlsServerParameters.getJsseProvider() == null + ? SSLContext.getInstance(proto) + : SSLContext.getInstance(proto, tlsServerParameters.getJsseProvider()); + + KeyManager keyManagers[] = tlsServerParameters.getKeyManagers(); + if (tlsServerParameters.getCertAlias() != null) { + keyManagers = getKeyManagersWithCertAlias(keyManagers); + } + context.init(tlsServerParameters.getKeyManagers(), + tlsServerParameters.getTrustManagers(), + tlsServerParameters.getSecureRandom()); + + String[] cs = + SSLUtils.getCiphersuites( + tlsServerParameters.getCipherSuites(), + SSLUtils.getServerSupportedCipherSuites(context), + tlsServerParameters.getCipherSuitesFilter(), + LOG, true); + + scf.setExcludeCipherSuites(cs); + return context; + } + protected KeyManager[] getKeyManagersWithCertAlias(KeyManager keyManagers[]) throws Exception { + if (tlsServerParameters.getCertAlias() != null) { + for (int idx = 0; idx < keyManagers.length; idx++) { + if (keyManagers[idx] instanceof X509KeyManager) { + keyManagers[idx] = new AliasedX509ExtendedKeyManager( + tlsServerParameters.getCertAlias(), (X509KeyManager)keyManagers[idx]); + } + } + } + return keyManagers; + } + protected void setClientAuthentication(SslContextFactory con, + ClientAuthentication clientAuth) { + con.setWantClientAuth(true); + if (clientAuth != null) { + if (clientAuth.isSetWant()) { + con.setWantClientAuth(clientAuth.isWant()); + } + if (clientAuth.isSetRequired()) { + con.setNeedClientAuth(clientAuth.isRequired()); + } + } + } + /** + * This method sets the security properties for the CXF extension + * of the JettySslConnector. + */ + private void decorateCXFJettySslSocketConnector( + SslContextFactory con + ) { + setClientAuthentication(con, + tlsServerParameters.getClientAuthentication()); + con.setCertAlias(tlsServerParameters.getCertAlias()); + } + + + private static Container getContainer(Object server) { + if (server instanceof Container) { + return (Container)server; + } + try { + return (Container)server.getClass().getMethod("getContainer").invoke(server); + } catch (RuntimeException t) { + throw t; + } catch (Throwable t) { + throw new RuntimeException(t); + } + } + + private static void logConnector(Connector connector) { + try { + String h = (String)connector.getClass().getMethod("getHost").invoke(connector); + int port = (Integer)connector.getClass().getMethod("getPort").invoke(connector); + LOG.finer("connector.host: " + + h == null + ? "null" + : "\"" + h + "\""); + LOG.finer("connector.port: " + port); + } catch (Throwable t) { + //ignore + } + } + +>>>>>>> 990f4b1... Disallow SSLv3 by default in Jetty protected void setupThreadPool() { AbstractConnector aconn = (AbstractConnector) connector; if (isSetThreadingParameters()) { http://git-wip-us.apache.org/repos/asf/cxf/blob/fd04a6e2/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ssl/SSLTest.java ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ssl/SSLTest.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ssl/SSLTest.java new file mode 100644 index 0000000..47c240d --- /dev/null +++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ssl/SSLTest.java @@ -0,0 +1,142 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.systest.ws.ssl; + +import java.io.IOException; +import java.net.URL; + +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; +import javax.net.ssl.TrustManager; + +import org.apache.cxf.Bus; +import org.apache.cxf.bus.spring.SpringBusFactory; +import org.apache.cxf.common.logging.LogUtils; +import org.apache.cxf.configuration.jsse.SSLUtils; +import org.apache.cxf.systest.ws.common.SecurityTestUtil; +import org.apache.cxf.testutil.common.AbstractBusClientServerTestBase; +import org.junit.BeforeClass; + +/** + * A set of tests SSL protocol support. + */ +public class SSLTest extends AbstractBusClientServerTestBase { + static final String PORT = allocatePort(Server.class); + static final String PORT2 = allocatePort(Server.class, 2); + + @BeforeClass + public static void startServers() throws Exception { + assertTrue( + "Server failed to launch", + // run the server in the same process + // set this to false to fork + launchServer(Server.class, true) + ); + } + + public static void cleanup() throws Exception { + SecurityTestUtil.cleanup(); + stopAllServers(); + } + + @org.junit.Test + public void testSSLv3NotAllowed() throws Exception { + + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = SSLTest.class.getResource("client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + System.setProperty("https.protocols", "SSLv3"); + + URL service = new URL("https://localhost:" + PORT); + HttpsURLConnection connection = (HttpsURLConnection) service.openConnection(); + + connection.setHostnameVerifier(new DisableCNCheckVerifier()); + + SSLContext sslContext = SSLContext.getInstance("SSL"); + URL keystore = SSLTest.class.getResource("../security/Truststore.jks"); + TrustManager[] trustManagers = + SSLUtils.getTrustStoreManagers(false, "jks", keystore.getPath(), + "PKIX", LogUtils.getL7dLogger(SSLTest.class)); + sslContext.init(null, trustManagers, new java.security.SecureRandom()); + + connection.setSSLSocketFactory(sslContext.getSocketFactory()); + + try { + connection.connect(); + fail("Failure expected on an SSLv3 connection attempt"); + } catch (IOException ex) { + // expected + } + + System.clearProperty("https.protocols"); + + bus.shutdown(true); + } + + @org.junit.Test + public void testSSLv3Allowed() throws Exception { + + SpringBusFactory bf = new SpringBusFactory(); + URL busFile = SSLTest.class.getResource("client.xml"); + + Bus bus = bf.createBus(busFile.toString()); + SpringBusFactory.setDefaultBus(bus); + SpringBusFactory.setThreadDefaultBus(bus); + + System.setProperty("https.protocols", "SSLv3"); + + URL service = new URL("https://localhost:" + PORT2); + HttpsURLConnection connection = (HttpsURLConnection) service.openConnection(); + + connection.setHostnameVerifier(new DisableCNCheckVerifier()); + + SSLContext sslContext = SSLContext.getInstance("SSL"); + URL keystore = SSLTest.class.getResource("../security/Truststore.jks"); + TrustManager[] trustManagers = + SSLUtils.getTrustStoreManagers(false, "jks", keystore.getPath(), + "PKIX", LogUtils.getL7dLogger(SSLTest.class)); + sslContext.init(null, trustManagers, new java.security.SecureRandom()); + + connection.setSSLSocketFactory(sslContext.getSocketFactory()); + + connection.connect(); + + connection.disconnect(); + + System.clearProperty("https.protocols"); + + bus.shutdown(true); + } + + private static final class DisableCNCheckVerifier implements HostnameVerifier { + + @Override + public boolean verify(String arg0, SSLSession arg1) { + return true; + } + + }; +} http://git-wip-us.apache.org/repos/asf/cxf/blob/fd04a6e2/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ssl/Server.java ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ssl/Server.java b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ssl/Server.java new file mode 100644 index 0000000..ce169c3 --- /dev/null +++ b/systests/ws-security/src/test/java/org/apache/cxf/systest/ws/ssl/Server.java @@ -0,0 +1,47 @@ +/** + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + */ + +package org.apache.cxf.systest.ws.ssl; + +import java.net.URL; + +import org.apache.cxf.Bus; +import org.apache.cxf.BusFactory; +import org.apache.cxf.bus.spring.SpringBusFactory; +import org.apache.cxf.testutil.common.AbstractBusTestServerBase; + +public class Server extends AbstractBusTestServerBase { + + public Server() { + + } + + protected void run() { + URL busFile = Server.class.getResource("server.xml"); + Bus busLocal = new SpringBusFactory().createBus(busFile); + BusFactory.setDefaultBus(busLocal); + setBus(busLocal); + + try { + new Server(); + } catch (Exception e) { + e.printStackTrace(); + } + } +} http://git-wip-us.apache.org/repos/asf/cxf/blob/fd04a6e2/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/DoubleItSSL.wsdl ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/DoubleItSSL.wsdl b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/DoubleItSSL.wsdl new file mode 100644 index 0000000..ed021f4 --- /dev/null +++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/DoubleItSSL.wsdl @@ -0,0 +1,109 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + http://git-wip-us.apache.org/repos/asf/cxf/blob/fd04a6e2/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/client.xml ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/client.xml b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/client.xml new file mode 100644 index 0000000..d6bbe97 --- /dev/null +++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/client.xml @@ -0,0 +1,34 @@ + + + + + + + + + + + + + + + + + http://git-wip-us.apache.org/repos/asf/cxf/blob/fd04a6e2/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/server.xml ---------------------------------------------------------------------- diff --git a/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/server.xml b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/server.xml new file mode 100644 index 0000000..d1593b9 --- /dev/null +++ b/systests/ws-security/src/test/resources/org/apache/cxf/systest/ws/ssl/server.xml @@ -0,0 +1,69 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +