Repository: activemq-artemis Updated Branches: refs/heads/master 0ec39a540 -> 0746ea8ac (forced update)
ARTEMIS-1872 Fixing Security test Project: http://git-wip-us.apache.org/repos/asf/activemq-artemis/repo Commit: http://git-wip-us.apache.org/repos/asf/activemq-artemis/commit/0746ea8a Tree: http://git-wip-us.apache.org/repos/asf/activemq-artemis/tree/0746ea8a Diff: http://git-wip-us.apache.org/repos/asf/activemq-artemis/diff/0746ea8a Branch: refs/heads/master Commit: 0746ea8acabc1c70fca553c4ac5967212ed311ca Parents: e28a8a5 Author: Michael André Pearce <[email protected]> Authored: Wed May 23 21:01:22 2018 -0400 Committer: Clebert Suconic <[email protected]> Committed: Wed May 23 22:49:45 2018 -0400 ---------------------------------------------------------------------- .../artemis/jms/client/ActiveMQSession.java | 21 ++- .../server/SecureConfigurationTest.java | 159 +++++++++++++------ .../src/test/resources/multicast_topic.xml | 18 ++- 3 files changed, 134 insertions(+), 64 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0746ea8a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java ---------------------------------------------------------------------- diff --git a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java index 3149ff0..065c7a3 100644 --- a/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java +++ b/artemis-jms-client/src/main/java/org/apache/activemq/artemis/jms/client/ActiveMQSession.java @@ -387,7 +387,7 @@ public class ActiveMQSession implements QueueSession, TopicSession { queue = queueCache.get(queueName); } if (queue == null) { - queue = internalCreateQueue(queueName, false); + queue = internalCreateQueue(queueName); } if (cacheDestination) { queueCache.put(queueName, queue); @@ -397,8 +397,7 @@ public class ActiveMQSession implements QueueSession, TopicSession { throw JMSExceptionHelper.convertFromActiveMQException(e); } } - - protected Queue internalCreateQueue(String queueName, final boolean retry) throws ActiveMQException, JMSException { + protected Queue internalCreateQueue(String queueName) throws ActiveMQException, JMSException { ActiveMQQueue queue = lookupQueue(queueName, false); if (queue == null) { @@ -406,15 +405,25 @@ public class ActiveMQSession implements QueueSession, TopicSession { } if (queue == null) { - if (!retry) { - return internalCreateQueue("jms.queue." + queueName, true); - } + queue = internalCreateQueueCompatibility("jms.queue." + queueName); + } + if (queue == null) { throw new JMSException("There is no queue with name " + queueName); } else { return queue; } } + protected ActiveMQQueue internalCreateQueueCompatibility(String queueName) throws ActiveMQException, JMSException { + ActiveMQQueue queue = lookupQueue(queueName, false); + + if (queue == null) { + queue = lookupQueue(queueName, true); + } + + return queue; + } + @Override public Topic createTopic(final String topicName) throws JMSException { // As per spec. section 4.11 http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0746ea8a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/SecureConfigurationTest.java ---------------------------------------------------------------------- diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/SecureConfigurationTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/SecureConfigurationTest.java index 615ffcc..3a15ea9 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/SecureConfigurationTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/server/SecureConfigurationTest.java @@ -16,6 +16,20 @@ */ package org.apache.activemq.artemis.tests.integration.server; +import java.lang.IllegalStateException; +import java.util.Arrays; +import java.util.Collection; +import javax.jms.Connection; +import javax.jms.ConnectionFactory; +import javax.jms.Destination; +import javax.jms.JMSException; +import javax.jms.JMSRuntimeException; +import javax.jms.JMSSecurityException; +import javax.jms.MessageConsumer; +import javax.jms.Queue; +import javax.jms.Session; +import javax.jms.TextMessage; +import javax.jms.Topic; import org.apache.activemq.artemis.core.config.FileDeploymentManager; import org.apache.activemq.artemis.core.config.impl.FileConfiguration; import org.apache.activemq.artemis.core.config.impl.SecurityConfiguration; @@ -25,35 +39,24 @@ import org.apache.activemq.artemis.jms.client.ActiveMQConnectionFactory; import org.apache.activemq.artemis.jms.server.config.impl.FileJMSConfiguration; import org.apache.activemq.artemis.spi.core.security.ActiveMQJAASSecurityManager; import org.apache.activemq.artemis.spi.core.security.jaas.InVMLoginModule; -import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; import org.apache.activemq.artemis.tests.util.ActiveMQTestBase; import org.apache.qpid.jms.JmsConnectionFactory; import org.junit.After; import org.junit.Assert; import org.junit.Assume; import org.junit.Before; +import org.junit.Ignore; import org.junit.Test; import org.junit.runner.RunWith; import org.junit.runners.Parameterized; -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.jms.JMSSecurityException; -import javax.jms.MessageConsumer; -import javax.jms.Session; -import javax.jms.TextMessage; -import javax.jms.Topic; -import java.util.Arrays; -import java.util.Collection; - @RunWith(Parameterized.class) public class SecureConfigurationTest extends ActiveMQTestBase { @Parameterized.Parameters(name = "{index}: protocol={0}") public static Collection<Object[]> parameters() { return Arrays.asList(new Object[][] { - {"CORE"}, {"AMQP"}, {"OPENWIRE"} + {"CORE"}, {"AMQP"}, {"OPENWIRE"} }); } @@ -88,18 +91,18 @@ public class SecureConfigurationTest extends ActiveMQTestBase { String message = "blah"; //Expect to be able to create subscriber on pre-defined/existing queue. - String messageRecieved = sendAndReceiveText(connectionFactory, null, message, "secured_topic_shared_durable", (t, s) -> s.createSharedDurableConsumer(t, "secured_topic_shared_durable/queue")); + String messageRecieved = sendAndReceiveTextUsingTopic(connectionFactory, null, message, "secured_topic_shared_durable", (t, s) -> s.createSharedDurableConsumer(t, "secured_topic_shared_durable/queue")); Assert.assertEquals(message, messageRecieved); try { - sendAndReceiveText(connectionFactory, null, message, "secured_topic_shared_durable", (t, s) -> s.createSharedDurableConsumer(t, "secured_topic_shared_durable/non-existant-queue")); + sendAndReceiveTextUsingTopic(connectionFactory, null, message, "secured_topic_shared_durable", (t, s) -> s.createSharedDurableConsumer(t, "secured_topic_shared_durable/non-existant-queue")); Assert.fail("Security exception expected, but did not occur, excepetion expected as not permissioned to dynamically create queue"); } catch (JMSSecurityException j) { //Expected exception } try { - sendAndReceiveText(connectionFactory, null, message, "secured_topic_shared_durable", (t, s) -> s.createSharedDurableConsumer(t, "secured_topic_shared_durable/queue", "age < 10")); + sendAndReceiveTextUsingTopic(connectionFactory, null, message, "secured_topic_shared_durable", (t, s) -> s.createSharedDurableConsumer(t, "secured_topic_shared_durable/queue", "age < 10")); Assert.fail("Security exception expected, but did not occur, excepetion expected as not permissioned to dynamically create queue"); } catch (JMSSecurityException j) { //Expected exception @@ -114,18 +117,18 @@ public class SecureConfigurationTest extends ActiveMQTestBase { String message = "blah"; //Expect to be able to create subscriber on pre-defined/existing queue. - String messageRecieved = sendAndReceiveText(connectionFactory, null, message, "secured_topic_shared", (t, s) -> s.createSharedConsumer(t, "secured_topic_shared/queue")); + String messageRecieved = sendAndReceiveTextUsingTopic(connectionFactory, null, message, "secured_topic_shared", (t, s) -> s.createSharedConsumer(t, "secured_topic_shared/queue")); Assert.assertEquals(message, messageRecieved); try { - sendAndReceiveText(connectionFactory, null, message, "secured_topic_shared", (t, s) -> s.createSharedConsumer(t, "secured_topic_shared/non-existant-queue")); + sendAndReceiveTextUsingTopic(connectionFactory, null, message, "secured_topic_shared", (t, s) -> s.createSharedConsumer(t, "secured_topic_shared/non-existant-queue")); Assert.fail("Security exception expected, but did not occur, excepetion expected as not permissioned to dynamically create queue"); } catch (JMSSecurityException j) { //Expected exception } try { - sendAndReceiveText(connectionFactory, null, message, "secured_topic_shared", (t, s) -> s.createSharedConsumer(t, "secured_topic_shared/queue", "age < 10")); + sendAndReceiveTextUsingTopic(connectionFactory, null, message, "secured_topic_shared", (t, s) -> s.createSharedConsumer(t, "secured_topic_shared/queue", "age < 10")); Assert.fail("Security exception expected, but did not occur, excepetion expected as not permissioned to dynamically create queue"); } catch (JMSSecurityException j) { //Expected exception @@ -138,60 +141,91 @@ public class SecureConfigurationTest extends ActiveMQTestBase { String message = "blah"; //Expect to be able to create subscriber on pre-defined/existing queue. - String messageRecieved = sendAndReceiveText(connectionFactory, "clientId", message, "secured_topic_durable", (t, s) -> s.createDurableSubscriber(t, "secured_topic_durable/queue")); + String messageRecieved = sendAndReceiveTextUsingTopic(connectionFactory, "clientId", message, "secured_topic_durable", (t, s) -> s.createDurableSubscriber(t, "secured_topic_durable/queue")); Assert.assertEquals(message, messageRecieved); try { - sendAndReceiveText(connectionFactory, "clientId", message, "secured_topic_durable", (t, s) -> s.createDurableSubscriber(t, "secured_topic_durable/non-existant-queue")); + sendAndReceiveTextUsingTopic(connectionFactory, "clientId", message, "secured_topic_durable", (t, s) -> s.createDurableSubscriber(t, "secured_topic_durable/non-existant-queue")); Assert.fail("Security exception expected, but did not occur, excepetion expected as not permissioned to dynamically create queue"); } catch (JMSSecurityException j) { //Expected exception } try { - sendAndReceiveText(connectionFactory, "clientId", message, "secured_topic_durable", (t, s) -> s.createDurableSubscriber(t, "secured_topic_durable/queue", "age < 10", false)); + sendAndReceiveTextUsingTopic(connectionFactory, "clientId", message, "secured_topic_durable", (t, s) -> s.createDurableSubscriber(t, "secured_topic_durable/queue", "age < 10", false)); Assert.fail("Security exception expected, but did not occur, excepetion expected as not permissioned to dynamically create queue"); } catch (JMSSecurityException j) { //Expected exception } try { - sendAndReceiveText(connectionFactory, "clientId", message, "secured_topic_durable", (t, s) -> s.createDurableSubscriber(t, "secured_topic_durable/queue", "age < 10", true)); + sendAndReceiveTextUsingTopic(connectionFactory, "clientId", message, "secured_topic_durable", (t, s) -> s.createDurableSubscriber(t, "secured_topic_durable/queue", "age < 10", true)); Assert.fail("Security exception expected, but did not occur, excepetion expected as not permissioned to dynamically create queue"); } catch (JMSSecurityException j) { //Expected exception } + } - Connection connection = null; + @Test + public void testTemporaryQueue() throws Exception { + ConnectionFactory connectionFactory = getConnectionFactory("c", "c"); + String message = "blah"; try { - connection = connectionFactory.createConnection(); - Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); - - try { - session.createTemporaryQueue(); - Assert.fail("Security exception expected, but did not occur, excepetion expected as not permissioned to create a temporary queue"); - } catch (JMSSecurityException jmsse) { - IntegrationTestLogger.LOGGER.info("Client should have thrown a JMSSecurityException but only threw JMSException"); - } catch (JMSException e) { - e.printStackTrace(); - Assert.fail("thrown a JMSEXception instead of a JMSSEcurityException"); - } + sendAndReceiveText(connectionFactory, "clientId", message, s -> s.createTemporaryQueue(), (d, s) -> s.createConsumer(d)); + Assert.fail("Security exception expected, but did not occur, excepetion expected as not permissioned to create a temporary queue"); + } catch (JMSSecurityException jmsse) { + } catch (JMSException e) { + e.printStackTrace(); + Assert.fail("thrown a JMSEXception instead of a JMSSEcurityException"); + } + } - // Should not be fatal - assertNotNull(connection.createSession(false, Session.AUTO_ACKNOWLEDGE)); - } finally { - connection.close(); + @Test + public void testTemporaryTopic() throws Exception { + ConnectionFactory connectionFactory = getConnectionFactory("c", "c"); + String message = "blah"; + + try { + sendAndReceiveText(connectionFactory, "clientId", message, s -> s.createTemporaryTopic(), (d, s) -> s.createConsumer(d)); + Assert.fail("Security exception expected, but did not occur, excepetion expected as not permissioned to create a temporary queue"); + } catch (JMSSecurityException jmsse) { + } catch (JMSException e) { + e.printStackTrace(); + Assert.fail("thrown a JMSEXception instead of a JMSSEcurityException"); + } + } + + @Test + public void testSecureQueue() throws Exception { + // Core & OpenWire are not creating the queue as the test expects.. just querying + Assume.assumeTrue(protocol.equals("AMQP")); + ConnectionFactory connectionFactory = getConnectionFactory("b", "b"); + String message = "blah"; + + //Expect to be able to create subscriber on pre-defined/existing queue. + String messageRecieved = sendAndReceiveTextUsingQueue(connectionFactory, "clientId", message, "secured_queue", (q, s) -> s.createConsumer(q)); + Assert.assertEquals(message, messageRecieved); + + try { + sendAndReceiveTextUsingQueue(connectionFactory, "clientId", message, "non-existent-queue", (q, s) -> s.createConsumer(q)); + Assert.fail("Security exception expected, but did not occur, excepetion expected as not permissioned to dynamically create queue"); + } catch (JMSSecurityException j) { + //Expected exception } } private ConnectionFactory getConnectionFactory(String user, String password) { switch (protocol) { - case "CORE": return getActiveMQConnectionFactory(user, password); - case "AMQP" : return getAMQPConnectionFactory(user, password); - case "OPENWIRE": return getOpenWireConnectionFactory(user, password); - default: throw new IllegalStateException("Unsupported Protocol"); + case "CORE": + return getActiveMQConnectionFactory(user, password); + case "AMQP": + return getAMQPConnectionFactory(user, password); + case "OPENWIRE": + return getOpenWireConnectionFactory(user, password); + default: + throw new IllegalStateException("Unsupported Protocol"); } } @@ -216,24 +250,40 @@ public class SecureConfigurationTest extends ActiveMQTestBase { return activeMQConnectionFactory; } - private String sendAndReceiveText(ConnectionFactory connectionFactory, String clientId, String message, String topicName, ConsumerSupplier consumerSupplier) throws JMSException { + private String sendAndReceiveTextUsingTopic(ConnectionFactory connectionFactory, String clientId, String message, String topicName, ConsumerSupplier<Topic> consumerSupplier) throws JMSException { + return sendAndReceiveText(connectionFactory, clientId, message, s -> s.createTopic(topicName), consumerSupplier); + } + + private String sendAndReceiveTextUsingQueue(ConnectionFactory connectionFactory, String clientId, String message, String queueName, ConsumerSupplier<Queue> consumerSupplier) throws JMSException { + return sendAndReceiveText(connectionFactory, clientId, message, s -> s.createQueue(queueName), consumerSupplier); + } + + private <D extends Destination> String sendAndReceiveText(ConnectionFactory connectionFactory, String clientId, String message, DestinationSupplier<D> destinationSupplier, ConsumerSupplier<D> consumerSupplier) throws JMSException { String messageRecieved; - try (Connection connection = connectionFactory.createConnection()) { + Connection connection = null; + try { + connection = connectionFactory.createConnection(); if (clientId != null && !clientId.isEmpty()) { connection.setClientID(clientId); } connection.start(); try (Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE)) { - Topic topic = session.createTopic(topicName); - MessageConsumer messageConsumer = consumerSupplier.create(topic, session); + D destination = destinationSupplier.create(session); + MessageConsumer messageConsumer = consumerSupplier.create(destination, session); messageConsumer.receive(1000); TextMessage messageToSend = session.createTextMessage(message); - session.createProducer(topic).send(messageToSend); + session.createProducer(destination).send(messageToSend); TextMessage received = (TextMessage) messageConsumer.receive(1000); messageRecieved = received != null ? received.getText() : null; } + } catch (JMSException | JMSRuntimeException e) { + // Exception Should not be fatal + assertNotNull(connection.createSession(false, Session.AUTO_ACKNOWLEDGE)); + throw e; + } finally { + connection.close(); } return messageRecieved; } @@ -246,7 +296,6 @@ public class SecureConfigurationTest extends ActiveMQTestBase { deploymentManager.addDeployable(fileConfiguration); deploymentManager.readConfiguration(); - SecurityConfiguration securityConfiguration = new SecurityConfiguration(); securityConfiguration.addUser("a", "a"); securityConfiguration.addRole("a", "a"); @@ -254,14 +303,20 @@ public class SecureConfigurationTest extends ActiveMQTestBase { securityConfiguration.addUser("b", "b"); securityConfiguration.addRole("b", "b"); + securityConfiguration.addUser("c", "c"); + securityConfiguration.addRole("c", "c"); ActiveMQJAASSecurityManager sm = new ActiveMQJAASSecurityManager(InVMLoginModule.class.getName(), securityConfiguration); return addServer(new ActiveMQServerImpl(fc, sm)); } - private interface ConsumerSupplier { - MessageConsumer create(Topic topic, Session session) throws JMSException; + private interface ConsumerSupplier<D extends Destination> { + MessageConsumer create(D destination, Session session) throws JMSException; + } + + private interface DestinationSupplier<D extends Destination> { + D create(Session session) throws JMSException; } } http://git-wip-us.apache.org/repos/asf/activemq-artemis/blob/0746ea8a/tests/integration-tests/src/test/resources/multicast_topic.xml ---------------------------------------------------------------------- diff --git a/tests/integration-tests/src/test/resources/multicast_topic.xml b/tests/integration-tests/src/test/resources/multicast_topic.xml index 2535ad3..3f546e7 100644 --- a/tests/integration-tests/src/test/resources/multicast_topic.xml +++ b/tests/integration-tests/src/test/resources/multicast_topic.xml @@ -77,6 +77,12 @@ under the License. <queue name="clientId.secured_topic_durable/queue" /> </multicast> </address> + + <address name="secured_queue"> + <anycast> + <queue name="secured_queue" /> + </anycast> + </address> </addresses> <acceptors> @@ -85,13 +91,13 @@ under the License. <security-settings> <security-setting match="#"> - <permission type="createNonDurableQueue" roles="a"/> - <permission type="deleteNonDurableQueue" roles="a"/> - <permission type="createDurableQueue" roles="a"/> - <permission type="deleteDurableQueue" roles="a"/> + <permission type="createNonDurableQueue" roles="a,b"/> + <permission type="deleteNonDurableQueue" roles="a,b"/> + <permission type="createDurableQueue" roles="a,b"/> + <permission type="deleteDurableQueue" roles="a,b"/> <permission type="browse" roles="a"/> - <permission type="send" roles="a"/> - <permission type="consume" roles="a" /> + <permission type="send" roles="a,b"/> + <permission type="consume" roles="a,b" /> <!-- we need this otherwise ./artemis data imp wouldn't work --> <permission type="manage" roles="a"/> </security-setting>
