From cbeecb0e4e6ef1200ffc6afed4e1100828312850 Mon Sep 17 00:00:00 2001 From: Robert Gemmell Date: Mon, 31 May 2010 16:05:55 +0000 Subject: QPID-2569: Implement the SimpleXML as an OSGi plugin Applied patch from Andrew Kennedy git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@949784 13f79535-47bb-0310-9956-ffa450edef68 --- java/broker-plugins/simple-xml/MANIFEST.MF | 36 ++ java/broker-plugins/simple-xml/build.xml | 29 + .../access/config/PrincipalPermissions.java | 687 +++++++++++++++++++++ .../server/security/access/plugins/SimpleXML.java | 425 +++++++++++++ .../access/plugins/SimpleXMLActivator.java | 22 + .../access/plugins/SimpleXMLConfiguration.java | 57 ++ .../security/access/PrincipalPermissionsTest.java | 240 +++++++ .../security/access/PrincipalPermissions.java | 673 -------------------- .../server/security/access/plugins/SimpleXML.java | 483 --------------- .../security/access/PrincipalPermissionsTest.java | 254 -------- .../qpid/server/security/acl/SimpleACLTest.java | 9 +- 11 files changed, 1498 insertions(+), 1417 deletions(-) create mode 100644 java/broker-plugins/simple-xml/MANIFEST.MF create mode 100644 java/broker-plugins/simple-xml/build.xml create mode 100755 java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java create mode 100644 java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java create mode 100644 java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.java create mode 100644 java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java create mode 100644 java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java delete mode 100755 java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java delete mode 100644 java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java delete mode 100644 java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java (limited to 'java') diff --git a/java/broker-plugins/simple-xml/MANIFEST.MF b/java/broker-plugins/simple-xml/MANIFEST.MF new file mode 100644 index 0000000000..04fe7518df --- /dev/null +++ b/java/broker-plugins/simple-xml/MANIFEST.MF @@ -0,0 +1,36 @@ +Manifest-Version: 1.0 +Bundle-ManifestVersion: 2 +Bundle-Name: Qpid Broker-Plugins Simple XML +Bundle-SymbolicName: broker-plugins-simple-xml +Bundle-Description: Simple XML ACL plugin for Qpid. +Bundle-License: http://www.apache.org/licenses/LICENSE-2.0.txt +Bundle-DocURL: http://www.apache.org/ +Bundle-Version: 1.0.0 +Bundle-Activator: org.apache.qpid.server.security.access.plugins.SimpleXMLActivator +Bundle-RequiredExecutionEnvironment: JavaSE-1.5 +Bundle-ClassPath: . +Bundle-ActivationPolicy: lazy +Import-Package: org.apache.qpid, + org.apache.qpid.framing, + org.apache.qpid.junit.extensions.util, + org.apache.qpid.protocol, + org.apache.qpid.server.configuration, + org.apache.qpid.server.configuration.plugins, + org.apache.qpid.server.exchange, + org.apache.qpid.server.management, + org.apache.qpid.server.plugins, + org.apache.qpid.server.queue, + org.apache.qpid.server.security, + org.apache.qpid.server.security.access, + org.apache.qpid.server.virtualhost, + org.apache.qpid.util, + org.apache.commons.configuration;version=1.0.0, + org.apache.commons.lang;version=1.0.0, + org.apache.commons.lang.builder;version=1.0.0, + org.apache.log4j;version=1.0.0, + javax.management;version=1.0.0, + javax.management.openmbean;version=1.0.0, + org.osgi.util.tracker;version=1.0.0, + org.osgi.framework;version=1.3 +Private-Package: org.apache.qpid.server.security.access.config +Export-Package: org.apache.qpid.server.security.access.plugins diff --git a/java/broker-plugins/simple-xml/build.xml b/java/broker-plugins/simple-xml/build.xml new file mode 100644 index 0000000000..2c26c9129a --- /dev/null +++ b/java/broker-plugins/simple-xml/build.xml @@ -0,0 +1,29 @@ + + + + + + + + + + + + diff --git a/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java b/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java new file mode 100755 index 0000000000..d9fc292f03 --- /dev/null +++ b/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/config/PrincipalPermissions.java @@ -0,0 +1,687 @@ +/* + * + * 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.qpid.server.security.access.config; + +import java.util.HashSet; +import java.util.Iterator; +import java.util.LinkedList; +import java.util.List; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.lang.StringUtils; +import org.apache.log4j.Logger; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.security.Result; + +@SuppressWarnings("unchecked") +public class PrincipalPermissions +{ + public enum Permission + { + CONSUME, + PUBLISH, + CREATEQUEUE, + CREATEEXCHANGE, + ACCESS, + BIND, + UNBIND, + DELETE, + PURGE + } + + private static final Logger _logger = Logger.getLogger(PrincipalPermissions.class); + + private static final Object CONSUME_QUEUES_KEY = new Object(); + private static final Object CONSUME_TEMPORARY_KEY = new Object(); + private static final Object CONSUME_OWN_QUEUES_ONLY_KEY = new Object(); + + private static final Object CREATE_QUEUES_KEY = new Object(); + private static final Object CREATE_EXCHANGES_KEY = new Object(); + + + private static final Object CREATE_QUEUE_TEMPORARY_KEY = new Object(); + private static final Object CREATE_QUEUE_QUEUES_KEY = new Object(); + private static final Object CREATE_QUEUE_EXCHANGES_KEY = new Object(); + + private static final Object CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY = new Object(); + + private static final int PUBLISH_EXCHANGES_KEY = 0; + + private Map _permissions; + private boolean _fullVHostAccess = false; + + private String _user; + + + public PrincipalPermissions(String user) + { + _user = user; + _permissions = new ConcurrentHashMap(); + } + + /** + * + * @param permission the type of permission to check + * + * @param parameters vararg depending on what permission was passed in + * ACCESS: none + * BIND: none + * CONSUME: AMQShortString queueName, Boolean temporary, Boolean ownQueueOnly + * CREATEQUEUE: Boolean temporary, AMQShortString queueName, AMQShortString exchangeName, AMQShortString routingKey + * CREATEEXCHANGE: AMQShortString exchangeName, AMQShortString Class + * DELETE: none + * PUBLISH: Exchange exchange, AMQShortString routingKey + * PURGE: none + * UNBIND: none + */ + public void grant(Permission permission, Object... parameters) + { + switch (permission) + { + case ACCESS:// Parameters : None + grantAccess(permission); + break; + case CONSUME: // Parameters : AMQShortString queueName, Boolean Temporary, Boolean ownQueueOnly + grantConsume(permission, parameters); + break; + case CREATEQUEUE: // Parameters : Boolean temporary, AMQShortString queueName + // , AMQShortString exchangeName , AMQShortString routingKey + grantCreateQueue(permission, parameters); + break; + case CREATEEXCHANGE: + // Parameters AMQShortString exchangeName , AMQShortString Class + grantCreateExchange(permission, parameters); + break; + case PUBLISH: // Parameters : Exchange exchange, AMQShortString routingKey + grantPublish(permission, parameters); + break; + /* The other cases just fall through to no-op */ + case DELETE: + case BIND: // All the details are currently included in the create setup. + case PURGE: + case UNBIND: + break; + } + + } + + private void grantAccess(Permission permission) + { + _fullVHostAccess = true; + } + + private void grantPublish(Permission permission, Object... parameters) { + Map publishRights = (Map) _permissions.get(permission); + + if (publishRights == null) + { + publishRights = new ConcurrentHashMap(); + _permissions.put(permission, publishRights); + } + + if (parameters == null || parameters.length == 0) + { + //If we have no parameters then allow publish to all destinations + // this is signified by having a null value for publish_exchanges + } + else + { + Map publish_exchanges = (Map) publishRights.get(PUBLISH_EXCHANGES_KEY); + + if (publish_exchanges == null) + { + publish_exchanges = new ConcurrentHashMap(); + publishRights.put(PUBLISH_EXCHANGES_KEY, publish_exchanges); + } + + + HashSet routingKeys = (HashSet) publish_exchanges.get(parameters[0]); + + // Check to see if we have a routing key + if (parameters.length == 2) + { + if (routingKeys == null) + { + routingKeys = new HashSet(); + } + //Add routing key to permitted publish destinations + routingKeys.add(parameters[1]); + } + + // Add the updated routingkey list or null if all values allowed + publish_exchanges.put(parameters[0], routingKeys); + } + } + + private void grantCreateExchange(Permission permission, Object... parameters) { + Map rights = (Map) _permissions.get(permission); + if (rights == null) + { + rights = new ConcurrentHashMap(); + _permissions.put(permission, rights); + } + + Map create_exchanges = (Map) rights.get(CREATE_EXCHANGES_KEY); + if (create_exchanges == null) + { + create_exchanges = new ConcurrentHashMap(); + rights.put(CREATE_EXCHANGES_KEY, create_exchanges); + } + + //Should perhaps error if parameters[0] is null; + AMQShortString name = parameters.length > 0 ? (AMQShortString) parameters[0] : null; + AMQShortString className = parameters.length > 1 ? (AMQShortString) parameters[1] : new AMQShortString("direct"); + + //Store the exchangeName / class mapping if the mapping is null + rights.put(name, className); + } + + private void grantCreateQueue(Permission permission, Object... parameters) + { + Map createRights = (Map) _permissions.get(permission); + + if (createRights == null) + { + createRights = new ConcurrentHashMap(); + _permissions.put(permission, createRights); + } + + //The existence of the empty map mean permission to all. + if (parameters.length == 0) + { + return; + } + + // Get the queues map + Map create_queues = (Map) createRights.get(CREATE_QUEUES_KEY); + + //Initialiase the queue permissions if not already done + if (create_queues == null) + { + create_queues = new ConcurrentHashMap(); + //initialise temp queue permission to false and overwrite below if true + create_queues.put(CREATE_QUEUE_TEMPORARY_KEY, false); + createRights.put(CREATE_QUEUES_KEY, create_queues); + } + + //Create empty list of queues + Map create_queues_queues = (Map) create_queues.get(CREATE_QUEUE_QUEUES_KEY); + + if (create_queues_queues == null) + { + create_queues_queues = new ConcurrentHashMap(); + create_queues.put(CREATE_QUEUE_QUEUES_KEY, create_queues_queues); + } + + // If we are initialising and granting CREATE rights to all temporary queues, then that's all we do + Boolean temporary = false; + if (parameters.length == 1) + { + temporary = (Boolean) parameters[0]; + create_queues.put(CREATE_QUEUE_TEMPORARY_KEY, temporary); + return; + } + + //From here we can be permissioning a variety of things, with varying parameters + AMQShortString queueName = parameters.length > 1 ? (AMQShortString) parameters[1] : null; + AMQShortString exchangeName = parameters.length > 2 ? (AMQShortString) parameters[2] : null; + //Set the routingkey to the specified value or the queueName if present + AMQShortString routingKey = (parameters.length > 3 && null != parameters[3]) ? (AMQShortString) parameters[3] : queueName; + // if we have a queueName then we need to store any associated exchange / rk bindings + if (queueName != null) + { + Map queue = (Map) create_queues_queues.get(queueName); + if (queue == null) + { + queue = new ConcurrentHashMap(); + create_queues_queues.put(queueName, queue); + } + + if (exchangeName != null) + { + queue.put(exchangeName, routingKey); + } + + //If no exchange is specified then the presence of the queueName in the map says any exchange is ok + } + + // Store the exchange that we are being granted rights to. This will be used as part of binding + + //Lookup the list of exchanges + Map create_queues_exchanges = (Map) create_queues.get(CREATE_QUEUE_EXCHANGES_KEY); + + if (create_queues_exchanges == null) + { + create_queues_exchanges = new ConcurrentHashMap(); + create_queues.put(CREATE_QUEUE_EXCHANGES_KEY, create_queues_exchanges); + } + + //if we have an exchange + if (exchangeName != null) + { + //Retrieve the list of permitted exchanges. + Map exchanges = (Map) create_queues_exchanges.get(exchangeName); + + if (exchanges == null) + { + exchanges = new ConcurrentHashMap(); + create_queues_exchanges.put(exchangeName, exchanges); + } + + //Store the binding details of queue/rk for this exchange. + if (queueName != null) + { + //Retrieve the list of permitted routingKeys. + Map rKeys = (Map) exchanges.get(exchangeName); + + if (rKeys == null) + { + rKeys = new ConcurrentHashMap(); + exchanges.put(CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY, rKeys); + } + + rKeys.put(queueName, routingKey); + } + } + } + + /** + * Grant consume permissions + */ + private void grantConsume(Permission permission, Object... parameters) + { + Map consumeRights = (Map) _permissions.get(permission); + + if (consumeRights == null) + { + consumeRights = new ConcurrentHashMap(); + _permissions.put(permission, consumeRights); + + //initialise own and temporary rights to false to be overwritten below if set + consumeRights.put(CONSUME_TEMPORARY_KEY, false); + consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, false); + } + + + //if we only have one param then we're permissioning temporary queues and topics + if (parameters.length == 1) + { + Boolean temporary = (Boolean) parameters[0]; + + if (temporary) + { + consumeRights.put(CONSUME_TEMPORARY_KEY, true); + } + } + + //if we have 2 parameters - should be a contract for this, but for now we'll handle it as is + if (parameters.length == 2) + { + AMQShortString queueName = (AMQShortString) parameters[0]; + Boolean ownQueueOnly = (Boolean) parameters[1]; + + if (ownQueueOnly) + { + consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, true); + } + + LinkedList queues = (LinkedList) consumeRights.get(CONSUME_QUEUES_KEY); + if (queues == null) + { + queues = new LinkedList(); + consumeRights.put(CONSUME_QUEUES_KEY, queues); + } + + if (queueName != null) + { + queues.add(queueName); + } + } + } + + /** + * + * @param permission the type of permission to check + * + * @param parameters vararg depending on what permission was passed in + * ACCESS: none + * BIND: QueueBindBody bindmethod, Exchange exchange, AMQQueue queue, AMQShortString routingKey + * CONSUME: AMQQueue queue + * CREATEQUEUE: Boolean autodelete, AMQShortString name + * CREATEEXCHANGE: AMQShortString exchangeName + * DELETE: none + * PUBLISH: Exchange exchange, AMQShortString routingKey + * PURGE: none + * UNBIND: none + */ + public Result authorise(Permission permission, String... parameters) + { + + switch (permission) + { + case ACCESS://No Parameters + return Result.ALLOWED; // The existence of this user-specific PP infers some level of access is authorised + case BIND: // Parameters : QueueBindMethod , exhangeName , queueName, routingKey + return authoriseBind(parameters); + case CREATEQUEUE:// Parameters : autoDelete, queueName + return authoriseCreateQueue(permission, parameters); + case CREATEEXCHANGE: //Parameters: exchangeName + return authoriseCreateExchange(permission, parameters); + case CONSUME: // Parameters : queueName, autoDelete, owner + return authoriseConsume(permission, parameters); + case PUBLISH: // Parameters : exchangeName, routingKey + return authorisePublish(permission, parameters); + /* Fall through */ + case DELETE: + case PURGE: + case UNBIND: + default: + if(_fullVHostAccess) + { + //user has been granted full access to the vhost + return Result.ALLOWED; + } + else + { + //SimpleXML ACL does not implement these permissions and should abstain + return Result.ABSTAIN; + } + } + + } + + private Result authoriseConsume(Permission permission, String... parameters) + { + if(_fullVHostAccess) + { + //user has been granted full access to the vhost + return Result.ALLOWED; + } + + if (parameters.length == 3) + { + AMQShortString queueName = new AMQShortString(parameters[0]); + Boolean autoDelete = Boolean.valueOf(parameters[1]); + AMQShortString owner = new AMQShortString(parameters[2]); + Map queuePermissions = (Map) _permissions.get(permission); + + _logger.error("auth consume on " + StringUtils.join(parameters, ", ")); + + if (queuePermissions == null) + { + //we have a problem - we've never granted this type of permission ..... + return Result.DENIED; + } + + List queues = (List) queuePermissions.get(CONSUME_QUEUES_KEY); + + Boolean temporaryQueues = (Boolean) queuePermissions.get(CONSUME_TEMPORARY_KEY); + Boolean ownQueuesOnly = (Boolean) queuePermissions.get(CONSUME_OWN_QUEUES_ONLY_KEY); + + + // If user is allowed to consume from temporary queues and this is a temp queue then allow it. + if (temporaryQueues && autoDelete) + { + // This will allow consumption from any temporary queue including ones not owned by this user. + // Of course the exclusivity will not be broken. + { + + // if not limited to ownQueuesOnly then ok else check queue Owner. + return (!ownQueuesOnly || owner.equals(_user)) ? Result.ALLOWED : Result.DENIED; + } + } + //if this is a temporary queue and the user does not have permissions for temporary queues then deny + else if (!temporaryQueues && autoDelete) + { + return Result.DENIED; + } + + // if queues are white listed then ensure it is ok + if (queues != null) + { + // if no queues are listed then ALL are ok othereise it must be specified. + if (ownQueuesOnly) + { + if (owner.equals(_user)) + { + return (queues.size() == 0 || queues.contains(queueName)) ? Result.ALLOWED : Result.DENIED; + } + else + { + return Result.DENIED; + } + } + + // If we are + return (queues.size() == 0 || queues.contains(queueName)) ? Result.ALLOWED : Result.DENIED; + } + } + + // Can't authenticate without the right parameters + return Result.DENIED; + } + + private Result authorisePublish(Permission permission, String... parameters) + { + if(_fullVHostAccess) + { + //user has been granted full access to the vhost + return Result.ALLOWED; + } + + Map publishRights = (Map) _permissions.get(permission); + + if (publishRights == null) + { + return Result.DENIED; + } + + Map exchanges = (Map) publishRights.get(PUBLISH_EXCHANGES_KEY); + + // Having no exchanges listed gives full publish rights to all exchanges + if (exchanges == null) + { + return Result.ALLOWED; + } + // Otherwise exchange must be listed in the white list + + // If the map doesn't have the exchange then it isn't allowed + AMQShortString exchangeName = new AMQShortString(parameters[0]); + if (!exchanges.containsKey(exchangeName)) + { + return Result.DENIED; + } + else + { + // Get valid routing keys + HashSet routingKeys = (HashSet) exchanges.get(exchangeName); + + // Having no routingKeys in the map then all are allowed. + if (routingKeys == null) + { + return Result.ALLOWED; + } + else + { + // We have routingKeys so a match must be found to allowed binding + Iterator keys = routingKeys.iterator(); + + AMQShortString publishRKey = new AMQShortString(parameters[1]); + + boolean matched = false; + while (keys.hasNext() && !matched) + { + AMQShortString rkey = (AMQShortString) keys.next(); + + if (rkey.endsWith("*")) + { + matched = publishRKey.startsWith(rkey.subSequence(0, rkey.length() - 1)); + } + else + { + matched = publishRKey.equals(rkey); + } + } + return (matched) ? Result.ALLOWED : Result.DENIED; + } + } + } + + private Result authoriseCreateExchange(Permission permission, String... parameters) + { + if(_fullVHostAccess) + { + //user has been granted full access to the vhost + return Result.ALLOWED; + } + + Map rights = (Map) _permissions.get(permission); + + AMQShortString exchangeName = new AMQShortString(parameters[0]); + + // If the exchange list is doesn't exist then all is allowed else + // check the valid exchanges + if (rights == null || rights.containsKey(exchangeName)) + { + return Result.ALLOWED; + } + else + { + return Result.DENIED; + } + } + + private Result authoriseCreateQueue(Permission permission, String... parameters) + { + if(_fullVHostAccess) + { + //user has been granted full access to the vhost + return Result.ALLOWED; + } + + Map createRights = (Map) _permissions.get(permission); + + // If there are no create rights then deny request + if (createRights == null) + { + return Result.DENIED; + } + + //Look up the Queue Creation Rights + Map create_queues = (Map) createRights.get(CREATE_QUEUES_KEY); + + //Lookup the list of queues allowed to be created + Map create_queues_queues = (Map) create_queues.get(CREATE_QUEUE_QUEUES_KEY); + + + Boolean autoDelete = Boolean.valueOf(parameters[0]); + AMQShortString queueName = new AMQShortString(parameters[1]); + + if (autoDelete)// we have a temporary queue + { + return ((Boolean) create_queues.get(CREATE_QUEUE_TEMPORARY_KEY)) ? Result.ALLOWED : Result.DENIED; + } + else + { + // If there is a white list then check + if (create_queues_queues == null || create_queues_queues.containsKey(queueName)) + { + return Result.ALLOWED; + } + else + { + return Result.DENIED; + } + + } + } + + private Result authoriseBind(String... parameters) + { + if(_fullVHostAccess) + { + //user has been granted full access to the vhost + return Result.ALLOWED; + } + + AMQShortString exchangeName = new AMQShortString(parameters[1]); + AMQShortString bind_queueName = new AMQShortString(parameters[2]); + AMQShortString routingKey = new AMQShortString(parameters[3]); + + //Get all Create Rights for this user + Map bindCreateRights = (Map) _permissions.get(Permission.CREATEQUEUE); + + //Lookup the list of queues + Map bind_create_queues_queues = (Map) bindCreateRights.get(CREATE_QUEUE_QUEUES_KEY); + + // Check and see if we have a queue white list to check + if (bind_create_queues_queues != null) + { + //There a white list for queues + Map exchangeDetails = (Map) bind_create_queues_queues.get(bind_queueName); + + if (exchangeDetails == null) //Then all queue can be bound to all exchanges. + { + return Result.ALLOWED; + } + + // Check to see if we have a white list of routingkeys to check + Map rkeys = (Map) exchangeDetails.get(exchangeName); + + // if keys is null then any rkey is allowed on this exchange + if (rkeys == null) + { + // There is no routingkey white list + return Result.ALLOWED; + } + else + { + // We have routingKeys so a match must be found to allowed binding + Iterator keys = rkeys.keySet().iterator(); + + boolean matched = false; + while (keys.hasNext() && !matched) + { + AMQShortString rkey = (AMQShortString) keys.next(); + if (rkey.endsWith("*")) + { + matched = routingKey.startsWith(rkey.subSequence(0, rkey.length() - 1).toString()); + } + else + { + matched = routingKey.equals(rkey); + } + } + + + return (matched) ? Result.ALLOWED : Result.DENIED; + } + + + } + else + { + //no white list so all allowed. + return Result.ALLOWED; + } + } +} diff --git a/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java b/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java new file mode 100644 index 0000000000..4b3d8f02de --- /dev/null +++ b/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java @@ -0,0 +1,425 @@ +/* + * 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.qpid.server.security.access.plugins; + +import static org.apache.qpid.server.security.access.ObjectProperties.Property.*; + +import java.security.Principal; +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.log4j.Logger; +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; +import org.apache.qpid.server.security.AbstractPlugin; +import org.apache.qpid.server.security.Result; +import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.SecurityPluginFactory; +import org.apache.qpid.server.security.access.ObjectProperties; +import org.apache.qpid.server.security.access.ObjectType; +import org.apache.qpid.server.security.access.Operation; +import org.apache.qpid.server.security.access.config.PrincipalPermissions; +import org.apache.qpid.server.security.access.config.PrincipalPermissions.Permission; + +/** + * This uses the default + */ +public class SimpleXML extends AbstractPlugin +{ + public static final Logger _logger = Logger.getLogger(SimpleXML.class); + + private Map _users; + + public static final SecurityPluginFactory FACTORY = new SecurityPluginFactory() + { + public SimpleXML newInstance(ConfigurationPlugin config) throws ConfigurationException + { + SimpleXML plugin = new SimpleXML(config); + plugin.configure(); + return plugin; + } + + public String getPluginName() + { + return SimpleXML.class.getName(); + } + + public Class getPluginClass() + { + return SimpleXML.class; + } + }; + + public SimpleXML(ConfigurationPlugin config) throws ConfigurationException + { + _config = config.getConfiguration(SimpleXMLConfiguration.class); + } + + public void configure() throws ConfigurationException + { + SimpleXMLConfiguration config = (SimpleXMLConfiguration) _config; + + if (isConfigured()) + { + _users = new ConcurrentHashMap(); + + processConfig(config.getConfiguration()); + } + } + + private void processConfig(Configuration config) + { + processPublish(config); + processConsume(config); + processCreate(config); + processAccess(config); + } + + /** + * @param config XML Configuration + */ + private void processAccess(Configuration config) + { + Configuration accessConfig = config.subset("access"); + + if (accessConfig.isEmpty()) + { + //there is no access configuration to process + return; + } + + // Process users that have full access permission + String[] users = accessConfig.getStringArray("users.user"); + + for (String user : users) + { + grant(Permission.ACCESS, user); + } + } + + /** + * Publish format takes Exchange + Routing Key Pairs + * + * @param config XML Configuration + */ + private void processPublish(Configuration config) + { + Configuration publishConfig = config.subset("publish"); + + // Process users that have full publish permission + String[] users = publishConfig.getStringArray("users.user"); + + for (String user : users) + { + grant(Permission.PUBLISH, user); + } + + // Process exchange limited users + int exchangeCount = 0; + Configuration exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")"); + + while (!exchangeConfig.isEmpty()) + { + // Get Exchange Name + AMQShortString exchangeName = new AMQShortString(exchangeConfig.getString("name")); + + // Get Routing Keys + int keyCount = 0; + Configuration routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")"); + + while (!routingkeyConfig.isEmpty()) + { + // Get RoutingKey Value + AMQShortString routingKeyValue = new AMQShortString(routingkeyConfig.getString("value")); + + // Apply Exchange + RoutingKey permissions to Users + users = routingkeyConfig.getStringArray("users.user"); + for (String user : users) + { + grant(Permission.PUBLISH, user, exchangeName, routingKeyValue); + } + + // Apply permissions to Groups + + // Check for more configs + keyCount++; + routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")"); + } + + // Apply Exchange wide permissions to Users + users = exchangeConfig.getStringArray("exchange(" + exchangeCount + ").users.user"); + + for (String user : users) + { + grant(Permission.PUBLISH, user, exchangeName); + } + + // Apply permissions to Groups + exchangeCount++; + exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")"); + } + } + + private void grant(Permission permission, String user, Object... parameters) + { + PrincipalPermissions permissions = _users.get(user); + + if (permissions == null) + { + permissions = new PrincipalPermissions(user); + } + + _users.put(user, permissions); + permissions.grant(permission, parameters); + } + + /** + * @param config XML Configuration + */ + private void processConsume(Configuration config) + { + boolean temporary = false; + Configuration tempConfig = null; + Configuration consumeConfig = config.subset("consume"); + + tempConfig = consumeConfig.subset("queues.temporary(0)"); + if (tempConfig != null) + { + temporary = true; + } + + //Permission all users who have rights to temp queues and topics + if (tempConfig != null && !tempConfig.isEmpty()) + { + String[] tempUsers = tempConfig.getStringArray("users.user"); + for (String user : tempUsers) + { + grant(Permission.CONSUME, user, temporary); + } + } + + // Process queue limited users + int queueCount = 0; + Configuration queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")"); + + while (!queueConfig.isEmpty()) + { + // Get queue Name + AMQShortString queueName = new AMQShortString(queueConfig.getString("name")); + // if there is no name then there may be a temporary element + + boolean ownQueues = queueConfig.containsKey("own_queues"); + + // Process permissions for this queue + String[] users = queueConfig.getStringArray("users.user"); + for (String user : users) + { + grant(Permission.CONSUME, user, queueName, ownQueues); + } + + // See if we have another config + queueCount++; + queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")"); + } + + // Process users that have full consume permission + String[] users = consumeConfig.getStringArray("users.user"); + + for (String user : users) + { + //NOTE: this call does not appear to do anything inside the grant section for consume + grant(Permission.CONSUME, user); + } + } + + /** + * @param config XML Configuration + */ + private void processCreate(Configuration config) + { + boolean temporary = false; + Configuration tempConfig = null; + + Configuration createConfig = config.subset("create"); + + tempConfig = createConfig.subset("queues.temporary(0)"); + if (tempConfig != null) + { + temporary = true; + } + + //Permission all users who have rights to temp queues and topics + if (tempConfig != null && !tempConfig.isEmpty()) + { + String[] tempUsers = tempConfig.getStringArray("users.user"); + for (String user : tempUsers) + { + grant(Permission.CREATEQUEUE, user, temporary); + } + } + // Process create permissions for queue creation + int queueCount = 0; + Configuration queueConfig = createConfig.subset("queues.queue(" + queueCount + ")"); + + while (!queueConfig.isEmpty()) + { + // Get queue Name + AMQShortString queueName = new AMQShortString(queueConfig.getString("name")); + + int exchangeCount = 0; + Configuration exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")"); + + while (!exchangeConfig.isEmpty()) + { + + AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name")); + AMQShortString routingKey = new AMQShortString(exchangeConfig.getString("routing_key")); + + // Process permissions for this queue + String[] users = exchangeConfig.getStringArray("users.user"); + for (String user : users) + { + //This is broken as the user name is not stored + grant(Permission.CREATEEXCHANGE, user, exchange); + + //This call could be cleaned up as temporary is now being set earlier (above) + grant(Permission.CREATEQUEUE, user, temporary, (queueName.equals("") ? null : queueName), (exchange + .equals("") ? null : exchange), (routingKey.equals("") ? null : routingKey)); + } + + // See if we have another config + exchangeCount++; + exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")"); + } + + // Process users that are not bound to an exchange + String[] users = queueConfig.getStringArray("users.user"); + + for (String user : users) + { + grant(Permission.CREATEQUEUE, user, temporary, queueName); + } + + // See if we have another config + queueCount++; + queueConfig = createConfig.subset("queues.queue(" + queueCount + ")"); + } + + // Process create permissions for exchange creation + int exchangeCount = 0; + Configuration exchangeConfig = createConfig.subset("exchanges.exchange(" + exchangeCount + ")"); + + while (!exchangeConfig.isEmpty()) + { + AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name")); + AMQShortString clazz = new AMQShortString(exchangeConfig.getString("class")); + + // Process permissions for this queue + String[] users = exchangeConfig.getStringArray("users.user"); + for (String user : users) + { + //And this is broken too + grant(Permission.CREATEEXCHANGE, user, exchange, clazz); + } + + // See if we have another config + exchangeCount++; + exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")"); + } + + // Process users that have full create permission + String[] users = createConfig.getStringArray("users.user"); + + for (String user : users) + { + grant(Permission.CREATEEXCHANGE, user); + grant(Permission.CREATEQUEUE, user); + } + } + + public Result access(ObjectType objectType, Object instance) + { + Principal principal = SecurityManager.getThreadPrincipal(); + if (principal == null) + { + return getDefault(); // Default if there is no user associated with the thread + } + PrincipalPermissions principalPermissions = _users.get(principal.getName()); + if (principalPermissions == null) + { + return Result.DENIED; + } + + // Authorise object access + if (objectType == ObjectType.BROKER || objectType == ObjectType.VIRTUALHOST) + { + return principalPermissions.authorise(Permission.ACCESS); + } + + // Default + return getDefault(); + } + + public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties) + { + Principal principal = SecurityManager.getThreadPrincipal(); + if (principal == null) + { + return getDefault(); // Default if there is no user associated with the thread + } + PrincipalPermissions principalPermissions = _users.get(principal.getName()); + if (principalPermissions == null) + { + return Result.DENIED; + } + + // Authorise operation + switch (operation) + { + case CONSUME: + return principalPermissions.authorise(Permission.CONSUME, properties.get(NAME), properties.get(AUTO_DELETE), properties.get(OWNER)); + case PUBLISH: + return principalPermissions.authorise(Permission.PUBLISH, properties.get(NAME), properties.get(ROUTING_KEY)); + case CREATE: + if (objectType == ObjectType.EXCHANGE) + { + return principalPermissions.authorise(Permission.CREATEEXCHANGE, properties.get(NAME)); + } + else if (objectType == ObjectType.QUEUE) + { + return principalPermissions.authorise(Permission.CREATEQUEUE, properties.get(AUTO_DELETE), properties.get(NAME)); + } + case ACCESS: + return principalPermissions.authorise(Permission.ACCESS); + case BIND: + return principalPermissions.authorise(Permission.BIND, null, properties.get(NAME), properties.get(QUEUE_NAME), properties.get(ROUTING_KEY)); + case UNBIND: + return principalPermissions.authorise(Permission.UNBIND); + case DELETE: + return principalPermissions.authorise(Permission.DELETE); + case PURGE: + return principalPermissions.authorise(Permission.PURGE); + } + + // Default + return getDefault(); + } +} diff --git a/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.java b/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.java new file mode 100644 index 0000000000..e5bae0669a --- /dev/null +++ b/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLActivator.java @@ -0,0 +1,22 @@ +package org.apache.qpid.server.security.access.plugins; + +import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; +import org.apache.qpid.server.security.SecurityPluginActivator; +import org.apache.qpid.server.security.SecurityPluginFactory; +import org.osgi.framework.BundleActivator; + +/** + * The OSGi {@link BundleActivator} for {@link SimpleXML}. + */ +public class SimpleXMLActivator extends SecurityPluginActivator +{ + public SecurityPluginFactory getFactory() + { + return SimpleXML.FACTORY; + } + + public ConfigurationPluginFactory getConfigurationFactory() + { + return SimpleXMLConfiguration.FACTORY; + } +} diff --git a/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java b/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java new file mode 100644 index 0000000000..b73ab97080 --- /dev/null +++ b/java/broker-plugins/simple-xml/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXMLConfiguration.java @@ -0,0 +1,57 @@ +/* + * + * 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.qpid.server.security.access.plugins; + +import java.util.Arrays; +import java.util.List; + +import org.apache.commons.configuration.Configuration; +import org.apache.commons.configuration.ConfigurationException; +import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin; +import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory; + +public class SimpleXMLConfiguration extends ConfigurationPlugin +{ + public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory() + { + public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException + { + ConfigurationPlugin instance = new SimpleXMLConfiguration(); + instance.setConfiguration(path, config); + return instance; + } + + public List getParentPaths() + { + return Arrays.asList("security", "virtualhosts.virtualhost.security"); + } + }; + + public String[] getElementsProcessed() + { + return new String[] { "access_control_list" }; + } + + public Configuration getConfiguration() + { + return _configuration.subset("access_control_list"); + } +} diff --git a/java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java b/java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java new file mode 100644 index 0000000000..3cbad83369 --- /dev/null +++ b/java/broker-plugins/simple-xml/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java @@ -0,0 +1,240 @@ +/* + * + * 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.qpid.server.security.access; + +import junit.framework.TestCase; + +import org.apache.qpid.framing.AMQShortString; +import org.apache.qpid.framing.FieldTable; +import org.apache.qpid.server.exchange.DirectExchange; +import org.apache.qpid.server.queue.AMQQueueFactory; +import org.apache.qpid.server.registry.ApplicationRegistry; +import org.apache.qpid.server.security.Result; +import org.apache.qpid.server.security.access.config.PrincipalPermissions; +import org.apache.qpid.server.security.access.config.PrincipalPermissions.Permission; +import org.apache.qpid.server.virtualhost.VirtualHost; + +public class PrincipalPermissionsTest extends TestCase +{ + private String _user = "user"; + private PrincipalPermissions _perms; + + // Common things that are passed to frame constructors + private AMQShortString _queueName = new AMQShortString(this.getClass().getName() + "queue"); + private AMQShortString _tempQueueName = new AMQShortString(this.getClass().getName() + "tempqueue"); + private AMQShortString _exchangeName = new AMQShortString("amq.direct"); + private AMQShortString _routingKey = new AMQShortString(this.getClass().getName() + "route"); + private int _ticket = 1; + private FieldTable _arguments = null; + private boolean _durable = false; + private boolean _autoDelete = false; + private AMQShortString _exchangeType = new AMQShortString("direct"); + private DirectExchange _exchange; + private VirtualHost _virtualHost; + private AMQShortString _owner = new AMQShortString(this.getClass().getName() + "owner"); + private Boolean _temporary = false; + private Boolean _ownQueue = false; + + @Override + public void setUp() + { + //Highlight that this test will cause a new AR to be created + ApplicationRegistry.getInstance(); + + _perms = new PrincipalPermissions(_user); + try + { + _virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"); + _exchange = DirectExchange.TYPE.newInstance(_virtualHost, _exchangeName, _durable, _ticket, _autoDelete); + AMQQueueFactory.createAMQQueueImpl(_queueName, false, _owner , false, false, _virtualHost, _arguments); + AMQQueueFactory.createAMQQueueImpl(_tempQueueName, false, _owner , true, false, _virtualHost, _arguments); + } + catch (Exception e) + { + fail(e.getMessage()); + } + } + + @Override + protected void tearDown() throws Exception + { + //Ensure we close the opened Registry + ApplicationRegistry.remove(); + } + + + public void testPrincipalPermissions() + { + assertNotNull(_perms); + assertEquals(Result.ALLOWED, _perms.authorise(Permission.ACCESS, (String[]) null)); + } + + // FIXME: test has been disabled since the permissions assume that the user has tried to create + // the queue first. QPID-1597 + public void disableTestBind() throws Exception + { + String[] args = new String[]{null, _exchangeName.asString(), _queueName.asString(), _routingKey.asString()}; + + assertEquals(Result.DENIED, _perms.authorise(Permission.BIND, args)); + _perms.grant(Permission.BIND, (Object[]) null); + assertEquals(Result.ALLOWED, _perms.authorise(Permission.BIND, args)); + } + + public void testQueueCreate() + { + Object[] grantArgs = new Object[]{_temporary , _queueName, _exchangeName, _routingKey}; + String[] authArgs = new String[]{Boolean.toString(_autoDelete), _queueName.asString()}; + + assertEquals(Result.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgs)); + _perms.grant(Permission.CREATEQUEUE, grantArgs); + assertEquals(Result.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgs)); + } + + public void testQueueCreateWithNullRoutingKey() + { + Object[] grantArgs = new Object[]{_temporary , _queueName, _exchangeName, null}; + String[] authArgs = new String[]{Boolean.toString(_autoDelete), _queueName.asString()}; + + assertEquals(Result.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgs)); + _perms.grant(Permission.CREATEQUEUE, grantArgs); + assertEquals(Result.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgs)); + } + + // FIXME disabled, this fails due to grant putting the grant into the wrong map QPID-1598 + public void disableTestExchangeCreate() + { + String[] authArgs = new String[]{_exchangeName.asString()}; + Object[] grantArgs = new Object[]{_exchangeName, _exchangeType}; + + assertEquals(Result.DENIED, _perms.authorise(Permission.CREATEEXCHANGE, authArgs)); + _perms.grant(Permission.CREATEEXCHANGE, grantArgs); + assertEquals(Result.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgs)); + } + + public void testConsume() + { + String[] authArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user}; + Object[] grantArgs = new Object[]{_queueName, _ownQueue}; + + // FIXME: This throws a null pointer exception QPID-1599 + // assertFalse(_perms.authorise(Permission.CONSUME, authArgs)); + _perms.grant(Permission.CONSUME, grantArgs); + assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authArgs)); + } + + public void testPublish() + { + String[] authArgs = new String[]{_exchangeName.asString(), _routingKey.asString()}; + Object[] grantArgs = new Object[]{_exchange.getNameShortString(), _routingKey}; + + assertEquals(Result.DENIED, _perms.authorise(Permission.PUBLISH, authArgs)); + _perms.grant(Permission.PUBLISH, grantArgs); + assertEquals(Result.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgs)); + } + + public void testVhostAccess() + { + //Tests that granting a user Virtualhost level access allows all authorisation requests + //where previously they would be denied + + //QPID-2133 createExchange rights currently allow all exchange creation unless rights for creating some + //specific exchanges are granted. Grant a specific exchange creation to cause all others to be denied. + Object[] createArgsCreateExchange = new Object[]{new AMQShortString("madeup"), _exchangeType}; + String[] authArgsCreateExchange = new String[]{_exchangeName.asString()}; + assertEquals("Exchange creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange)); + _perms.grant(Permission.CREATEEXCHANGE, createArgsCreateExchange); + + String[] authArgsPublish = new String[]{_exchangeName.asString(), _routingKey.asString()}; + String[] authArgsConsume = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user}; + String[] authArgsCreateQueue = new String[]{Boolean.toString(_autoDelete), _queueName.asString()}; +// QueueBindBodyImpl bind = new QueueBindBodyImpl(_ticket, _queueName, _exchangeName, _routingKey, _nowait, _arguments); + String[] authArgsBind = new String[]{ null, _exchangeName.asString(), _queueName.asString(), _routingKey.asString()}; + + assertEquals("Exchange creation was not denied", Result.DENIED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange)); + assertEquals("Publish was not denied", Result.DENIED, _perms.authorise(Permission.PUBLISH, authArgsPublish)); + assertEquals("Consume creation was not denied", Result.DENIED, _perms.authorise(Permission.CONSUME, authArgsConsume)); + assertEquals("Queue creation was not denied", Result.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue)); + //BIND pre-grant authorise check disabled due to QPID-1597 + //assertEquals("Binding creation was not denied", Result.DENIED, _perms.authorise(Permission.BIND, authArgsBind)); + + _perms.grant(Permission.ACCESS); + + assertEquals("Exchange creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange)); + assertEquals("Publish was not allowed", Result.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgsPublish)); + assertEquals("Consume creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CONSUME, authArgsConsume)); + assertEquals("Queue creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue)); + assertEquals("Binding creation was not allowed", Result.ALLOWED, _perms.authorise(Permission.BIND, authArgsBind)); + } + + /** + * If the consume permission for temporary queues is for an unnamed queue then is should + * be global for any temporary queue but not for any non-temporary queue + */ + public void testTemporaryUnnamedQueueConsume() + { + String[] authNonTempQArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user}; + String[] authTempQArgs = new String[]{_tempQueueName.asString(), Boolean.TRUE.toString(), _user}; + Object[] grantArgs = new Object[]{true}; + + _perms.grant(Permission.CONSUME, grantArgs); + + //Next line shows up bug - non temp queue should be denied + assertEquals(Result.DENIED, _perms.authorise(Permission.CONSUME, authNonTempQArgs)); + assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs)); + } + + /** + * Test that temporary queue permissions before queue perms in the ACL config work correctly + */ + public void testTemporaryQueueFirstConsume() + { + String[] authNonTempQArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user}; + String[] authTempQArgs = new String[]{_tempQueueName.asString(), Boolean.TRUE.toString(), _user}; + Object[] grantArgs = new Object[]{true}; + Object[] grantNonTempQArgs = new Object[]{_queueName, _ownQueue}; + + //should not matter if the temporary permission is processed first or last + _perms.grant(Permission.CONSUME, grantNonTempQArgs); + _perms.grant(Permission.CONSUME, grantArgs); + + assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authNonTempQArgs)); + assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs)); + } + + /** + * Test that temporary queue permissions after queue perms in the ACL config work correctly + */ + public void testTemporaryQueueLastConsume() + { + String[] authNonTempQArgs = new String[]{_queueName.asString(), Boolean.toString(_autoDelete), _user}; + String[] authTempQArgs = new String[]{_tempQueueName.asString(), Boolean.TRUE.toString(), _user}; + Object[] grantArgs = new Object[]{true}; + Object[] grantNonTempQArgs = new Object[]{_queueName, _ownQueue}; + + //should not matter if the temporary permission is processed first or last + _perms.grant(Permission.CONSUME, grantArgs); + _perms.grant(Permission.CONSUME, grantNonTempQArgs); + + assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authNonTempQArgs)); + assertEquals(Result.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs)); + } +} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java deleted file mode 100755 index e7fc8effaf..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java +++ /dev/null @@ -1,673 +0,0 @@ -/* - * - * 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.qpid.server.security.access; - -import java.util.HashSet; -import java.util.Iterator; -import java.util.LinkedList; -import java.util.List; -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.security.access.ACLPlugin.AuthzResult; - -public class PrincipalPermissions -{ - - private static final Object CONSUME_QUEUES_KEY = new Object(); - private static final Object CONSUME_TEMPORARY_KEY = new Object(); - private static final Object CONSUME_OWN_QUEUES_ONLY_KEY = new Object(); - - private static final Object CREATE_QUEUES_KEY = new Object(); - private static final Object CREATE_EXCHANGES_KEY = new Object(); - - - private static final Object CREATE_QUEUE_TEMPORARY_KEY = new Object(); - private static final Object CREATE_QUEUE_QUEUES_KEY = new Object(); - private static final Object CREATE_QUEUE_EXCHANGES_KEY = new Object(); - - private static final Object CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY = new Object(); - - private static final int PUBLISH_EXCHANGES_KEY = 0; - - private Map _permissions; - private boolean _fullVHostAccess = false; - - private String _user; - - - public PrincipalPermissions(String user) - { - _user = user; - _permissions = new ConcurrentHashMap(); - } - - /** - * - * @param permission the type of permission to check - * - * @param parameters vararg depending on what permission was passed in - * ACCESS: none - * BIND: none - * CONSUME: AMQShortString queueName, Boolean temporary, Boolean ownQueueOnly - * CREATEQUEUE: Boolean temporary, AMQShortString queueName, AMQShortString exchangeName, AMQShortString routingKey - * CREATEEXCHANGE: AMQShortString exchangeName, AMQShortString Class - * DELETE: none - * PUBLISH: Exchange exchange, AMQShortString routingKey - * PURGE: none - * UNBIND: none - */ - public void grant(Permission permission, Object... parameters) - { - switch (permission) - { - case ACCESS:// Parameters : None - grantAccess(permission); - break; - case CONSUME: // Parameters : AMQShortString queueName, Boolean Temporary, Boolean ownQueueOnly - grantConsume(permission, parameters); - break; - case CREATEQUEUE: // Parameters : Boolean temporary, AMQShortString queueName - // , AMQShortString exchangeName , AMQShortString routingKey - grantCreateQueue(permission, parameters); - break; - case CREATEEXCHANGE: - // Parameters AMQShortString exchangeName , AMQShortString Class - grantCreateExchange(permission, parameters); - break; - case PUBLISH: // Parameters : Exchange exchange, AMQShortString routingKey - grantPublish(permission, parameters); - break; - /* The other cases just fall through to no-op */ - case DELETE: - case BIND: // All the details are currently included in the create setup. - case PURGE: - case UNBIND: - break; - } - - } - - private void grantAccess(Permission permission) - { - _fullVHostAccess = true; - } - - private void grantPublish(Permission permission, Object... parameters) { - Map publishRights = (Map) _permissions.get(permission); - - if (publishRights == null) - { - publishRights = new ConcurrentHashMap(); - _permissions.put(permission, publishRights); - } - - if (parameters == null || parameters.length == 0) - { - //If we have no parameters then allow publish to all destinations - // this is signified by having a null value for publish_exchanges - } - else - { - Map publish_exchanges = (Map) publishRights.get(PUBLISH_EXCHANGES_KEY); - - if (publish_exchanges == null) - { - publish_exchanges = new ConcurrentHashMap(); - publishRights.put(PUBLISH_EXCHANGES_KEY, publish_exchanges); - } - - - HashSet routingKeys = (HashSet) publish_exchanges.get(parameters[0]); - - // Check to see if we have a routing key - if (parameters.length == 2) - { - if (routingKeys == null) - { - routingKeys = new HashSet(); - } - //Add routing key to permitted publish destinations - routingKeys.add(parameters[1]); - } - - // Add the updated routingkey list or null if all values allowed - publish_exchanges.put(parameters[0], routingKeys); - } - } - - private void grantCreateExchange(Permission permission, Object... parameters) { - Map rights = (Map) _permissions.get(permission); - if (rights == null) - { - rights = new ConcurrentHashMap(); - _permissions.put(permission, rights); - } - - Map create_exchanges = (Map) rights.get(CREATE_EXCHANGES_KEY); - if (create_exchanges == null) - { - create_exchanges = new ConcurrentHashMap(); - rights.put(CREATE_EXCHANGES_KEY, create_exchanges); - } - - //Should perhaps error if parameters[0] is null; - AMQShortString name = parameters.length > 0 ? (AMQShortString) parameters[0] : null; - AMQShortString className = parameters.length > 1 ? (AMQShortString) parameters[1] : new AMQShortString("direct"); - - //Store the exchangeName / class mapping if the mapping is null - rights.put(name, className); - } - - private void grantCreateQueue(Permission permission, Object... parameters) - { - Map createRights = (Map) _permissions.get(permission); - - if (createRights == null) - { - createRights = new ConcurrentHashMap(); - _permissions.put(permission, createRights); - } - - //The existence of the empty map mean permission to all. - if (parameters.length == 0) - { - return; - } - - // Get the queues map - Map create_queues = (Map) createRights.get(CREATE_QUEUES_KEY); - - //Initialiase the queue permissions if not already done - if (create_queues == null) - { - create_queues = new ConcurrentHashMap(); - //initialise temp queue permission to false and overwrite below if true - create_queues.put(CREATE_QUEUE_TEMPORARY_KEY, false); - createRights.put(CREATE_QUEUES_KEY, create_queues); - } - - //Create empty list of queues - Map create_queues_queues = (Map) create_queues.get(CREATE_QUEUE_QUEUES_KEY); - - if (create_queues_queues == null) - { - create_queues_queues = new ConcurrentHashMap(); - create_queues.put(CREATE_QUEUE_QUEUES_KEY, create_queues_queues); - } - - // If we are initialising and granting CREATE rights to all temporary queues, then that's all we do - Boolean temporary = false; - if (parameters.length == 1) - { - temporary = (Boolean) parameters[0]; - create_queues.put(CREATE_QUEUE_TEMPORARY_KEY, temporary); - return; - } - - //From here we can be permissioning a variety of things, with varying parameters - AMQShortString queueName = parameters.length > 1 ? (AMQShortString) parameters[1] : null; - AMQShortString exchangeName = parameters.length > 2 ? (AMQShortString) parameters[2] : null; - //Set the routingkey to the specified value or the queueName if present - AMQShortString routingKey = (parameters.length > 3 && null != parameters[3]) ? (AMQShortString) parameters[3] : queueName; - // if we have a queueName then we need to store any associated exchange / rk bindings - if (queueName != null) - { - Map queue = (Map) create_queues_queues.get(queueName); - if (queue == null) - { - queue = new ConcurrentHashMap(); - create_queues_queues.put(queueName, queue); - } - - if (exchangeName != null) - { - queue.put(exchangeName, routingKey); - } - - //If no exchange is specified then the presence of the queueName in the map says any exchange is ok - } - - // Store the exchange that we are being granted rights to. This will be used as part of binding - - //Lookup the list of exchanges - Map create_queues_exchanges = (Map) create_queues.get(CREATE_QUEUE_EXCHANGES_KEY); - - if (create_queues_exchanges == null) - { - create_queues_exchanges = new ConcurrentHashMap(); - create_queues.put(CREATE_QUEUE_EXCHANGES_KEY, create_queues_exchanges); - } - - //if we have an exchange - if (exchangeName != null) - { - //Retrieve the list of permitted exchanges. - Map exchanges = (Map) create_queues_exchanges.get(exchangeName); - - if (exchanges == null) - { - exchanges = new ConcurrentHashMap(); - create_queues_exchanges.put(exchangeName, exchanges); - } - - //Store the binding details of queue/rk for this exchange. - if (queueName != null) - { - //Retrieve the list of permitted routingKeys. - Map rKeys = (Map) exchanges.get(exchangeName); - - if (rKeys == null) - { - rKeys = new ConcurrentHashMap(); - exchanges.put(CREATE_QUEUE_EXCHANGES_ROUTINGKEYS_KEY, rKeys); - } - - rKeys.put(queueName, routingKey); - } - } - } - - /** - * Grant consume permissions - */ - private void grantConsume(Permission permission, Object... parameters) - { - Map consumeRights = (Map) _permissions.get(permission); - - if (consumeRights == null) - { - consumeRights = new ConcurrentHashMap(); - _permissions.put(permission, consumeRights); - - //initialise own and temporary rights to false to be overwritten below if set - consumeRights.put(CONSUME_TEMPORARY_KEY, false); - consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, false); - } - - - //if we only have one param then we're permissioning temporary queues and topics - if (parameters.length == 1) - { - Boolean temporary = (Boolean) parameters[0]; - - if (temporary) - { - consumeRights.put(CONSUME_TEMPORARY_KEY, true); - } - } - - //if we have 2 parameters - should be a contract for this, but for now we'll handle it as is - if (parameters.length == 2) - { - AMQShortString queueName = (AMQShortString) parameters[0]; - Boolean ownQueueOnly = (Boolean) parameters[1]; - - if (ownQueueOnly) - { - consumeRights.put(CONSUME_OWN_QUEUES_ONLY_KEY, true); - } - - LinkedList queues = (LinkedList) consumeRights.get(CONSUME_QUEUES_KEY); - if (queues == null) - { - queues = new LinkedList(); - consumeRights.put(CONSUME_QUEUES_KEY, queues); - } - - if (queueName != null) - { - queues.add(queueName); - } - } - } - - /** - * - * @param permission the type of permission to check - * - * @param parameters vararg depending on what permission was passed in - * ACCESS: none - * BIND: QueueBindBody bindmethod, Exchange exchange, AMQQueue queue, AMQShortString routingKey - * CONSUME: AMQQueue queue - * CREATEQUEUE: Boolean autodelete, AMQShortString name - * CREATEEXCHANGE: AMQShortString exchangeName - * DELETE: none - * PUBLISH: Exchange exchange, AMQShortString routingKey - * PURGE: none - * UNBIND: none - */ - public AuthzResult authorise(Permission permission, Object... parameters) - { - - switch (permission) - { - case ACCESS://No Parameters - return AuthzResult.ALLOWED; // The existence of this user-specific PP infers some level of access is authorised - case BIND: // Parameters : QueueBindMethod , Exchange , AMQQueue, AMQShortString routingKey - return authoriseBind(parameters); - case CREATEQUEUE:// Parameters : boolean autodelete, AMQShortString name - return authoriseCreateQueue(permission, parameters); - case CREATEEXCHANGE: - return authoriseCreateExchange(permission, parameters); - case CONSUME: // Parameters : AMQQueue - return authoriseConsume(permission, parameters); - case PUBLISH: // Parameters : Exchange exchange, AMQShortString routingKey - return authorisePublish(permission, parameters); - /* Fall through */ - case DELETE: - case PURGE: - case UNBIND: - default: - if(_fullVHostAccess) - { - //user has been granted full access to the vhost - return AuthzResult.ALLOWED; - } - else - { - //SimpleXML ACL does not implement these permissions and should abstain - return AuthzResult.ABSTAIN; - } - } - - } - - private AuthzResult authoriseConsume(Permission permission, Object... parameters) - { - if(_fullVHostAccess) - { - //user has been granted full access to the vhost - return AuthzResult.ALLOWED; - } - - if (parameters.length == 1 && parameters[0] instanceof AMQQueue) - { - AMQQueue queue = ((AMQQueue) parameters[0]); - Map queuePermissions = (Map) _permissions.get(permission); - - if (queuePermissions == null) - { - //we have a problem - we've never granted this type of permission ..... - return AuthzResult.DENIED; - } - - List queues = (List) queuePermissions.get(CONSUME_QUEUES_KEY); - - Boolean temporaryQueues = (Boolean) queuePermissions.get(CONSUME_TEMPORARY_KEY); - Boolean ownQueuesOnly = (Boolean) queuePermissions.get(CONSUME_OWN_QUEUES_ONLY_KEY); - - - // If user is allowed to consume from temporary queues and this is a temp queue then allow it. - if (temporaryQueues && queue.isAutoDelete()) - { - // This will allow consumption from any temporary queue including ones not owned by this user. - // Of course the exclusivity will not be broken. - { - - // if not limited to ownQueuesOnly then ok else check queue Owner. - return (!ownQueuesOnly || new AMQShortString(queue.getPrincipalHolder().getPrincipal().getName()).equals(_user)) ? AuthzResult.ALLOWED : AuthzResult.DENIED; - } - } - //if this is a temporary queue and the user does not have permissions for temporary queues then deny - else if (!temporaryQueues && queue.isAutoDelete()) - { - return AuthzResult.DENIED; - } - - // if queues are white listed then ensure it is ok - if (queues != null) - { - // if no queues are listed then ALL are ok othereise it must be specified. - if (ownQueuesOnly) - { - if ( new AMQShortString(queue.getPrincipalHolder().getPrincipal().getName()).equals(_user)) - { - return (queues.size() == 0 || queues.contains(queue.getNameShortString())) ? AuthzResult.ALLOWED : AuthzResult.DENIED; - } - else - { - return AuthzResult.DENIED; - } - } - - // If we are - return (queues.size() == 0 || queues.contains(queue.getNameShortString())) ? AuthzResult.ALLOWED : AuthzResult.DENIED; - } - } - - // Can't authenticate without the right parameters - return AuthzResult.DENIED; - } - - private AuthzResult authorisePublish(Permission permission, Object... parameters) - { - if(_fullVHostAccess) - { - //user has been granted full access to the vhost - return AuthzResult.ALLOWED; - } - - Map publishRights = (Map) _permissions.get(permission); - - if (publishRights == null) - { - return AuthzResult.DENIED; - } - - Map exchanges = (Map) publishRights.get(PUBLISH_EXCHANGES_KEY); - - // Having no exchanges listed gives full publish rights to all exchanges - if (exchanges == null) - { - return AuthzResult.ALLOWED; - } - // Otherwise exchange must be listed in the white list - - // If the map doesn't have the exchange then it isn't allowed - if (!exchanges.containsKey(((Exchange) parameters[0]).getNameShortString())) - { - return AuthzResult.DENIED; - } - else - { - - // Get valid routing keys - HashSet routingKeys = (HashSet) exchanges.get(((Exchange)parameters[0]).getNameShortString()); - - // Having no routingKeys in the map then all are allowed. - if (routingKeys == null) - { - return AuthzResult.ALLOWED; - } - else - { - // We have routingKeys so a match must be found to allowed binding - Iterator keys = routingKeys.iterator(); - - - AMQShortString publishRKey = (AMQShortString)parameters[1]; - - boolean matched = false; - while (keys.hasNext() && !matched) - { - AMQShortString rkey = (AMQShortString) keys.next(); - - if (rkey.endsWith("*")) - { - matched = publishRKey.startsWith(rkey.subSequence(0, rkey.length() - 1)); - } - else - { - matched = publishRKey.equals(rkey); - } - } - return (matched) ? AuthzResult.ALLOWED : AuthzResult.DENIED; - } - } - } - - private AuthzResult authoriseCreateExchange(Permission permission, Object... parameters) - { - if(_fullVHostAccess) - { - //user has been granted full access to the vhost - return AuthzResult.ALLOWED; - } - - Map rights = (Map) _permissions.get(permission); - - AMQShortString exchangeName = (AMQShortString) parameters[0]; - - // If the exchange list is doesn't exist then all is allowed else - // check the valid exchanges - if (rights == null || rights.containsKey(exchangeName)) - { - return AuthzResult.ALLOWED; - } - else - { - return AuthzResult.DENIED; - } - } - - private AuthzResult authoriseCreateQueue(Permission permission, Object... parameters) - { - if(_fullVHostAccess) - { - //user has been granted full access to the vhost - return AuthzResult.ALLOWED; - } - - Map createRights = (Map) _permissions.get(permission); - - // If there are no create rights then deny request - if (createRights == null) - { - return AuthzResult.DENIED; - } - - //Look up the Queue Creation Rights - Map create_queues = (Map) createRights.get(CREATE_QUEUES_KEY); - - //Lookup the list of queues allowed to be created - Map create_queues_queues = (Map) create_queues.get(CREATE_QUEUE_QUEUES_KEY); - - - AMQShortString queueName = (AMQShortString) parameters[1]; - Boolean autoDelete = (Boolean) parameters[0]; - - if (autoDelete)// we have a temporary queue - { - return ((Boolean) create_queues.get(CREATE_QUEUE_TEMPORARY_KEY)) ? AuthzResult.ALLOWED : AuthzResult.DENIED; - } - else - { - // If there is a white list then check - if (create_queues_queues == null || create_queues_queues.containsKey(queueName)) - { - return AuthzResult.ALLOWED; - } - else - { - return AuthzResult.DENIED; - } - - } - } - - private AuthzResult authoriseBind(Object... parameters) - { - if(_fullVHostAccess) - { - //user has been granted full access to the vhost - return AuthzResult.ALLOWED; - } - - Exchange exchange = (Exchange) parameters[1]; - - AMQQueue bind_queueName = (AMQQueue) parameters[2]; - AMQShortString routingKey = (AMQShortString) parameters[3]; - - //Get all Create Rights for this user - Map bindCreateRights = (Map) _permissions.get(Permission.CREATEQUEUE); - - //Look up the Queue Creation Rights - Map bind_create_queues = (Map) bindCreateRights.get(CREATE_QUEUES_KEY); - - //Lookup the list of queues - Map bind_create_queues_queues = (Map) bindCreateRights.get(CREATE_QUEUE_QUEUES_KEY); - - // Check and see if we have a queue white list to check - if (bind_create_queues_queues != null) - { - //There a white list for queues - Map exchangeDetails = (Map) bind_create_queues_queues.get(bind_queueName); - - if (exchangeDetails == null) //Then all queue can be bound to all exchanges. - { - return AuthzResult.ALLOWED; - } - - // Check to see if we have a white list of routingkeys to check - Map rkeys = (Map) exchangeDetails.get(exchange.getNameShortString()); - - // if keys is null then any rkey is allowed on this exchange - if (rkeys == null) - { - // There is no routingkey white list - return AuthzResult.ALLOWED; - } - else - { - // We have routingKeys so a match must be found to allowed binding - Iterator keys = rkeys.keySet().iterator(); - - boolean matched = false; - while (keys.hasNext() && !matched) - { - AMQShortString rkey = (AMQShortString) keys.next(); - if (rkey.endsWith("*")) - { - matched = routingKey.startsWith(rkey.subSequence(0, rkey.length() - 1).toString()); - } - else - { - matched = routingKey.equals(rkey); - } - } - - - return (matched) ? AuthzResult.ALLOWED : AuthzResult.DENIED; - } - - - } - else - { - //no white list so all allowed. - return AuthzResult.ALLOWED; - } - } -} diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java deleted file mode 100644 index a5bdf662af..0000000000 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java +++ /dev/null @@ -1,483 +0,0 @@ -/* - * 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.qpid.server.security.access.plugins; - -import org.apache.commons.configuration.Configuration; -import org.apache.qpid.framing.AMQShortString; - -import org.apache.qpid.server.exchange.Exchange; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.security.access.ACLPlugin; -import org.apache.qpid.server.security.access.ACLPluginFactory; -import org.apache.qpid.server.security.access.AccessResult; -import org.apache.qpid.server.security.access.Permission; -import org.apache.qpid.server.security.access.PrincipalPermissions; -import org.apache.qpid.server.security.PrincipalHolder; -import org.apache.qpid.server.virtualhost.VirtualHost; - -import java.util.Map; -import java.util.concurrent.ConcurrentHashMap; - -/** - * This uses the default - */ -public class SimpleXML implements ACLPlugin -{ - public static final ACLPluginFactory FACTORY = new ACLPluginFactory() - { - public boolean supportsTag(String name) - { - return name.startsWith("access_control_list"); - } - - public ACLPlugin newInstance(Configuration config) - { - SimpleXML plugin = new SimpleXML(); - plugin.setConfiguration(config); - return plugin; - } - }; - - private Map _users; - private final AccessResult GRANTED = new AccessResult(this, AccessResult.AccessStatus.GRANTED); - - public SimpleXML() - { - _users = new ConcurrentHashMap(); - } - - public void setConfiguration(Configuration config) - { - processConfig(config); - } - - private void processConfig(Configuration config) - { - processPublish(config); - - processConsume(config); - - processCreate(config); - - processAccess(config); - } - - private void processAccess(Configuration config) - { - Configuration accessConfig = config.subset("access_control_list.access"); - - if(accessConfig.isEmpty()) - { - //there is no access configuration to process - return; - } - - // Process users that have full access permission - String[] users = accessConfig.getStringArray("users.user"); - - for (String user : users) - { - grant(Permission.ACCESS, user); - } - } - - /** - * Publish format takes Exchange + Routing Key Pairs - * - * @param config - * XML Configuration - */ - private void processPublish(Configuration config) - { - Configuration publishConfig = config.subset("access_control_list.publish"); - - // Process users that have full publish permission - String[] users = publishConfig.getStringArray("users.user"); - - for (String user : users) - { - grant(Permission.PUBLISH, user); - } - - // Process exchange limited users - int exchangeCount = 0; - Configuration exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")"); - - while (!exchangeConfig.isEmpty()) - { - // Get Exchange Name - AMQShortString exchangeName = new AMQShortString(exchangeConfig.getString("name")); - - // Get Routing Keys - int keyCount = 0; - Configuration routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")"); - - while (!routingkeyConfig.isEmpty()) - { - // Get RoutingKey Value - AMQShortString routingKeyValue = new AMQShortString(routingkeyConfig.getString("value")); - - // Apply Exchange + RoutingKey permissions to Users - users = routingkeyConfig.getStringArray("users.user"); - for (String user : users) - { - grant(Permission.PUBLISH, user, exchangeName, routingKeyValue); - } - - // Apply permissions to Groups - - // Check for more configs - keyCount++; - routingkeyConfig = exchangeConfig.subset("routing_keys.routing_key(" + keyCount + ")"); - } - - // Apply Exchange wide permissions to Users - users = exchangeConfig.getStringArray("exchange(" + exchangeCount + ").users.user"); - - for (String user : users) - { - grant(Permission.PUBLISH, user, exchangeName); - } - - // Apply permissions to Groups - exchangeCount++; - exchangeConfig = publishConfig.subset("exchanges.exchange(" + exchangeCount + ")"); - } - } - - private void grant(Permission permission, String user, Object... parameters) - { - PrincipalPermissions permissions = _users.get(user); - - if (permissions == null) - { - permissions = new PrincipalPermissions(user); - } - - _users.put(user, permissions); - permissions.grant(permission, parameters); - } - - private void processConsume(Configuration config) - { - boolean temporary = false; - Configuration tempConfig = null; - Configuration consumeConfig = config.subset("access_control_list.consume"); - - tempConfig = consumeConfig.subset("queues.temporary(0)"); - if (tempConfig != null) - { - temporary = true; - } - - //Permission all users who have rights to temp queues and topics - if (tempConfig != null && !tempConfig.isEmpty()) - { - String[] tempUsers = tempConfig.getStringArray("users.user"); - for (String user : tempUsers) - { - grant(Permission.CONSUME, user, temporary); - } - } - - // Process queue limited users - int queueCount = 0; - Configuration queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")"); - - while (!queueConfig.isEmpty()) - { - // Get queue Name - AMQShortString queueName = new AMQShortString(queueConfig.getString("name")); - // if there is no name then there may be a temporary element - - boolean ownQueues = queueConfig.containsKey("own_queues"); - - // Process permissions for this queue - String[] users = queueConfig.getStringArray("users.user"); - for (String user : users) - { - grant(Permission.CONSUME, user, queueName, ownQueues); - } - - // See if we have another config - queueCount++; - queueConfig = consumeConfig.subset("queues.queue(" + queueCount + ")"); - } - - // Process users that have full consume permission - String[] users = consumeConfig.getStringArray("users.user"); - - for (String user : users) - { - //NOTE: this call does not appear to do anything inside the grant section for consume - grant(Permission.CONSUME, user); - } - } - - private void processCreate(Configuration config) - { - boolean temporary = false; - Configuration tempConfig = null; - - Configuration createConfig = config.subset("access_control_list.create"); - - tempConfig = createConfig.subset("queues.temporary(0)"); - if (tempConfig != null) - { - temporary = true; - } - - //Permission all users who have rights to temp queues and topics - if (tempConfig != null && !tempConfig.isEmpty()) - { - String[] tempUsers = tempConfig.getStringArray("users.user"); - for (String user : tempUsers) - { - grant(Permission.CREATEQUEUE, user, temporary); - } - } - // Process create permissions for queue creation - int queueCount = 0; - Configuration queueConfig = createConfig.subset("queues.queue(" + queueCount + ")"); - - while (!queueConfig.isEmpty()) - { - // Get queue Name - AMQShortString queueName = new AMQShortString(queueConfig.getString("name")); - - int exchangeCount = 0; - Configuration exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")"); - - while (!exchangeConfig.isEmpty()) - { - - AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name")); - AMQShortString routingKey = new AMQShortString(exchangeConfig.getString("routing_key")); - - // Process permissions for this queue - String[] users = exchangeConfig.getStringArray("users.user"); - for (String user : users) - { - //This is broken as the user name is not stored - grant(Permission.CREATEEXCHANGE, user, exchange); - - //This call could be cleaned up as temporary is now being set earlier (above) - grant(Permission.CREATEQUEUE, user, temporary, (queueName.equals("") ? null : queueName), (exchange - .equals("") ? null : exchange), (routingKey.equals("") ? null : routingKey)); - } - - // See if we have another config - exchangeCount++; - exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")"); - } - - // Process users that are not bound to an exchange - String[] users = queueConfig.getStringArray("users.user"); - - for (String user : users) - { - grant(Permission.CREATEQUEUE, user, temporary, queueName); - } - - // See if we have another config - queueCount++; - queueConfig = createConfig.subset("queues.queue(" + queueCount + ")"); - } - - // Process create permissions for exchange creation - int exchangeCount = 0; - Configuration exchangeConfig = createConfig.subset("exchanges.exchange(" + exchangeCount + ")"); - - while (!exchangeConfig.isEmpty()) - { - AMQShortString exchange = new AMQShortString(exchangeConfig.getString("name")); - AMQShortString clazz = new AMQShortString(exchangeConfig.getString("class")); - - // Process permissions for this queue - String[] users = exchangeConfig.getStringArray("users.user"); - for (String user : users) - { - //And this is broken too - grant(Permission.CREATEEXCHANGE, user, exchange, clazz); - } - - // See if we have another config - exchangeCount++; - exchangeConfig = queueConfig.subset("exchanges.exchange(" + exchangeCount + ")"); - } - - // Process users that have full create permission - String[] users = createConfig.getStringArray("users.user"); - - for (String user : users) - { - grant(Permission.CREATEEXCHANGE, user); - grant(Permission.CREATEQUEUE, user); - } - - } - - public String getPluginName() - { - return "Simple"; - } - - public AuthzResult authoriseBind(PrincipalHolder session, Exchange exch, AMQQueue queue, AMQShortString routingKey) - { - PrincipalPermissions principalPermissions = _users.get(session.getPrincipal().getName()); - if (principalPermissions == null) - { - return AuthzResult.DENIED; - } - else - { - return principalPermissions.authorise(Permission.BIND, null, exch, queue, routingKey); - } - } - - public AuthzResult authoriseConnect(PrincipalHolder session, VirtualHost virtualHost) - { - PrincipalPermissions principalPermissions = _users.get(session.getPrincipal().getName()); - if (principalPermissions == null) - { - return AuthzResult.DENIED; - } - else - { - return principalPermissions.authorise(Permission.ACCESS); - } - } - - public AuthzResult authoriseConsume(PrincipalHolder session, boolean noAck, AMQQueue queue) - { - PrincipalPermissions principalPermissions = _users.get(session.getPrincipal().getName()); - if (principalPermissions == null) - { - return AuthzResult.DENIED; - } - else - { - return principalPermissions.authorise(Permission.CONSUME, queue); - } - } - - public AuthzResult authoriseConsume(PrincipalHolder session, boolean exclusive, boolean noAck, boolean noLocal, - boolean nowait, AMQQueue queue) - { - return authoriseConsume(session, noAck, queue); - } - - public AuthzResult authoriseCreateExchange(PrincipalHolder session, boolean autoDelete, boolean durable, - AMQShortString exchangeName, boolean internal, boolean nowait, boolean passive, AMQShortString exchangeType) - { - PrincipalPermissions principalPermissions = _users.get(session.getPrincipal().getName()); - if (principalPermissions == null) - { - return AuthzResult.DENIED; - } - else - { - return principalPermissions.authorise(Permission.CREATEEXCHANGE, exchangeName); - } - } - - public AuthzResult authoriseCreateQueue(PrincipalHolder session, boolean autoDelete, boolean durable, boolean exclusive, - boolean nowait, boolean passive, AMQShortString queue) - { - PrincipalPermissions principalPermissions = _users.get(session.getPrincipal().getName()); - if (principalPermissions == null) - { - return AuthzResult.DENIED; - } - else - { - return principalPermissions.authorise(Permission.CREATEQUEUE, autoDelete, queue); - } - } - - public AuthzResult authoriseDelete(PrincipalHolder session, AMQQueue queue) - { - PrincipalPermissions principalPermissions = _users.get(session.getPrincipal().getName()); - if (principalPermissions == null) - { - return AuthzResult.DENIED; - } - else - { - return principalPermissions.authorise(Permission.DELETE); - } - } - - public AuthzResult authoriseDelete(PrincipalHolder session, Exchange exchange) - { - PrincipalPermissions principalPermissions = _users.get(session.getPrincipal().getName()); - if (principalPermissions == null) - { - return AuthzResult.DENIED; - } - else - { - return principalPermissions.authorise(Permission.DELETE); - } - } - - public AuthzResult authorisePublish(PrincipalHolder session, boolean immediate, boolean mandatory, - AMQShortString routingKey, Exchange e) - { - PrincipalPermissions principalPermissions = _users.get(session.getPrincipal().getName()); - if (principalPermissions == null) - { - return AuthzResult.DENIED; - } - else - { - return principalPermissions.authorise(Permission.PUBLISH, e, routingKey); - } - } - - public AuthzResult authorisePurge(PrincipalHolder session, AMQQueue queue) - { - PrincipalPermissions principalPermissions = _users.get(session.getPrincipal().getName()); - if (principalPermissions == null) - { - return AuthzResult.DENIED; - } - else - { - return principalPermissions.authorise(Permission.PURGE); - } - } - - public AuthzResult authoriseUnbind(PrincipalHolder session, Exchange exch, AMQShortString routingKey, AMQQueue queue) - { - PrincipalPermissions principalPermissions = _users.get(session.getPrincipal().getName()); - if (principalPermissions == null) - { - return AuthzResult.DENIED; - } - else - { - return principalPermissions.authorise(Permission.UNBIND); - } - } - -} diff --git a/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java b/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java deleted file mode 100644 index 8704f58e55..0000000000 --- a/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java +++ /dev/null @@ -1,254 +0,0 @@ -/* - * - * 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.qpid.server.security.access; - -import junit.framework.TestCase; - -import org.apache.qpid.framing.AMQShortString; -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.amqp_0_9.ExchangeDeclareBodyImpl; -import org.apache.qpid.framing.amqp_8_0.QueueBindBodyImpl; -import org.apache.qpid.server.exchange.DirectExchange; -import org.apache.qpid.server.queue.AMQQueue; -import org.apache.qpid.server.queue.AMQQueueFactory; -import org.apache.qpid.server.registry.ApplicationRegistry; -import org.apache.qpid.server.security.access.ACLPlugin.AuthzResult; -import org.apache.qpid.server.virtualhost.VirtualHost; - -public class PrincipalPermissionsTest extends TestCase -{ - - private String _user = "user"; - private PrincipalPermissions _perms; - - // Common things that are passed to frame constructors - private AMQShortString _queueName = new AMQShortString(this.getClass().getName()+"queue"); - private AMQShortString _tempQueueName = new AMQShortString(this.getClass().getName()+"tempqueue"); - private AMQShortString _exchangeName = new AMQShortString("amq.direct"); - private AMQShortString _routingKey = new AMQShortString(this.getClass().getName()+"route"); - private int _ticket = 1; - private FieldTable _arguments = null; - private boolean _nowait = false; - private boolean _passive = false; - private boolean _durable = false; - private boolean _autoDelete = false; - private AMQShortString _exchangeType = new AMQShortString("direct"); - private boolean _internal = false; - - private DirectExchange _exchange; - private VirtualHost _virtualHost; - private AMQShortString _owner = new AMQShortString(this.getClass().getName()+"owner"); - private AMQQueue _queue; - private AMQQueue _temporaryQueue; - private Boolean _temporary = false; - private Boolean _ownQueue = false; - - @Override - public void setUp() - { - //Highlight that this test will cause a new AR to be created - ApplicationRegistry.getInstance(); - - _perms = new PrincipalPermissions(_user); - try - { - _virtualHost = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost("test"); - _exchange = DirectExchange.TYPE.newInstance(_virtualHost, _exchangeName, _durable, _ticket, _autoDelete); - _queue = AMQQueueFactory.createAMQQueueImpl(_queueName, false, _owner , false, false, _virtualHost, _arguments); - _temporaryQueue = AMQQueueFactory.createAMQQueueImpl(_tempQueueName, false, _owner , true, false, _virtualHost, _arguments); - } - catch (Exception e) - { - fail(e.getMessage()); - } - } - - @Override - protected void tearDown() throws Exception - { - //Ensure we close the opened Registry - ApplicationRegistry.remove(); - } - - - public void testPrincipalPermissions() - { - assertNotNull(_perms); - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.ACCESS, (Object[]) null)); - } - - // FIXME: test has been disabled since the permissions assume that the user has tried to create - // the queue first. QPID-1597 - public void disableTestBind() throws Exception - { - QueueBindBodyImpl bind = new QueueBindBodyImpl(_ticket, _queueName, _exchangeName, _routingKey, _nowait, _arguments); - Object[] args = new Object[]{bind, _exchange, _queue, _routingKey}; - - assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.BIND, args)); - _perms.grant(Permission.BIND, (Object[]) null); - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.BIND, args)); - } - - public void testQueueCreate() - { - Object[] grantArgs = new Object[]{_temporary , _queueName, _exchangeName, _routingKey}; - Object[] authArgs = new Object[]{_autoDelete, _queueName}; - - assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgs)); - _perms.grant(Permission.CREATEQUEUE, grantArgs); - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgs)); - } - - public void testQueueCreateWithNullRoutingKey() - { - Object[] grantArgs = new Object[]{_temporary , _queueName, _exchangeName, null}; - Object[] authArgs = new Object[]{_autoDelete, _queueName}; - - assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgs)); - _perms.grant(Permission.CREATEQUEUE, grantArgs); - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgs)); - } - - // FIXME disabled, this fails due to grant putting the grant into the wrong map QPID-1598 - public void disableTestExchangeCreate() - { - ExchangeDeclareBodyImpl exchangeDeclare = - new ExchangeDeclareBodyImpl(_ticket, _exchangeName, _exchangeType, _passive, _durable, - _autoDelete, _internal, _nowait, _arguments); - Object[] authArgs = new Object[]{exchangeDeclare}; - Object[] grantArgs = new Object[]{_exchangeName, _exchangeType}; - - assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.CREATEEXCHANGE, authArgs)); - _perms.grant(Permission.CREATEEXCHANGE, grantArgs); - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgs)); - } - - public void testConsume() - { - Object[] authArgs = new Object[]{_queue}; - Object[] grantArgs = new Object[]{_queueName, _ownQueue}; - - /* FIXME: This throws a null pointer exception QPID-1599 - * assertFalse(_perms.authorise(Permission.CONSUME, authArgs)); - */ - _perms.grant(Permission.CONSUME, grantArgs); - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authArgs)); - } - - public void testPublish() - { - Object[] authArgs = new Object[]{_exchange, _routingKey}; - Object[] grantArgs = new Object[]{_exchange.getNameShortString(), _routingKey}; - - assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.PUBLISH, authArgs)); - _perms.grant(Permission.PUBLISH, grantArgs); - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgs)); - } - - public void testVhostAccess() - { - //Tests that granting a user Virtualhost level access allows all authorisation requests - //where previously they would be denied - - //QPID-2133 createExchange rights currently allow all exchange creation unless rights for creating some - //specific exchanges are granted. Grant a specific exchange creation to cause all others to be denied. - Object[] createArgsCreateExchange = new Object[]{new AMQShortString("madeup"), _exchangeType}; - Object[] authArgsCreateExchange = new Object[]{_exchangeName,_exchangeType}; - assertEquals("Exchange creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange)); - _perms.grant(Permission.CREATEEXCHANGE, createArgsCreateExchange); - - Object[] authArgsPublish = new Object[]{_exchange, _routingKey}; - Object[] authArgsConsume = new Object[]{_queue}; - Object[] authArgsCreateQueue = new Object[]{_autoDelete, _queueName}; - QueueBindBodyImpl bind = new QueueBindBodyImpl(_ticket, _queueName, _exchangeName, _routingKey, _nowait, _arguments); - Object[] authArgsBind = new Object[]{bind, _exchange, _queue, _routingKey}; - - assertEquals("Exchange creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange)); - assertEquals("Publish was not denied", AuthzResult.DENIED, _perms.authorise(Permission.PUBLISH, authArgsPublish)); - assertEquals("Consume creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.CONSUME, authArgsConsume)); - assertEquals("Queue creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue)); - //BIND pre-grant authorise check disabled due to QPID-1597 - //assertEquals("Binding creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.BIND, authArgsBind)); - - _perms.grant(Permission.ACCESS); - - assertEquals("Exchange creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange)); - assertEquals("Publish was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgsPublish)); - assertEquals("Consume creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authArgsConsume)); - assertEquals("Queue creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue)); - assertEquals("Binding creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.BIND, authArgsBind)); - } - - /** - * If the consume permission for temporary queues is for an unnamed queue then is should - * be global for any temporary queue but not for any non-temporary queue - */ - public void testTemporaryUnnamedQueueConsume() - { - Object[] authNonTempQArgs = new Object[]{_queue}; - Object[] authTempQArgs = new Object[]{_temporaryQueue}; - Object[] grantArgs = new Object[]{true}; - - _perms.grant(Permission.CONSUME, grantArgs); - - //Next line shows up bug - non temp queue should be denied - assertEquals(AuthzResult.DENIED, _perms.authorise(Permission.CONSUME, authNonTempQArgs)); - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs)); - } - - /** - * Test that temporary queue permissions before queue perms in the ACL config work correctly - */ - public void testTemporaryQueueFirstConsume() - { - Object[] authNonTempQArgs = new Object[]{_queue}; - Object[] authTempQArgs = new Object[]{_temporaryQueue}; - Object[] grantArgs = new Object[]{true}; - Object[] grantNonTempQArgs = new Object[]{_queueName, _ownQueue}; - - //should not matter if the temporary permission is processed first or last - _perms.grant(Permission.CONSUME, grantNonTempQArgs); - _perms.grant(Permission.CONSUME, grantArgs); - - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authNonTempQArgs)); - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs)); - } - - /** - * Test that temporary queue permissions after queue perms in the ACL config work correctly - */ - public void testTemporaryQueueLastConsume() - { - Object[] authNonTempQArgs = new Object[]{_queue}; - Object[] authTempQArgs = new Object[]{_temporaryQueue}; - Object[] grantArgs = new Object[]{true}; - Object[] grantNonTempQArgs = new Object[]{_queueName, _ownQueue}; - - //should not matter if the temporary permission is processed first or last - _perms.grant(Permission.CONSUME, grantArgs); - _perms.grant(Permission.CONSUME, grantNonTempQArgs); - - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authNonTempQArgs)); - assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authTempQArgs)); - } - -} diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java index fc9b07eadd..ee2938f2fe 100644 --- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java +++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java @@ -88,13 +88,8 @@ public class SimpleACLTest extends AbstractACLTestCase try { //get a connection to the 'test2' vhost using the guest user and perform various actions. - Connection conn = getConnection(new AMQConnectionURL( - "amqp://username:password@clientid/test2?brokerlist='" + getBroker() + "'")); - - ((AMQConnection) conn).setConnectionListener(this); - - Session sesh = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); - + Connection conn = getConnection("test2", "guest", "guest"); + Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE); conn.start(); //create Queues and consumers for each -- cgit v1.2.1