From 9822d58d04abe22f059b85b418478a4f80592322 Mon Sep 17 00:00:00 2001 From: Gary Tully Date: Wed, 31 Mar 2010 16:54:49 +0000 Subject: [PATCH] resolve https://issues.apache.org/activemq/browse/AMQ-2384 - not exactly the patch but allowing the introspector to work, which is more generic with some tests, thanks phil for the impetus on this git-svn-id: https://svn.apache.org/repos/asf/activemq/trunk@929618 13f79535-47bb-0310-9956-ffa450edef68 --- .../activemq/util/IntrospectionSupport.java | 7 +++ .../activemq/util/StringArrayEditor.java | 39 ++++++++++++ .../transport/tcp/SslBrokerServiceTest.java | 62 ++++++++++++++++++- 3 files changed, 107 insertions(+), 1 deletion(-) create mode 100644 activemq-core/src/main/java/org/apache/activemq/util/StringArrayEditor.java diff --git a/activemq-core/src/main/java/org/apache/activemq/util/IntrospectionSupport.java b/activemq-core/src/main/java/org/apache/activemq/util/IntrospectionSupport.java index 8b7e0e0f97..8f6c979b00 100755 --- a/activemq-core/src/main/java/org/apache/activemq/util/IntrospectionSupport.java +++ b/activemq-core/src/main/java/org/apache/activemq/util/IntrospectionSupport.java @@ -30,6 +30,8 @@ import java.util.Map; import java.util.Set; import java.util.Map.Entry; +import javax.net.ssl.SSLServerSocket; + import org.apache.activemq.command.ActiveMQDestination; @@ -53,6 +55,7 @@ public final class IntrospectionSupport { newSearchPath, existingSearchPath.length, additionalPath.length); PropertyEditorManager.setEditorSearchPath(newSearchPath); + PropertyEditorManager.registerEditor(String[].class, StringArrayEditor.class); } } @@ -179,6 +182,10 @@ public final class IntrospectionSupport { public static boolean setProperty(Object target, String name, Object value) { try { Class clazz = target.getClass(); + if (target instanceof SSLServerSocket) { + // overcome illegal access issues with internal implementation class + clazz = SSLServerSocket.class; + } Method setter = findSetterMethod(clazz, name); if (setter == null) { return false; diff --git a/activemq-core/src/main/java/org/apache/activemq/util/StringArrayEditor.java b/activemq-core/src/main/java/org/apache/activemq/util/StringArrayEditor.java new file mode 100644 index 0000000000..c908611942 --- /dev/null +++ b/activemq-core/src/main/java/org/apache/activemq/util/StringArrayEditor.java @@ -0,0 +1,39 @@ +/** + * 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.activemq.util; + +import java.beans.PropertyEditorSupport; + +import org.springframework.util.StringUtils; + + +public class StringArrayEditor extends PropertyEditorSupport { + + public static final String DEFAULT_SEPARATOR = ","; + + public String getAsText() { + return getValue().toString(); + } + + + public void setAsText(String text) throws IllegalArgumentException { + String[] array = StringUtils.delimitedListToStringArray(text, ListEditor.DEFAULT_SEPARATOR, null); + setValue(array); + } + +} + diff --git a/activemq-core/src/test/java/org/apache/activemq/transport/tcp/SslBrokerServiceTest.java b/activemq-core/src/test/java/org/apache/activemq/transport/tcp/SslBrokerServiceTest.java index a20293b1b4..4ad4248d4a 100644 --- a/activemq-core/src/test/java/org/apache/activemq/transport/tcp/SslBrokerServiceTest.java +++ b/activemq-core/src/test/java/org/apache/activemq/transport/tcp/SslBrokerServiceTest.java @@ -20,10 +20,16 @@ import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileInputStream; import java.io.IOException; +import java.net.SocketException; +import java.net.UnknownHostException; import java.security.KeyStore; import javax.net.ssl.KeyManager; import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLException; +import javax.net.ssl.SSLSession; +import javax.net.ssl.SSLSocket; import javax.net.ssl.TrustManager; import javax.net.ssl.TrustManagerFactory; @@ -33,11 +39,18 @@ import junit.textui.TestRunner; import org.apache.activemq.broker.BrokerService; import org.apache.activemq.broker.SslBrokerService; import org.apache.activemq.broker.SslContext; +import org.apache.activemq.broker.TransportConnector; import org.apache.activemq.transport.TransportBrokerTestSupport; import org.apache.activemq.transport.TransportFactory; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; public class SslBrokerServiceTest extends TransportBrokerTestSupport { + private static final Log LOG = LogFactory.getLog(SslBrokerServiceTest.class); + TransportConnector needClientAuthConnector; + TransportConnector limitedCipherSuites; + protected String getBindLocation() { return "ssl://localhost:0"; } @@ -50,6 +63,8 @@ public class SslBrokerServiceTest extends TransportBrokerTestSupport { KeyManager[] km = getKeyManager(); TrustManager[] tm = getTrustManager(); connector = service.addSslConnector(getBindLocation(), km, tm, null); + limitedCipherSuites = service.addSslConnector("ssl://localhost:0?transport.enabledCipherSuites=SSL_RSA_WITH_RC4_128_SHA,SSL_DH_anon_WITH_3DES_EDE_CBC_SHA", km, tm, null); + needClientAuthConnector = service.addSslConnector("ssl://localhost:0?transport.needClientAuth=true", km, tm, null); // for client side SslTransportFactory sslFactory = new SslTransportFactory(); @@ -59,8 +74,53 @@ public class SslBrokerServiceTest extends TransportBrokerTestSupport { return service; } - + public void testNeedClientAuth() throws Exception { + SSLContext context = SSLContext.getInstance("TLS"); + // no client cert + context.init(null, getTrustManager(), null); + + try { + makeSSLConnection(context, null, needClientAuthConnector); + fail("expected failure on no client cert"); + } catch (SSLException expected) { + expected.printStackTrace(); + } + // should work with regular connector + makeSSLConnection(context, null, connector); + } + + public void testCipherSuitesDisabled() throws Exception { + SSLContext context = SSLContext.getInstance("TLS"); + context.init(getKeyManager(), getTrustManager(), null); + + // Enable only one cipher suite which is not enabled on the server + try { + makeSSLConnection(context, new String[]{ "SSL_RSA_WITH_RC4_128_MD5" }, limitedCipherSuites); + fail("expected failure on non allowed cipher suite"); + } catch (SSLException expectedOnNotAnAvailableSuite) { + } + + // ok with the enabled one + makeSSLConnection(context, new String[]{ "SSL_RSA_WITH_RC4_128_SHA" }, limitedCipherSuites); + } + + private void makeSSLConnection(SSLContext context, String enabledSuites[], TransportConnector connector) throws Exception, + UnknownHostException, SocketException { + SSLSocket sslSocket = (SSLSocket) context.getSocketFactory().createSocket("localhost", connector.getUri().getPort()); + + if (enabledSuites != null) { + sslSocket.setEnabledCipherSuites(enabledSuites); + } + sslSocket.setSoTimeout(5000); + + SSLSession session = sslSocket.getSession(); + sslSocket.startHandshake(); + LOG.info("cyphersuite: " + session.getCipherSuite()); + LOG.info("peer port: " + session.getPeerPort()); + LOG.info("peer cert: " + session.getPeerCertificateChain()[0].toString()); + } + private TrustManager[] getTrustManager() throws Exception { TrustManager[] trustStoreManagers = null; KeyStore trustedCertStore = KeyStore.getInstance(SslTransportBrokerTest.KEYSTORE_TYPE);