/* * 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 * <p> * http://www.apache.org/licenses/LICENSE-2.0 * <p> * 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.tests.integration.amqp; import java.util.concurrent.CountDownLatch; import java.util.concurrent.TimeUnit; import org.apache.activemq.artemis.tests.integration.IntegrationTestLogger; import org.apache.activemq.transport.amqp.client.AmqpClient; import org.apache.activemq.transport.amqp.client.AmqpConnection; import org.apache.activemq.transport.amqp.client.AmqpMessage; import org.apache.activemq.transport.amqp.client.AmqpSender; import org.apache.activemq.transport.amqp.client.AmqpSession; import org.apache.activemq.transport.amqp.client.AmqpValidator; import org.apache.qpid.proton.amqp.messaging.Rejected; import org.apache.qpid.proton.amqp.transport.AmqpError; import org.apache.qpid.proton.amqp.transport.DeliveryState; import org.apache.qpid.proton.amqp.transport.ErrorCondition; import org.apache.qpid.proton.engine.Delivery; import org.apache.qpid.proton.engine.Receiver; import org.apache.qpid.proton.engine.Sender; import org.junit.Test; public class AmqpSecurityTest extends AmqpClientTestSupport { @Override protected boolean isSecurityEnabled() { return true; } @Test(timeout = 60000) public void testSaslAuthWithInvalidCredentials() throws Exception { AmqpConnection connection = null; AmqpClient client = createAmqpClient(fullUser, guestUser); try { connection = client.connect(); fail("Should not authenticate when invalid credentials provided"); } catch (Exception ex) { // Expected } finally { if (connection != null) { connection.close(); } } } @Test(timeout = 60000) public void testSaslAuthWithAuthzid() throws Exception { AmqpConnection connection = null; AmqpClient client = createAmqpClient(guestUser, guestPass); client.setAuthzid(guestUser); try { connection = client.connect(); } catch (Exception ex) { fail("Should authenticate even with authzid set"); } finally { if (connection != null) { connection.close(); } } } @Test(timeout = 60000) public void testSaslAuthWithoutAuthzid() throws Exception { AmqpConnection connection = null; AmqpClient client = createAmqpClient(guestUser, guestPass); try { connection = client.connect(); } catch (Exception ex) { fail("Should authenticate even with authzid set"); } finally { if (connection != null) { connection.close(); } } } @Test(timeout = 60000) public void testSendAndRejected() throws Exception { AmqpClient client = createAmqpClient(guestUser, guestPass); client.setValidator(new AmqpValidator() { @Override public void inspectOpenedResource(Sender sender) { ErrorCondition condition = sender.getRemoteCondition(); if (condition != null && condition.getCondition() != null) { if (!condition.getCondition().equals(AmqpError.UNAUTHORIZED_ACCESS)) { markAsInvalid("Should have been tagged with unauthorized access error"); } } else { markAsInvalid("Sender should have been opened with an error"); } } }); AmqpConnection connection = addConnection(client.connect()); AmqpSession session = connection.createSession(); try { try { session.createSender(getQueueName()); fail("Should not be able to consume here."); } catch (Exception ex) { IntegrationTestLogger.LOGGER.info("Caught expected exception"); } connection.getStateInspector().assertValid(); } finally { connection.close(); } } @Test(timeout = 60000) public void testSendMessageFailsOnAnonymousRelayWhenNotAuthorizedToSendToAddress() 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(); 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"); } } } else { markAsInvalid("Delivery should have been Rejected"); } latch.countDown(); } }); AmqpConnection connection = client.connect(); try { AmqpSession session = connection.createSession(); AmqpSender sender = session.createAnonymousSender(); AmqpMessage message = new AmqpMessage(); message.setAddress(getQueueName()); message.setMessageId("msg" + 1); message.setText("Test-Message"); try { sender.send(message); fail("Should not be able to send, message should be rejected"); } catch (Exception ex) { ex.printStackTrace(); } finally { sender.close(); } assertTrue(latch.await(5000, TimeUnit.MILLISECONDS)); connection.getStateInspector().assertValid(); } finally { connection.close(); } } @Test(timeout = 30000) public void testReceiverNotAuthorized() throws Exception { AmqpClient client = createAmqpClient(noprivUser, noprivPass); client.setValidator(new AmqpValidator() { @Override public void inspectOpenedResource(Receiver receiver) { ErrorCondition condition = receiver.getRemoteCondition(); if (condition != null && condition.getCondition() != null) { if (!condition.getCondition().equals(AmqpError.UNAUTHORIZED_ACCESS)) { markAsInvalid("Should have been tagged with unauthorized access error"); } } else { markAsInvalid("Receiver should have been opened with an error"); } } }); AmqpConnection connection = client.connect(); try { AmqpSession session = connection.createSession(); try { session.createReceiver(getQueueName()); fail("Should not be able to consume here."); } catch (Exception ex) { IntegrationTestLogger.LOGGER.info("Caught expected exception"); } connection.getStateInspector().assertValid(); } finally { connection.close(); } } @Test(timeout = 30000) public void testConsumerNotAuthorizedToCreateQueues() throws Exception { AmqpClient client = createAmqpClient(noprivUser, noprivPass); client.setValidator(new AmqpValidator() { @Override public void inspectOpenedResource(Sender sender) { ErrorCondition condition = sender.getRemoteCondition(); if (condition != null && condition.getCondition() != null) { if (!condition.getCondition().equals(AmqpError.UNAUTHORIZED_ACCESS)) { markAsInvalid("Should have been tagged with unauthorized access error"); } } else { markAsInvalid("Sender should have been opened with an error"); } } }); AmqpConnection connection = client.connect(); try { AmqpSession session = connection.createSession(); try { session.createReceiver(getQueueName(getPrecreatedQueueSize() + 1)); fail("Should not be able to consume here."); } catch (Exception ex) { IntegrationTestLogger.LOGGER.info("Caught expected exception"); } connection.getStateInspector().assertValid(); } finally { connection.close(); } } }