activemq-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From cshan...@apache.org
Subject [1/2] activemq git commit: https://issues.apache.org/jira/browse/AMQ-6418
Date Tue, 06 Sep 2016 14:19:35 GMT
Repository: activemq
Updated Branches:
  refs/heads/activemq-5.14.x fb24b48b8 -> c99eb1d60


https://issues.apache.org/jira/browse/AMQ-6418

Properly setting the transport properties on the
AutoNIOSSLTransportServer and fixing the Stomp protocol to set the peer
certs when using auto+ssl

(cherry picked from commit 98c5866c7534c1f26d2e41edbdb372fe21387fe4)


Project: http://git-wip-us.apache.org/repos/asf/activemq/repo
Commit: http://git-wip-us.apache.org/repos/asf/activemq/commit/c99eb1d6
Tree: http://git-wip-us.apache.org/repos/asf/activemq/tree/c99eb1d6
Diff: http://git-wip-us.apache.org/repos/asf/activemq/diff/c99eb1d6

Branch: refs/heads/activemq-5.14.x
Commit: c99eb1d6005fd81a6ebd2486ecc79ef2e78fec9b
Parents: 679f0cf
Author: Christopher L. Shannon (cshannon) <christopher.l.shannon@gmail.com>
Authored: Fri Sep 2 15:56:33 2016 -0400
Committer: Christopher L. Shannon (cshannon) <christopher.l.shannon@gmail.com>
Committed: Tue Sep 6 10:19:20 2016 -0400

----------------------------------------------------------------------
 .../transport/amqp/AmqpTransportFilter.java     |  15 +-
 .../transport/amqp/AmqpTestSupport.java         |  16 +++
 .../amqp/auto/JMSClientAutoSslAuthTest.java     | 113 +++++++++++++++
 .../transport/auto/AutoSslTransportFactory.java |   1 -
 .../transport/auto/AutoSslTransportServer.java  |  24 +---
 .../transport/auto/AutoTcpTransportServer.java  |   2 +-
 .../auto/nio/AutoNIOSSLTransportServer.java     |  12 +-
 .../auto/nio/AutoNioTransportFactory.java       |   2 -
 .../transport/tcp/SslTransportFactory.java      |  10 ++
 .../mqtt/auto/MQTTAutoSslAuthTest.java          | 102 ++++++++++++++
 .../stomp/StompSslTransportFactory.java         |  25 ++++
 .../stomp/auto/StompAutoSslAuthTest.java        | 140 +++++++++++++++++++
 .../transport/auto/AutoSslAuthTest.java         | 129 +++++++++++++++++
 13 files changed, 556 insertions(+), 35 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-amqp/src/main/java/org/apache/activemq/transport/amqp/AmqpTransportFilter.java
----------------------------------------------------------------------
diff --git a/activemq-amqp/src/main/java/org/apache/activemq/transport/amqp/AmqpTransportFilter.java
b/activemq-amqp/src/main/java/org/apache/activemq/transport/amqp/AmqpTransportFilter.java
index fdb4c0f..8fcf39b 100644
--- a/activemq-amqp/src/main/java/org/apache/activemq/transport/amqp/AmqpTransportFilter.java
+++ b/activemq-amqp/src/main/java/org/apache/activemq/transport/amqp/AmqpTransportFilter.java
@@ -25,6 +25,7 @@ import org.apache.activemq.command.Command;
 import org.apache.activemq.transport.Transport;
 import org.apache.activemq.transport.TransportFilter;
 import org.apache.activemq.transport.TransportListener;
+import org.apache.activemq.transport.nio.NIOSSLTransport;
 import org.apache.activemq.transport.tcp.SslTransport;
 import org.apache.activemq.util.IOExceptionSupport;
 import org.apache.activemq.wireformat.WireFormat;
