From 6881c1ddc32493b9f269be2638035a27b4d06eab Mon Sep 17 00:00:00 2001 From: jbertram Date: Tue, 21 Jun 2016 12:03:16 -0500 Subject: [PATCH] ARTEMIS-578 cert authn/z for STOMP --- .../core/protocol/stomp/StompConnection.java | 9 +- .../protocol/stomp/StompProtocolManager.java | 9 +- .../stomp/v10/StompFrameHandlerV10.java | 10 +- .../stomp/v11/StompFrameHandlerV11.java | 10 +- .../stomp/stomp-dual-authentication/pom.xml | 116 ++++++++++++++ .../stomp-dual-authentication/readme.html | 51 +++++++ .../StompDualAuthenticationExample.java | 141 ++++++++++++++++++ .../activemq/server0/artemis-roles.properties | 17 +++ .../activemq/server0/artemis-users.properties | 17 +++ .../resources/activemq/server0/bootstrap.xml | 26 ++++ .../resources/activemq/server0/broker.xml | 57 +++++++ .../activemq/server0/cert-roles.properties | 18 +++ .../activemq/server0/cert-users.properties | 18 +++ .../activemq/server0/client-side-keystore.jks | Bin 0 -> 1303 bytes .../server0/client-side-truststore.jks | Bin 0 -> 963 bytes .../resources/activemq/server0/login.config | 30 ++++ .../activemq/server0/server-side-keystore.jks | Bin 0 -> 2253 bytes .../server0/server-side-truststore.jks | Bin 0 -> 1732 bytes .../src/main/resources/jndi.properties | 20 +++ 19 files changed, 541 insertions(+), 8 deletions(-) create mode 100644 examples/protocols/stomp/stomp-dual-authentication/pom.xml create mode 100644 examples/protocols/stomp/stomp-dual-authentication/readme.html create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/java/org/apache/activemq/artemis/jms/example/StompDualAuthenticationExample.java create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-roles.properties create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-users.properties create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/bootstrap.xml create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/broker.xml create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-roles.properties create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-users.properties create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/client-side-keystore.jks create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/client-side-truststore.jks create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/login.config create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/server-side-keystore.jks create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/server-side-truststore.jks create mode 100644 examples/protocols/stomp/stomp-dual-authentication/src/main/resources/jndi.properties diff --git a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompConnection.java b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompConnection.java index 0812867afb..1cfd0a5718 100644 --- a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompConnection.java +++ b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompConnection.java @@ -16,6 +16,7 @@ */ package org.apache.activemq.artemis.core.protocol.stomp; +import javax.security.cert.X509Certificate; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; @@ -504,11 +505,11 @@ public final class StompConnection implements RemotingConnection { manager.sendReply(this, frame); } - public boolean validateUser(final String login1, final String passcode1) { - this.valid = manager.validateUser(login1, passcode1); + public boolean validateUser(final String login, final String pass, final X509Certificate[] certificates) { + this.valid = manager.validateUser(login, pass, certificates); if (valid) { - this.login = login1; - this.passcode = passcode1; + this.login = login; + this.passcode = pass; } return valid; } diff --git a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java index d572cd017d..7642e69faa 100644 --- a/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java +++ b/artemis-protocols/artemis-stomp-protocol/src/main/java/org/apache/activemq/artemis/core/protocol/stomp/StompProtocolManager.java @@ -16,6 +16,7 @@ */ package org.apache.activemq.artemis.core.protocol.stomp; +import javax.security.cert.X509Certificate; import java.nio.charset.StandardCharsets; import java.util.HashMap; import java.util.Iterator; @@ -45,6 +46,7 @@ import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; import org.apache.activemq.artemis.spi.core.remoting.Acceptor; import org.apache.activemq.artemis.spi.core.remoting.Connection; import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager; +import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager2; import org.apache.activemq.artemis.spi.core.security.ActiveMQSecurityManager3; import org.apache.activemq.artemis.utils.UUIDGenerator; @@ -326,14 +328,17 @@ class StompProtocolManager extends AbstractProtocolManager + + + + 4.0.0 + + + org.apache.activemq.examples.stomp + stomp-examples + 1.4.0-SNAPSHOT + + + stomp-dual-authentication + jar + ActiveMQ Artemis JMS Stomp Dual Authentication Example + + + ${project.basedir}/../../../.. + + + + + org.apache.activemq + artemis-jms-client + ${project.version} + + + + + + + org.apache.activemq + artemis-maven-plugin + + + create + + create + + + ${noServer} + + + + start + + cli + + + ${noServer} + true + tcp://localhost:61616 + consumer + activemq + + run + + + + + runClient + + runClient + + + org.apache.activemq.artemis.jms.example.StompDualAuthenticationExample + + ${project.basedir}/target/server0/etc/client-side-keystore.jks + secureexample + ${project.basedir}/target/server0/etc/client-side-truststore.jks + secureexample + + + + + stop + + cli + + + ${noServer} + + stop + + + + + + + org.apache.activemq.examples.stomp + stomp-dual-authentication + ${project.version} + + + + + + + diff --git a/examples/protocols/stomp/stomp-dual-authentication/readme.html b/examples/protocols/stomp/stomp-dual-authentication/readme.html new file mode 100644 index 0000000000..5ed4a2fcdf --- /dev/null +++ b/examples/protocols/stomp/stomp-dual-authentication/readme.html @@ -0,0 +1,51 @@ + + + + + ActiveMQ Artemis Stomp Example + + + + + +

Stomp Dual Authentication Example

+ +
To run the example, simply type mvn verify from this directory, 
or mvn -PnoServer verify if you want to start and create the server manually.
+ +

This example shows you how to configure 2-way SSL along with 2 different authentications mechanisms so that SSL and non-SSL clients can send and consume messages to/from ActiveMQ Artemis. + The non-SSL authentication mechanism simply uses username and password. The SSL authentication mechanism uses the client's certificate. The Stomp client uses SSL socket directly to send + a message. Then a JMS client will use a non-SSL connection to consume it.

+ +

The various keystore files are generated using the following commands:

+ +

+

+           
+keytool -genkey -keystore server-side-keystore.jks -storepass secureexample -keypass secureexample -dname "CN=ActiveMQ Artemis Server, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg RSA
+keytool -export -keystore server-side-keystore.jks -file server-side-cert.cer -storepass secureexample
+keytool -import -keystore client-side-truststore.jks -file server-side-cert.cer -storepass secureexample -keypass secureexample -noprompt
+keytool -genkey -keystore client-side-keystore.jks -storepass secureexample -keypass secureexample -dname "CN=ActiveMQ Artemis Client, OU=Artemis, O=ActiveMQ, L=AMQ, S=AMQ, C=AMQ" -keyalg RSA
+keytool -export -keystore client-side-keystore.jks -file client-side-cert.cer -storepass secureexample
+keytool -import -keystore server-side-truststore.jks -file client-side-cert.cer -storepass secureexample -keypass secureexample -noprompt
+           
+        
+

+ + diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/java/org/apache/activemq/artemis/jms/example/StompDualAuthenticationExample.java b/examples/protocols/stomp/stomp-dual-authentication/src/main/java/org/apache/activemq/artemis/jms/example/StompDualAuthenticationExample.java new file mode 100644 index 0000000000..1694cf11a4 --- /dev/null +++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/java/org/apache/activemq/artemis/jms/example/StompDualAuthenticationExample.java @@ -0,0 +1,141 @@ +/* + * 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.artemis.jms.example; + +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.MessageConsumer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.naming.InitialContext; +import javax.net.ssl.SSLSocket; +import javax.net.ssl.SSLSocketFactory; +import java.io.InputStream; +import java.io.OutputStream; +import java.net.Socket; +import java.nio.charset.StandardCharsets; +import java.security.Security; + +import com.sun.net.ssl.internal.ssl.Provider; + +/** + * An example where a client will send a Stomp message on a TCP socket + * and consume it from a JMS MessageConsumer. + */ +public class StompDualAuthenticationExample { + + private static final String END_OF_FRAME = "\u0000"; + + public static void main(final String[] args) throws Exception { + // set up SSL keystores for Stomp connection + System.setProperty("javax.net.ssl.keyStore", args[0]); + System.setProperty("javax.net.ssl.keyStorePassword", args[1]); + System.setProperty("javax.net.ssl.trustStore", args[2]); + System.setProperty("javax.net.ssl.trustStorePassword", args[3]); + + Connection connection = null; + InitialContext initialContext = null; + Security.addProvider(new Provider()); + + try { + // Step 1. Create an SSL socket to connect to the broker + SSLSocketFactory sslsocketfactory = (SSLSocketFactory) SSLSocketFactory.getDefault(); + SSLSocket socket = (SSLSocket) sslsocketfactory.createSocket("localhost", 5500); + + // Step 2. Send a CONNECT frame to connect to the server + String connectFrame = "CONNECT\n" + + "request-id: 1\n" + + "\n" + + END_OF_FRAME; + sendFrame(socket, connectFrame); + + readFrame(socket); + + // Step 3. Send a SEND frame (a Stomp message) to the + // jms.queue.exampleQueue address with a text body + String text = "Hello, world from Stomp!"; + String message = "SEND\n" + + "destination: jms.queue.exampleQueue\n" + + "\n" + + text + + END_OF_FRAME; + sendFrame(socket, message); + System.out.println("Sent Stomp message: " + text); + + // Step 4. Send a DISCONNECT frame to disconnect from the server + String disconnectFrame = "DISCONNECT\n" + + "\n" + + END_OF_FRAME; + sendFrame(socket, disconnectFrame); + + // Step 5. Slose the TCP socket + socket.close(); + + // We will now consume from JMS the message sent with Stomp. + + // Step 6. Create an initial context to perform the JNDI lookup. + initialContext = new InitialContext(); + + // Step 7. Perform a lookup on the queue and the connection factory + Queue queue = (Queue) initialContext.lookup("queue/exampleQueue"); + ConnectionFactory cf = (ConnectionFactory) initialContext.lookup("ConnectionFactory"); + + // Step 8.Create a JMS Connection, Session and a MessageConsumer on the queue + connection = cf.createConnection("consumer", "activemq"); + Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); + MessageConsumer consumer = session.createConsumer(queue); + + // Step 9. Start the Connection + connection.start(); + + // Step 10. Receive the message + TextMessage messageReceived = (TextMessage) consumer.receive(5000); + System.out.println("Received JMS message: " + messageReceived.getText()); + } + finally { + // Step 11. Be sure to close our JMS resources! + if (initialContext != null) { + initialContext.close(); + } + if (connection != null) { + connection.close(); + } + } + } + + private static void sendFrame(Socket socket, String data) throws Exception { + byte[] bytes = data.getBytes(StandardCharsets.UTF_8); + OutputStream outputStream = socket.getOutputStream(); + for (int i = 0; i < bytes.length; i++) { + outputStream.write(bytes[i]); + } + outputStream.flush(); + } + + private static String readFrame(Socket socket) throws Exception { + byte[] bytes = new byte[2048]; + InputStream inputStream = socket.getInputStream(); + int nbytes = inputStream.read(bytes); + byte[] data = new byte[nbytes]; + System.arraycopy(bytes, 0, data, 0, data.length); + String resp = new String(data, StandardCharsets.UTF_8); + System.out.println("Got response from server: " + resp); + return resp; + } + +} diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-roles.properties b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-roles.properties new file mode 100644 index 0000000000..643dfc37d1 --- /dev/null +++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-roles.properties @@ -0,0 +1,17 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- +consumers=consumer \ No newline at end of file diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-users.properties b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-users.properties new file mode 100644 index 0000000000..1c68f505dd --- /dev/null +++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/artemis-users.properties @@ -0,0 +1,17 @@ +## --------------------------------------------------------------------------- +## 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. +## --------------------------------------------------------------------------- +consumer=activemq \ No newline at end of file diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/bootstrap.xml b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/bootstrap.xml new file mode 100644 index 0000000000..2eabc517a6 --- /dev/null +++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/bootstrap.xml @@ -0,0 +1,26 @@ + + + + + + + + + + + diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/broker.xml b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/broker.xml new file mode 100644 index 0000000000..14fa849c77 --- /dev/null +++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/broker.xml @@ -0,0 +1,57 @@ + + + + + + + + + + + + + ./data/messaging/bindings + + ./data/messaging/journal + + ./data/messaging/largemessages + + ./data/messaging/paging + + + + tcp://localhost:61616 + tcp://localhost:5500?sslEnabled=true;needClientAuth=true;keyStorePath=${data.dir}/../etc/server-side-keystore.jks;keyStorePassword=secureexample;trustStorePath=${data.dir}/../etc/server-side-truststore.jks;trustStorePassword=secureexample + + + + + + + + + + + + + + diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-roles.properties b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-roles.properties new file mode 100644 index 0000000000..f52fa21753 --- /dev/null +++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-roles.properties @@ -0,0 +1,18 @@ +# +# 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. +# + +producers=producer diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-users.properties b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-users.properties new file mode 100644 index 0000000000..06874dc5e9 --- /dev/null +++ b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/cert-users.properties @@ -0,0 +1,18 @@ +# +# 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. +# + +producer=CN=ActiveMQ Artemis Client, OU=Artemis, O=ActiveMQ, L=AMQ, ST=AMQ, C=AMQ diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/client-side-keystore.jks b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/client-side-keystore.jks new file mode 100644 index 0000000000000000000000000000000000000000..cb65a44ddc868383e07e700b941d9ac0709daf58 GIT binary patch literal 1303 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 IlooIIKQG79H~;_u literal 0 HcmV?d00001 diff --git a/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/server-side-truststore.jks b/examples/protocols/stomp/stomp-dual-authentication/src/main/resources/activemq/server0/server-side-truststore.jks new file mode 100644 index 0000000000000000000000000000000000000000..0b7e224163358aef1f20d04f5c6720f98b97679a GIT binary patch literal 1732 zcmezO_TO6u1_mZLW=={>VPIek*!;DvkAXEp&(y$@fq_}Wpov+p`ni!fH z8AJiOW(I~v=1?x3T+zh1-Jpq42j+c7AV;35v610#eQ={}sgP#SeXlusZ=O8=Cb&Jw z=DiEUVLAJTZGmc;uCWeEfxjbddn11BKl*i-!MD@1LvyY-S~tj=+HZ6MH!u=sa<}1i)-ybe$y*AtS-swH7W6XAh z@2s4%e)lh{S4}^|eYkDeo6-X#!~1q!iS&O~$S%;>u*FlXQ2B+AhM4g7^PEOKCzd_5 z5v%GBsp-{tuy~!E_U2`!6Z00=bN^B_P5Ssdsftm>`plA#`&I-_=v>i!|6$bA`D~NA z)8ZPcLse54eXReT_tau;Y++z(Y%r=kbN_I)aQjBz7apnmULCHGthwoYIiq;Vm%RmV z?@n47b>?ra)6b>tSrY0=%WwEk-FIip&c&-Y+G@ zt&Qi`{8=yFqpKpTwk+J%ihWU}<mkT;M8rYl)K7BLo)MB_7#Mv^mDt4;Yl_xFC?=tt8y4N;Ocvp$1?4wHy=*^=l6 zw!k~;c?Q#?BJOs1TP)kkB*NsMsjZi_Qb6d)+Gd^R=1KCew@n1+Bi7u??9@t7E?Vy{ z@eh%UoPfE=4w#GnKy#6z#DORj>kJBE`G#7#NWnl3l8eM)Sxo_&!O*jm1u#RIo0!6~ zlo^ye5KbD+U*zVmqGPi8{m#Nkq1ipN_39t**RtKVdOyFwwENNq%!PA|7rnbW<>Z`V z5!OF#8z<$xSh<$n_rn~n4xMAQd-wMFMyjs4dd87s#twc1g?$D>+tw=_V_Ov;pnB)) zo5XCZu0#%(eRM%HFxSayE|v^wi`12K k_4O@1aE-GsYR(x({$u$93H;)JLJaM8R