From 90efd861331110146772327714462959bd9010b7 Mon Sep 17 00:00:00 2001 From: Timothy Bish Date: Fri, 28 Apr 2017 12:19:25 -0400 Subject: [PATCH 1/2] ARTEMIS-547 tests for auth on attach --- .../integration/amqp/AmqpSecurityTest.java | 41 +++++-------------- .../amqp/JMSConnectionWithSecurityTest.java | 4 +- 2 files changed, 11 insertions(+), 34 deletions(-) diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSecurityTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSecurityTest.java index 54e43a7bc5..c2cee06c9e 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSecurityTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/AmqpSecurityTest.java @@ -16,7 +16,6 @@ */ package org.apache.activemq.artemis.tests.integration.amqp; -import java.io.IOException; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; @@ -95,34 +94,20 @@ public class AmqpSecurityTest extends AmqpClientTestSupport { @Test(timeout = 60000) public void testSendAndRejected() throws Exception { - CountDownLatch latch = new CountDownLatch(1); - AmqpClient client = createAmqpClient(guestUser, guestPass); client.setValidator(new AmqpValidator() { @Override - public void inspectDeliveryUpdate(Sender sender, Delivery delivery) { - DeliveryState state = delivery.getRemoteState(); + public void inspectOpenedResource(Sender sender) { + ErrorCondition condition = sender.getRemoteCondition(); - if (!delivery.remotelySettled()) { - markAsInvalid("delivery is not remotely settled"); - } - - if (state instanceof Rejected) { - Rejected rejected = (Rejected) state; - if (rejected.getError() == null || rejected.getError().getCondition() == null) { - markAsInvalid("Delivery should have been Rejected with an error condition"); - } else { - ErrorCondition error = rejected.getError(); - if (!error.getCondition().equals(AmqpError.UNAUTHORIZED_ACCESS)) { - markAsInvalid("Should have been tagged with unauthorized access error"); - } + if (condition != null && condition.getCondition() != null) { + if (!condition.getCondition().equals(AmqpError.UNAUTHORIZED_ACCESS)) { + markAsInvalid("Should have been tagged with unauthorized access error"); } } else { - markAsInvalid("Delivery should have been Rejected"); + markAsInvalid("Sender should have been opened with an error"); } - - latch.countDown(); } }); @@ -130,19 +115,13 @@ public class AmqpSecurityTest extends AmqpClientTestSupport { AmqpSession session = connection.createSession(); try { - AmqpSender sender = session.createSender(getQueueName()); - AmqpMessage message = new AmqpMessage(); - - message.setMessageId("msg" + 1); - message.setMessageAnnotation("serialNo", 1); - message.setText("Test-Message"); - try { - sender.send(message); - } catch (IOException e) { + session.createSender(getQueueName()); + fail("Should not be able to consume here."); + } catch (Exception ex) { + IntegrationTestLogger.LOGGER.info("Caught expected exception"); } - assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); connection.getStateInspector().assertValid(); } finally { connection.close(); diff --git a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionWithSecurityTest.java b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionWithSecurityTest.java index 2db2215b8a..ee82e3dd82 100644 --- a/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionWithSecurityTest.java +++ b/tests/integration-tests/src/test/java/org/apache/activemq/artemis/tests/integration/amqp/JMSConnectionWithSecurityTest.java @@ -193,9 +193,7 @@ public class JMSConnectionWithSecurityTest extends JMSClientTestSupport { Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); javax.jms.Queue queue = session.createQueue(getQueueName()); try { - // TODO - This seems a bit odd, can attach but not send - MessageProducer producer = session.createProducer(queue); - producer.send(session.createMessage()); + session.createProducer(queue); fail("Should not be able to produce here."); } catch (JMSSecurityException jmsSE) { IntegrationTestLogger.LOGGER.info("Caught expected exception"); From 849c4b7def4c22e92dc91eda07f61f1461e3999d Mon Sep 17 00:00:00 2001 From: Justin Bertram Date: Fri, 28 Apr 2017 13:06:41 -0500 Subject: [PATCH 2/2] ARTEMIS-547 authorize AMQP sender on attach --- .../amqp/broker/AMQPSessionCallback.java | 6 +++ .../ActiveMQAMQPProtocolMessageBundle.java | 3 ++ .../proton/ProtonServerReceiverContext.java | 41 +++++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPSessionCallback.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPSessionCallback.java index 08ea959d7d..87e26e2807 100644 --- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPSessionCallback.java +++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/broker/AMQPSessionCallback.java @@ -31,6 +31,8 @@ import org.apache.activemq.artemis.core.io.IOCallback; import org.apache.activemq.artemis.core.paging.PagingStore; import org.apache.activemq.artemis.core.persistence.OperationContext; import org.apache.activemq.artemis.core.persistence.StorageManager; +import org.apache.activemq.artemis.core.security.CheckType; +import org.apache.activemq.artemis.core.security.SecurityAuth; import org.apache.activemq.artemis.core.server.AddressQueryResult; import org.apache.activemq.artemis.core.server.BindingQueryResult; import org.apache.activemq.artemis.core.server.MessageReference; @@ -654,4 +656,8 @@ public class AMQPSessionCallback implements SessionCallback { public RoutingType getDefaultRoutingType(String address) { return manager.getServer().getAddressSettingsRepository().getMatch(address).getDefaultQueueRoutingType(); } + + public void check(SimpleString address, CheckType checkType, SecurityAuth session) throws Exception { + manager.getServer().getSecurityStore().check(address, checkType, session); + } } diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/logger/ActiveMQAMQPProtocolMessageBundle.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/logger/ActiveMQAMQPProtocolMessageBundle.java index f8e888c7e4..12c17fc2e7 100644 --- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/logger/ActiveMQAMQPProtocolMessageBundle.java +++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/logger/ActiveMQAMQPProtocolMessageBundle.java @@ -84,4 +84,7 @@ public interface ActiveMQAMQPProtocolMessageBundle { @Message(id = 219016, value = "not authorized to create temporary destination, {0}", format = Message.Format.MESSAGE_FORMAT) ActiveMQAMQPSecurityException securityErrorCreatingTempDestination(String message); + @Message(id = 219017, value = "not authorized to create producer, {0}", format = Message.Format.MESSAGE_FORMAT) + ActiveMQAMQPSecurityException securityErrorCreatingProducer(String message); + } diff --git a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerReceiverContext.java b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerReceiverContext.java index 0258dd1027..66bdc544b3 100644 --- a/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerReceiverContext.java +++ b/artemis-protocols/artemis-amqp-protocol/src/main/java/org/apache/activemq/artemis/protocol/amqp/proton/ProtonServerReceiverContext.java @@ -21,12 +21,18 @@ import java.util.List; import org.apache.activemq.artemis.api.core.ActiveMQSecurityException; import org.apache.activemq.artemis.api.core.RoutingType; +import org.apache.activemq.artemis.api.core.SimpleString; +import org.apache.activemq.artemis.core.security.CheckType; +import org.apache.activemq.artemis.core.security.SecurityAuth; import org.apache.activemq.artemis.core.transaction.Transaction; import org.apache.activemq.artemis.protocol.amqp.broker.AMQPSessionCallback; import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPException; import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPInternalErrorException; import org.apache.activemq.artemis.protocol.amqp.exceptions.ActiveMQAMQPNotFoundException; import org.apache.activemq.artemis.protocol.amqp.logger.ActiveMQAMQPProtocolMessageBundle; +import org.apache.activemq.artemis.protocol.amqp.sasl.PlainSASLResult; +import org.apache.activemq.artemis.protocol.amqp.sasl.SASLResult; +import org.apache.activemq.artemis.spi.core.protocol.RemotingConnection; import org.apache.qpid.proton.amqp.Symbol; import org.apache.qpid.proton.amqp.messaging.Rejected; import org.apache.qpid.proton.amqp.messaging.TerminusExpiryPolicy; @@ -121,6 +127,41 @@ public class ProtonServerReceiverContext extends ProtonInitializable implements } catch (Exception e) { throw new ActiveMQAMQPInternalErrorException(e.getMessage(), e); } + + try { + sessionSPI.check(SimpleString.toSimpleString(address), CheckType.SEND, new SecurityAuth() { + @Override + public String getUsername() { + String username = null; + SASLResult saslResult = connection.getSASLResult(); + if (saslResult != null) { + username = saslResult.getUser(); + } + + return username; + } + + @Override + public String getPassword() { + String password = null; + SASLResult saslResult = connection.getSASLResult(); + if (saslResult != null) { + if (saslResult instanceof PlainSASLResult) { + password = ((PlainSASLResult) saslResult).getPassword(); + } + } + + return password; + } + + @Override + public RemotingConnection getRemotingConnection() { + return null; + } + }); + } catch (ActiveMQSecurityException e) { + throw ActiveMQAMQPProtocolMessageBundle.BUNDLE.securityErrorCreatingProducer(e.getMessage()); + } } }