@@ -157,14 +158,16 @@ public class AmqpTransportFilter extends TransportFilter implements
AmqpTranspor
 
     @Override
     public X509Certificate[] getPeerCertificates() {
+        X509Certificate[] peerCerts = null;
         if (next instanceof SslTransport) {
-            X509Certificate[] peerCerts = ((SslTransport) next).getPeerCertificates();
-            if (trace && peerCerts != null) {
-                LOG.debug("Peer Identity has been verified\n");
-            }
-            return peerCerts;
+            peerCerts = ((SslTransport) next).getPeerCertificates();
+        } else if (next instanceof NIOSSLTransport) {
+            peerCerts = ((NIOSSLTransport) next).getPeerCertificates();
+        }
+        if (trace && peerCerts != null) {
+            LOG.debug("Peer Identity has been verified\n");
         }
-        return null;
+        return peerCerts;
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/AmqpTestSupport.java
----------------------------------------------------------------------
diff --git a/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/AmqpTestSupport.java
b/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/AmqpTestSupport.java
index 12c0a17..fd4accb 100644
--- a/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/AmqpTestSupport.java
+++ b/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/AmqpTestSupport.java
@@ -21,6 +21,8 @@ import java.io.IOException;
 import java.net.ServerSocket;
 import java.net.URI;
 import java.security.SecureRandom;
+import java.util.ArrayList;
+import java.util.List;
 import java.util.Set;
 import java.util.Vector;
 import java.util.concurrent.ExecutorService;
@@ -40,6 +42,7 @@ import javax.net.ssl.SSLContext;
 import javax.net.ssl.TrustManager;
 
 import org.apache.activemq.ActiveMQConnectionFactory;
+import org.apache.activemq.broker.BrokerPlugin;
 import org.apache.activemq.broker.BrokerService;
 import org.apache.activemq.broker.TransportConnector;
 import org.apache.activemq.broker.jmx.BrokerViewMBean;
@@ -147,6 +150,15 @@ public class AmqpTestSupport {
         System.setProperty("javax.net.ssl.keyStorePassword", "password");
         System.setProperty("javax.net.ssl.keyStoreType", "jks");
 
+        ArrayList<BrokerPlugin> plugins = new ArrayList<BrokerPlugin>();
+
+        addAdditionalPlugins(plugins);
+
+        if (!plugins.isEmpty()) {
+            BrokerPlugin[] array = new BrokerPlugin[plugins.size()];
+            brokerService.setPlugins(plugins.toArray(array));
+        }
+
         addTranportConnectors();
     }
 
@@ -154,6 +166,10 @@ public class AmqpTestSupport {
 
     }
 
+    protected void addAdditionalPlugins(List<BrokerPlugin> plugins) throws Exception
{
+
+    }
+
     protected void addTranportConnectors() throws Exception {
         TransportConnector connector = null;
 

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/auto/JMSClientAutoSslAuthTest.java
----------------------------------------------------------------------
diff --git a/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/auto/JMSClientAutoSslAuthTest.java
b/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/auto/JMSClientAutoSslAuthTest.java
new file mode 100644
index 0000000..40c1eb3
--- /dev/null
+++ b/activemq-amqp/src/test/java/org/apache/activemq/transport/amqp/auto/JMSClientAutoSslAuthTest.java
@@ -0,0 +1,113 @@
+/**
+ * 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.transport.amqp.auto;
+
+import static org.junit.Assert.assertTrue;
+
+import java.net.URI;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.activemq.broker.Broker;
+import org.apache.activemq.broker.BrokerFilter;
+import org.apache.activemq.broker.BrokerPlugin;
+import org.apache.activemq.broker.ConnectionContext;
+import org.apache.activemq.command.ConnectionInfo;
+import org.apache.activemq.transport.amqp.JMSClientTestSupport;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class JMSClientAutoSslAuthTest extends JMSClientTestSupport {
+
+
+    private final boolean isNio;
+    private boolean hasCertificate = false;
+
+    @Parameters(name="isNio={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+                {false},
+                {true}
+            });
+    }
+
+    @Override
+    protected boolean isUseTcpConnector() {
+        return false;
+    }
+
+    /**
+     * @param isNio
+     */
+    public JMSClientAutoSslAuthTest(boolean isNio) {
+        this.isNio = isNio;
+    }
+
+    @Override
+    protected boolean isUseAutoSslConnector() {
+        return !isNio;
+    }
+
+    @Override
+    protected boolean isUseAutoNioPlusSslConnector() {
+        return isNio;
+    }
+
+    @Override
+    protected URI getBrokerURI() {
+        return isNio ? this.autoNioPlusSslURI : this.autoSslURI;
+    }
+
+    @Override
+    protected String getAdditionalConfig() {
+        return "?transport.needClientAuth=true";
+    }
+
+
+    @Override
+    protected void addAdditionalPlugins(List<BrokerPlugin> plugins) throws Exception
{
+        super.addAdditionalPlugins(plugins);
+        plugins.add(new BrokerPlugin() {
+
+            @Override
+            public Broker installPlugin(Broker broker) throws Exception {
+                return new BrokerFilter(broker) {
+
+                    @Override
+                    public void addConnection(ConnectionContext context, ConnectionInfo info)
throws Exception {
+                        super.addConnection(context, info);
+                        hasCertificate = info.getTransportContext() instanceof X509Certificate[];
+                    }
+                };
+            }
+        });
+    }
+
+
+    @Test(timeout = 60000)
+    public void testConnect() throws Exception {
+        createConnection();
+
+        assertTrue(hasCertificate);
+    }
+
+}

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoSslTransportFactory.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoSslTransportFactory.java
b/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoSslTransportFactory.java
index 8787547..39c5c41 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoSslTransportFactory.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoSslTransportFactory.java
@@ -97,7 +97,6 @@ public class AutoSslTransportFactory extends SslTransportFactory implements
Brok
      * @throws IOException
      * @throws URISyntaxException
      */
-   // @Override
     protected AutoSslTransportServer createAutoSslTransportServer(final URI location, SSLServerSocketFactory
serverSocketFactory) throws IOException, URISyntaxException {
         AutoSslTransportServer server = new AutoSslTransportServer(this, location, serverSocketFactory,
                 this.brokerService, enabledProtocols) {

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoSslTransportServer.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoSslTransportServer.java
b/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoSslTransportServer.java
index 1f1a9c6..acd9998 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoSslTransportServer.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoSslTransportServer.java
@@ -23,14 +23,10 @@ import java.net.URI;
 import java.net.URISyntaxException;
 import java.util.Set;
 
-import javax.net.ServerSocketFactory;
 import javax.net.ssl.SSLServerSocket;
 import javax.net.ssl.SSLServerSocketFactory;
-import javax.net.ssl.SSLSocket;
 
 import org.apache.activemq.broker.BrokerService;
-import org.apache.activemq.transport.Transport;
-import org.apache.activemq.transport.tcp.SslTransport;
 import org.apache.activemq.transport.tcp.SslTransportFactory;
 import org.apache.activemq.transport.tcp.TcpTransport;
 import org.apache.activemq.transport.tcp.TcpTransportFactory;
@@ -54,20 +50,6 @@ public class AutoSslTransportServer extends AutoTcpTransportServer {
     // Specifies if sockets created from this server should wantClientAuth.
     private boolean wantClientAuth;
 
-//    /**
-//     * Creates a ssl transport server for the specified url using the provided
-//     * serverSocketFactory
-//     *
-//     * @param transportFactory The factory used to create transports when connections arrive.
-//     * @param location The location of the broker to bind to.
-//     * @param serverSocketFactory The factory used to create this server.
-//     * @throws IOException passed up from TcpTransportFactory.
-//     * @throws URISyntaxException passed up from TcpTransportFactory.
-//     */
-//    public SslTransportServer(SslTransportFactory transportFactory, URI location, SSLServerSocketFactory
serverSocketFactory) throws IOException, URISyntaxException {
-//        super(transportFactory, location, serverSocketFactory);
-//    }
-
     public AutoSslTransportServer(SslTransportFactory transportFactory,
             URI location, SSLServerSocketFactory serverSocketFactory,
             BrokerService brokerService, Set<String> enabledProtocols) throws IOException,
URISyntaxException {
@@ -137,8 +119,10 @@ public class AutoSslTransportServer extends AutoTcpTransportServer {
      * @throws IOException
      */
     @Override
-    protected TcpTransport createTransport(Socket socket, WireFormat format) throws IOException
{
-        return new SslTransport(format, (SSLSocket)socket, this.initBuffer);
+    protected TcpTransport createTransport(Socket socket, WireFormat format,
+            TcpTransportFactory detectedTransportFactory) throws IOException {
+
+        return detectedTransportFactory.createTransport(format, socket, this.initBuffer);
     }
 
     @Override

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoTcpTransportServer.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoTcpTransportServer.java
b/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoTcpTransportServer.java
index 6f6cae4..308931b 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoTcpTransportServer.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/transport/auto/AutoTcpTransportServer.java
@@ -273,7 +273,7 @@ public class AutoTcpTransportServer extends TcpTransportServer {
         }
 
         WireFormat format = protocolInfo.detectedWireFormatFactory.createWireFormat();
-        Transport transport = createTransport(socket, format,protocolInfo.detectedTransportFactory);
+        Transport transport = createTransport(socket, format, protocolInfo.detectedTransportFactory);
 
         return new TransportInfo(format, transport, protocolInfo.detectedTransportFactory);
     }

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-broker/src/main/java/org/apache/activemq/transport/auto/nio/AutoNIOSSLTransportServer.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/transport/auto/nio/AutoNIOSSLTransportServer.java
b/activemq-broker/src/main/java/org/apache/activemq/transport/auto/nio/AutoNIOSSLTransportServer.java
index bd519cb..fff1055 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/transport/auto/nio/AutoNIOSSLTransportServer.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/transport/auto/nio/AutoNIOSSLTransportServer.java
@@ -5,11 +5,11 @@ import java.net.Socket;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.nio.ByteBuffer;
+import java.util.HashMap;
 import java.util.Set;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.Executors;
 import java.util.concurrent.Future;
-import java.util.concurrent.atomic.AtomicInteger;
 
 import javax.net.ServerSocketFactory;
 import javax.net.ssl.SSLContext;
@@ -25,9 +25,8 @@ import org.apache.activemq.transport.tcp.TcpTransport;
 import org.apache.activemq.transport.tcp.TcpTransport.InitBuffer;
 import org.apache.activemq.transport.tcp.TcpTransportFactory;
 import org.apache.activemq.transport.tcp.TcpTransportServer;
+import org.apache.activemq.util.IntrospectionSupport;
 import org.apache.activemq.wireformat.WireFormat;
-import org.slf4j.Logger;
-import org.slf4j.LoggerFactory;
 
 /**
  * Licensed to the Apache Software Foundation (ASF) under one or more
@@ -47,8 +46,6 @@ import org.slf4j.LoggerFactory;
  */
 public class AutoNIOSSLTransportServer extends AutoTcpTransportServer {
 
-    private static final Logger LOG = LoggerFactory.getLogger(AutoNIOSSLTransportServer.class);
-
     private SSLContext context;
 
     public AutoNIOSSLTransportServer(SSLContext context, TcpTransportFactory transportFactory,
URI location, ServerSocketFactory serverSocketFactory,
@@ -111,6 +108,11 @@ public class AutoNIOSSLTransportServer extends AutoTcpTransportServer
{
         if (context != null) {
             in.setSslContext(context);
         }
+        //We need to set the transport options on the init transport so that the SSL options
are set
+        if (transportOptions != null) {
+            //Clone the map because we will need to set the options later on the actual transport
+            IntrospectionSupport.setProperties(in, new HashMap<>(transportOptions));
+        }
         in.start();
         SSLEngine engine = in.getSslSession();
 

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-broker/src/main/java/org/apache/activemq/transport/auto/nio/AutoNioTransportFactory.java
----------------------------------------------------------------------
diff --git a/activemq-broker/src/main/java/org/apache/activemq/transport/auto/nio/AutoNioTransportFactory.java
b/activemq-broker/src/main/java/org/apache/activemq/transport/auto/nio/AutoNioTransportFactory.java
index 52244ff..e4cd539 100644
--- a/activemq-broker/src/main/java/org/apache/activemq/transport/auto/nio/AutoNioTransportFactory.java
+++ b/activemq-broker/src/main/java/org/apache/activemq/transport/auto/nio/AutoNioTransportFactory.java
@@ -29,11 +29,9 @@ import javax.net.ServerSocketFactory;
 import org.apache.activemq.broker.BrokerService;
 import org.apache.activemq.broker.BrokerServiceAware;
 import org.apache.activemq.openwire.OpenWireFormatFactory;
-import org.apache.activemq.transport.Transport;
 import org.apache.activemq.transport.TransportServer;
 import org.apache.activemq.transport.auto.AutoTcpTransportServer;
 import org.apache.activemq.transport.auto.AutoTransportUtils;
-import org.apache.activemq.transport.nio.NIOTransport;
 import org.apache.activemq.transport.nio.NIOTransportFactory;
 import org.apache.activemq.transport.tcp.TcpTransport;
 import org.apache.activemq.transport.tcp.TcpTransportFactory;

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-client/src/main/java/org/apache/activemq/transport/tcp/SslTransportFactory.java
----------------------------------------------------------------------
diff --git a/activemq-client/src/main/java/org/apache/activemq/transport/tcp/SslTransportFactory.java
b/activemq-client/src/main/java/org/apache/activemq/transport/tcp/SslTransportFactory.java
index e695fa8..b289eec 100644
--- a/activemq-client/src/main/java/org/apache/activemq/transport/tcp/SslTransportFactory.java
+++ b/activemq-client/src/main/java/org/apache/activemq/transport/tcp/SslTransportFactory.java
@@ -17,6 +17,7 @@
 package org.apache.activemq.transport.tcp;
 
 import java.io.IOException;
+import java.net.Socket;
 import java.net.URI;
 import java.net.URISyntaxException;
 import java.net.UnknownHostException;
@@ -26,11 +27,13 @@ import java.util.Map;
 import javax.net.ServerSocketFactory;
 import javax.net.SocketFactory;
 import javax.net.ssl.SSLServerSocketFactory;
+import javax.net.ssl.SSLSocket;
 import javax.net.ssl.SSLSocketFactory;
 
 import org.apache.activemq.broker.SslContext;
 import org.apache.activemq.transport.Transport;
 import org.apache.activemq.transport.TransportServer;
+import org.apache.activemq.transport.tcp.TcpTransport.InitBuffer;
 import org.apache.activemq.util.IOExceptionSupport;
 import org.apache.activemq.util.IntrospectionSupport;
 import org.apache.activemq.util.URISupport;
@@ -160,4 +163,11 @@ public class SslTransportFactory extends TcpTransportFactory {
             return SSLSocketFactory.getDefault();
         }
     }
+
+    @Override
+    public SslTransport createTransport(WireFormat wireFormat, Socket socket, InitBuffer
initBuffer)
+            throws IOException {
+
+        return new SslTransport(wireFormat, (SSLSocket)socket, initBuffer);
+    }
 }

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-mqtt/src/test/java/org/apache/activemq/transport/mqtt/auto/MQTTAutoSslAuthTest.java
----------------------------------------------------------------------
diff --git a/activemq-mqtt/src/test/java/org/apache/activemq/transport/mqtt/auto/MQTTAutoSslAuthTest.java
b/activemq-mqtt/src/test/java/org/apache/activemq/transport/mqtt/auto/MQTTAutoSslAuthTest.java
new file mode 100644
index 0000000..4fae9c4
--- /dev/null
+++ b/activemq-mqtt/src/test/java/org/apache/activemq/transport/mqtt/auto/MQTTAutoSslAuthTest.java
@@ -0,0 +1,102 @@
+/**
+ * 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.transport.mqtt.auto;
+
+import static org.junit.Assert.assertTrue;
+
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import org.apache.activemq.broker.Broker;
+import org.apache.activemq.broker.BrokerFilter;
+import org.apache.activemq.broker.BrokerPlugin;
+import org.apache.activemq.broker.ConnectionContext;
+import org.apache.activemq.command.ConnectionInfo;
+import org.apache.activemq.transport.mqtt.MQTTTestSupport;
+import org.fusesource.mqtt.client.BlockingConnection;
+import org.fusesource.mqtt.client.MQTT;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class MQTTAutoSslAuthTest extends MQTTTestSupport  {
+
+    private final String protocol;
+    private boolean hasCertificate = false;
+
+    @Parameters(name="scheme={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+                {"auto+nio+ssl"},
+                {"auto+ssl"}
+            });
+    }
+
+    /**
+     * @param isNio
+     */
+    public MQTTAutoSslAuthTest(String protocol) {
+        this.protocol = protocol;
+        protocolConfig = "transport.needClientAuth=true";
+    }
+
+    @Override
+    public boolean isUseSSL() {
+        return true;
+    }
+
+    @Override
+    public String getProtocolScheme() {
+        return protocol;
+    }
+
+    @Override
+    protected void createPlugins(List<BrokerPlugin> plugins) throws Exception {
+        super.createPlugins(plugins);
+        plugins.add(new BrokerPlugin() {
+
+            @Override
+            public Broker installPlugin(Broker broker) throws Exception {
+                return new BrokerFilter(broker) {
+
+                    @Override
+                    public void addConnection(ConnectionContext context, ConnectionInfo info)
throws Exception {
+                        super.addConnection(context, info);
+                        //The second time should contain the certificate
+                        hasCertificate = info.getTransportContext() instanceof X509Certificate[];
+                    }
+                };
+            }
+        });
+    }
+
+    @Test(timeout = 60 * 1000)
+    public void testMQTT311Connection() throws Exception {
+        MQTT mqtt = createMQTTConnection();
+        mqtt.setClientId("foo");
+        mqtt.setVersion("3.1.1");
+        final BlockingConnection connection = mqtt.blockingConnection();
+        connection.connect();
+        connection.disconnect();
+
+        assertTrue(hasCertificate);
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/StompSslTransportFactory.java
----------------------------------------------------------------------
diff --git a/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/StompSslTransportFactory.java
b/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/StompSslTransportFactory.java
index 1e844a3..7fd1b4b 100644
--- a/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/StompSslTransportFactory.java
+++ b/activemq-stomp/src/main/java/org/apache/activemq/transport/stomp/StompSslTransportFactory.java
@@ -35,6 +35,7 @@ import org.apache.activemq.transport.Transport;
 import org.apache.activemq.transport.tcp.SslTransport;
 import org.apache.activemq.transport.tcp.SslTransportFactory;
 import org.apache.activemq.transport.tcp.SslTransportServer;
+import org.apache.activemq.transport.tcp.TcpTransport.InitBuffer;
 import org.apache.activemq.util.IntrospectionSupport;
 import org.apache.activemq.wireformat.WireFormat;
 
@@ -47,10 +48,12 @@ public class StompSslTransportFactory extends SslTransportFactory implements
Bro
 
     private BrokerContext brokerContext = null;
 
+    @Override
     protected String getDefaultWireFormatType() {
         return "stomp";
     }
 
+    @Override
     protected SslTransportServer createSslTransportServer(final URI location, SSLServerSocketFactory
serverSocketFactory) throws IOException, URISyntaxException {
         return new SslTransportServer(this, location, serverSocketFactory) {
 
@@ -74,6 +77,27 @@ public class StompSslTransportFactory extends SslTransportFactory implements
Bro
         };
     }
 
+    @Override
+    public SslTransport createTransport(WireFormat wireFormat, Socket socket, InitBuffer
initBuffer)
+            throws IOException {
+
+        return new SslTransport(wireFormat, (SSLSocket)socket, initBuffer) {
+
+            private X509Certificate[] cachedPeerCerts;
+
+            @Override
+            public void doConsume(Object command) {
+                StompFrame frame = (StompFrame) command;
+                if (cachedPeerCerts == null) {
+                    cachedPeerCerts = getPeerCertificates();
+                }
+                frame.setTransportContext(cachedPeerCerts);
+                super.doConsume(command);
+            }
+        };
+    }
+
+    @Override
     @SuppressWarnings("rawtypes")
     public Transport compositeConfigure(Transport transport, WireFormat format, Map options)
{
         transport = new StompTransportFilter(transport, format, brokerContext);
@@ -94,6 +118,7 @@ public class StompSslTransportFactory extends SslTransportFactory implements
Bro
         return transport;
     }
 
+    @Override
     public void setBrokerService(BrokerService brokerService) {
         this.brokerContext = brokerService.getBrokerContext();
     }

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/auto/StompAutoSslAuthTest.java
----------------------------------------------------------------------
diff --git a/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/auto/StompAutoSslAuthTest.java
b/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/auto/StompAutoSslAuthTest.java
new file mode 100644
index 0000000..f878cf2
--- /dev/null
+++ b/activemq-stomp/src/test/java/org/apache/activemq/transport/stomp/auto/StompAutoSslAuthTest.java
@@ -0,0 +1,140 @@
+/**
+ * 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.transport.stomp.auto;
+
+import static org.junit.Assert.assertTrue;
+
+import java.io.IOException;
+import java.net.Socket;
+import java.security.cert.X509Certificate;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.List;
+
+import javax.jms.Connection;
+import javax.net.SocketFactory;
+import javax.net.ssl.SSLSocketFactory;
+
+import org.apache.activemq.broker.Broker;
+import org.apache.activemq.broker.BrokerFilter;
+import org.apache.activemq.broker.BrokerPlugin;
+import org.apache.activemq.broker.ConnectionContext;
+import org.apache.activemq.command.ConnectionInfo;
+import org.apache.activemq.transport.stomp.Stomp;
+import org.apache.activemq.transport.stomp.StompTestSupport;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class StompAutoSslAuthTest extends StompTestSupport {
+
+    private final boolean isNio;
+    private boolean hasCertificate = false;
+    private Connection connection;
+
+    @Parameters(name="isNio={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+                {false},
+                {true}
+            });
+    }
+
+    /**
+     * @param isNio
+     */
+    public StompAutoSslAuthTest(boolean isNio) {
+        this.isNio = isNio;
+    }
+
+    @Override
+    protected boolean isUseAutoSslConnector() {
+        return !isNio;
+    }
+
+    @Override
+    protected boolean isUseAutoNioPlusSslConnector() {
+        return isNio;
+    }
+
+    @Override
+    public void setUp() throws Exception {
+        super.setUp();
+
+        hasCertificate = false;
+
+        stompConnect();
+
+        connection = cf.createConnection("system", "manager");
+        connection.start();
+    }
+
+    @Override
+    public void tearDown() throws Exception {
+        try {
+            connection.close();
+        } catch (Exception ex) {}
+
+        super.tearDown();
+    }
+
+    @Override
+    protected Socket createSocket() throws IOException {
+        SocketFactory factory = SSLSocketFactory.getDefault();
+        return factory.createSocket("127.0.0.1", isNio ? this.autoNioSslPort : this.autoSslPort);
+    }
+
+    @Override
+    protected String getAdditionalConfig() {
+        return "?transport.needClientAuth=true";
+    }
+
+    @Override
+    protected void addAdditionalPlugins(List<BrokerPlugin> plugins) throws Exception
{
+        super.addAdditionalPlugins(plugins);
+        plugins.add(new BrokerPlugin() {
+
+            @Override
+            public Broker installPlugin(Broker broker) throws Exception {
+                return new BrokerFilter(broker) {
+
+                    @Override
+                    public void addConnection(ConnectionContext context, ConnectionInfo info)
throws Exception {
+                        super.addConnection(context, info);
+                        //The second time should contain the certificate
+                        hasCertificate = info.getTransportContext() instanceof X509Certificate[];
+                    }
+                };
+            }
+        });
+    }
+
+    @Test(timeout = 60000)
+    public void testConnect() throws Exception {
+
+        String connectFrame = "CONNECT\n" + "login:system\n" + "passcode:manager\n" + "request-id:1\n"
+ "\n" + Stomp.NULL;
+        stompConnection.sendFrame(connectFrame);
+
+        String f = stompConnection.receiveFrame();
+        assertTrue(f.startsWith("CONNECTED"));
+        assertTrue(f.indexOf("response-id:1") >= 0);
+
+        assertTrue(hasCertificate);
+    }
+}

http://git-wip-us.apache.org/repos/asf/activemq/blob/c99eb1d6/activemq-unit-tests/src/test/java/org/apache/activemq/transport/auto/AutoSslAuthTest.java
----------------------------------------------------------------------
diff --git a/activemq-unit-tests/src/test/java/org/apache/activemq/transport/auto/AutoSslAuthTest.java
b/activemq-unit-tests/src/test/java/org/apache/activemq/transport/auto/AutoSslAuthTest.java
new file mode 100644
index 0000000..1491852
--- /dev/null
+++ b/activemq-unit-tests/src/test/java/org/apache/activemq/transport/auto/AutoSslAuthTest.java
@@ -0,0 +1,129 @@
+/**
+ * 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.transport.auto;
+
+import static org.junit.Assert.assertTrue;
+
+import java.security.cert.X509Certificate;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Collection;
+
+import org.apache.activemq.ActiveMQConnectionFactory;
+import org.apache.activemq.broker.Broker;
+import org.apache.activemq.broker.BrokerFilter;
+import org.apache.activemq.broker.BrokerPlugin;
+import org.apache.activemq.broker.BrokerService;
+import org.apache.activemq.broker.ConnectionContext;
+import org.apache.activemq.broker.TransportConnector;
+import org.apache.activemq.command.ConnectionInfo;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+import org.junit.runners.Parameterized;
+import org.junit.runners.Parameterized.Parameters;
+
+@RunWith(Parameterized.class)
+public class AutoSslAuthTest {
+
+    public static final String KEYSTORE_TYPE = "jks";
+    public static final String PASSWORD = "password";
+    public static final String SERVER_KEYSTORE = "src/test/resources/server.keystore";
+    public static final String TRUST_KEYSTORE = "src/test/resources/client.keystore";
+
+    private String uri;
+    private final String protocol;
+    private boolean hasCertificate = false;
+    private BrokerService brokerService;
+
+    @Parameters(name="protocol={0}")
+    public static Collection<Object[]> data() {
+        return Arrays.asList(new Object[][] {
+                {"auto+nio+ssl"},
+                {"auto+ssl"}
+            });
+    }
+
+    static {
+        System.setProperty("javax.net.ssl.trustStore", TRUST_KEYSTORE);
+        System.setProperty("javax.net.ssl.trustStorePassword", PASSWORD);
+        System.setProperty("javax.net.ssl.trustStoreType", KEYSTORE_TYPE);
+        System.setProperty("javax.net.ssl.keyStore", SERVER_KEYSTORE);
+        System.setProperty("javax.net.ssl.keyStorePassword", PASSWORD);
+        System.setProperty("javax.net.ssl.keyStoreType", KEYSTORE_TYPE);
+    }
+
+    @Before
+    public void before() throws Exception {
+        BrokerService brokerService = new BrokerService();
+        brokerService.setPersistent(false);
+
+        TransportConnector connector = brokerService.addConnector(protocol + "://localhost:0?transport.needClientAuth=true");
+        uri = connector.getPublishableConnectString();
+
+        ArrayList<BrokerPlugin> plugins = new ArrayList<BrokerPlugin>();
+
+        plugins.add(new BrokerPlugin() {
+
+            @Override
+            public Broker installPlugin(Broker broker) throws Exception {
+                return new BrokerFilter(broker) {
+
+                    @Override
+                    public void addConnection(ConnectionContext context, ConnectionInfo info)
throws Exception {
+                        super.addConnection(context, info);
+                        hasCertificate = info.getTransportContext() instanceof X509Certificate[];
+                    }
+                };
+            }
+        });
+
+        if (!plugins.isEmpty()) {
+            BrokerPlugin[] array = new BrokerPlugin[plugins.size()];
+            brokerService.setPlugins(plugins.toArray(array));
+        }
+
+        this.brokerService = brokerService;
+        brokerService.start();
+        brokerService.waitUntilStarted();
+    }
+
+    @After
+    public void after() throws Exception {
+        if (brokerService != null) {
+            brokerService.stop();
+            brokerService.waitUntilStopped();
+        }
+    }
+
+    /**
+     * @param isNio
+     */
+    public AutoSslAuthTest(String protocol) {
+        this.protocol = protocol;
+    }
+
+    @Test(timeout = 60000)
+    public void testConnect() throws Exception {
+        ActiveMQConnectionFactory factory = new ActiveMQConnectionFactory();
+        factory.setBrokerURL(uri);
+        factory.createConnection().start();
+
+        assertTrue(hasCertificate);
+    }
+}


Mime
View raw message