summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
authorKeith Wall <kwall@apache.org>2011-11-24 10:43:24 +0000
committerKeith Wall <kwall@apache.org>2011-11-24 10:43:24 +0000
commit59c39b43a3d42498d065962aff6e3b5d58da6dbc (patch)
tree235fc91e82a30a3ded696e07df9177f052659883 /java
parent3a8e623a3ad07fce4e7338ecb68896b7405276f1 (diff)
downloadqpid-python-59c39b43a3d42498d065962aff6e3b5d58da6dbc.tar.gz
QPID-3641: ACLV2 Simplifications and Improvements for Java Broker
Improvements and simplifications to ACL V2 for the Java Broker: 1) Removed 'EXECUTE' operation (we now just have ACCESS and UPDATE like C++ broker) 2) Enable users with management rights for a procedure to complete that procedure without matching AMQP rights (configurable) 3) Fix up system tests (make clearer, remove need for lots of support files) 4) Fix disparity in DENY_LOG and DENY-LOG values between brokers. 5) Get rid of transitive/expand permission rules Work from Robbie Gemmell and myself. git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1205782 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java')
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java111
-rw-r--r--java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java1
-rw-r--r--java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java1
-rw-r--r--java/broker/etc/broker_example.acl63
-rw-r--r--java/broker/etc/config.xml7
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java26
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java137
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java7
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java52
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java10
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/Operation.java3
-rw-r--r--java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java12
-rw-r--r--java/systests/etc/config-systests-aclv2-settings.xml30
-rw-r--r--java/systests/etc/config-systests-aclv2.xml30
-rw-r--r--java/systests/etc/global-default.txt31
-rw-r--r--java/systests/etc/global-externaladminacl-changeloggerleveldenied.txt24
-rw-r--r--java/systests/etc/global-externaladminacl-getallloggerlevelsdenied.txt25
-rw-r--r--java/systests/etc/test-default.txt73
-rw-r--r--java/systests/etc/test-externalacljmx-deleteexchangefailure.txt26
-rw-r--r--java/systests/etc/test-externalacljmx.txt35
-rw-r--r--java/systests/etc/test-logging.txt23
-rw-r--r--java/systests/etc/test2-default.txt21
-rw-r--r--java/systests/etc/virtualhosts-systests-aclv2-settings.xml48
-rw-r--r--java/systests/etc/virtualhosts-systests-aclv2.xml29
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java17
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java88
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/acl/ExhaustiveACLTest.java26
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLFileTest.java19
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java342
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java628
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalAdminACLTest.java186
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java2
33 files changed, 674 insertions, 1464 deletions
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
index 78355a7501..94f05ed265 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/config/RuleSet.java
@@ -36,7 +36,7 @@ import javax.security.auth.Subject;
import org.apache.commons.lang.BooleanUtils;
import org.apache.commons.lang.StringUtils;
-import org.apache.qpid.exchange.ExchangeDefaults;
+import org.apache.log4j.Logger;
import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.security.Result;
import org.apache.qpid.server.security.access.ObjectProperties;
@@ -53,20 +53,15 @@ import org.apache.qpid.server.security.access.logging.AccessControlMessages;
*/
public class RuleSet
{
+ public static final Logger _logger = Logger.getLogger(RuleSet.class);
+
private static final String AT = "@";
private static final String SLASH = "/";
public static final String DEFAULT_ALLOW = "defaultallow";
public static final String DEFAULT_DENY = "defaultdeny";
- public static final String TRANSITIVE = "transitive";
- public static final String EXPAND = "expand";
- public static final String AUTONUMBER = "autonumber";
- public static final String CONTROLLED = "controlled";
- public static final String VALIDATE = "validate";
- public static final List<String> CONFIG_PROPERTIES = Arrays.asList(
- DEFAULT_ALLOW, DEFAULT_DENY, TRANSITIVE, EXPAND, AUTONUMBER, CONTROLLED
- );
+ public static final List<String> CONFIG_PROPERTIES = Arrays.asList(DEFAULT_ALLOW, DEFAULT_DENY);
private static final Integer _increment = 10;
@@ -80,7 +75,6 @@ public class RuleSet
{
// set some default configuration properties
configure(DEFAULT_DENY, Boolean.TRUE);
- configure(TRANSITIVE, Boolean.TRUE);
}
/**
@@ -139,10 +133,20 @@ public class RuleSet
// Save the rules we selected
objects.put(objectType, filtered);
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Cached " + objectType + " RulesList: " + filtered);
+ }
}
// Return the cached rules
- return objects.get(objectType);
+ List<Rule> rules = objects.get(objectType);
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Returning RuleList: " + rules);
+ }
+
+ return rules;
}
@@ -175,20 +179,6 @@ public class RuleSet
return false;
}
- private Permission noLog(Permission permission)
- {
- switch (permission)
- {
- case ALLOW:
- case ALLOW_LOG:
- return Permission.ALLOW;
- case DENY:
- case DENY_LOG:
- default:
- return Permission.DENY;
- }
- }
-
// TODO make this work when group membership is not known at file parse time
public void addRule(Integer number, String identity, Permission permission, Action action)
{
@@ -196,63 +186,13 @@ public class RuleSet
if (!action.isAllowed())
{
- throw new IllegalArgumentException("Action is not allowd: " + action);
+ throw new IllegalArgumentException("Action is not allowed: " + action);
}
if (ruleExists(identity, action))
{
return;
}
- // expand actions - possibly multiply number by
- if (isSet(EXPAND))
- {
- if (action.getOperation() == Operation.CREATE && action.getObjectType() == ObjectType.TOPIC)
- {
- addRule(null, identity, noLog(permission), new Action(Operation.BIND, ObjectType.EXCHANGE,
- new ObjectProperties("amq.topic", action.getProperties().get(ObjectProperties.Property.NAME))));
- ObjectProperties topicProperties = new ObjectProperties();
- topicProperties.put(ObjectProperties.Property.DURABLE, true);
- addRule(null, identity, permission, new Action(Operation.CREATE, ObjectType.QUEUE, topicProperties));
- return;
- }
- if (action.getOperation() == Operation.DELETE && action.getObjectType() == ObjectType.TOPIC)
- {
- addRule(null, identity, noLog(permission), new Action(Operation.UNBIND, ObjectType.EXCHANGE,
- new ObjectProperties("amq.topic", action.getProperties().get(ObjectProperties.Property.NAME))));
- ObjectProperties topicProperties = new ObjectProperties();
- topicProperties.put(ObjectProperties.Property.DURABLE, true);
- addRule(null, identity, permission, new Action(Operation.DELETE, ObjectType.QUEUE, topicProperties));
- return;
- }
- }
-
- // transitive action dependencies
- if (isSet(TRANSITIVE))
- {
- if (action.getOperation() == Operation.CREATE && action.getObjectType() == ObjectType.QUEUE)
- {
- ObjectProperties exchProperties = new ObjectProperties(action.getProperties());
- exchProperties.setName(ExchangeDefaults.DEFAULT_EXCHANGE_NAME);
- exchProperties.put(ObjectProperties.Property.ROUTING_KEY, action.getProperties().get(ObjectProperties.Property.NAME));
- addRule(null, identity, noLog(permission), new Action(Operation.BIND, ObjectType.EXCHANGE, exchProperties));
- if (action.getProperties().isSet(ObjectProperties.Property.AUTO_DELETE))
- {
- addRule(null, identity, noLog(permission), new Action(Operation.DELETE, ObjectType.QUEUE, action.getProperties()));
- }
- }
- else if (action.getOperation() == Operation.DELETE && action.getObjectType() == ObjectType.QUEUE)
- {
- ObjectProperties exchProperties = new ObjectProperties(action.getProperties());
- exchProperties.setName(ExchangeDefaults.DEFAULT_EXCHANGE_NAME);
- exchProperties.put(ObjectProperties.Property.ROUTING_KEY, action.getProperties().get(ObjectProperties.Property.NAME));
- addRule(null, identity, noLog(permission), new Action(Operation.UNBIND, ObjectType.EXCHANGE, exchProperties));
- }
- else if (action.getOperation() != Operation.ACCESS && action.getObjectType() != ObjectType.VIRTUALHOST)
- {
- addRule(null, identity, noLog(permission), new Action(Operation.ACCESS, ObjectType.VIRTUALHOST));
- }
- }
-
// set rule number if needed
Rule rule = new Rule(number, identity, action, permission);
if (rule.getNumber() == null)
@@ -392,24 +332,29 @@ public class RuleSet
// Create the action to check
Action action = new Action(operation, objectType, properties);
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Checking action: " + action);
+ }
+
// get the list of rules relevant for this request
List<Rule> rules = getRules(subject, operation, objectType);
if (rules == null)
{
- if (isSet(CONTROLLED))
+ if(_logger.isDebugEnabled())
{
- // Abstain if there are no rules for this operation
- return Result.ABSTAIN;
- }
- else
- {
- return getDefault();
+ _logger.debug("No rules found, returning default result");
}
+ return getDefault();
}
// Iterate through a filtered set of rules dealing with this identity and operation
for (Rule current : rules)
{
+ if(_logger.isDebugEnabled())
+ {
+ _logger.debug("Checking against rule: " + current);
+ }
// Check if action matches
if (action.matches(current.getAction()))
{
diff --git a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
index a7b3059262..a97b66a287 100644
--- a/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
+++ b/java/broker-plugins/access-control/src/main/java/org/apache/qpid/server/security/access/plugins/AccessControl.java
@@ -101,6 +101,7 @@ public class AccessControl extends AbstractPlugin
return Result.ABSTAIN;
}
+ _logger.debug("Checking " + operation + " " + objectType);
return _ruleSet.check(subject, operation, objectType, properties);
}
diff --git a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
index bd9deac153..4d46a32f45 100644
--- a/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
+++ b/java/broker-plugins/access-control/src/test/java/org/apache/qpid/server/security/access/plugins/RuleSetTest.java
@@ -69,7 +69,6 @@ public class RuleSetTest extends QpidTestCase
super.setUp();
_ruleSet = new RuleSet();
- _ruleSet.configure(RuleSet.TRANSITIVE, Boolean.FALSE);
}
@Override
diff --git a/java/broker/etc/broker_example.acl b/java/broker/etc/broker_example.acl
new file mode 100644
index 0000000000..93955bb7f9
--- /dev/null
+++ b/java/broker/etc/broker_example.acl
@@ -0,0 +1,63 @@
+#
+# 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.
+#
+
+### EXAMPLE ACL V2 FILE
+
+### DEFINE GROUPS ###
+
+#Define a 'messaging-users' group with users 'client' and 'server' in it
+GROUP messaging-users client server
+
+### MANAGEMENT ####
+
+#Allow 'guest' to perform read operations on the Serverinformation mbean and view logger levels
+ACL ALLOW-LOG guest ACCESS METHOD component="ServerInformation"
+ACL ALLOW-LOG guest ACCESS METHOD component="LoggingManagement" name="viewEffectiveRuntimeLoggerLevels"
+
+#Allow 'admin' all management operations
+ACL ALLOW-LOG admin ALL METHOD
+
+### MESSAGING ###
+
+#Example permissions for request-response based messaging.
+
+#Allow 'messaging-users' group to connect to the virtualhost
+ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST
+
+# Client side
+# Allow the 'client' user to publish requests to the request queue and create, consume from, and delete temporary reply queues.
+ACL ALLOW-LOG client CREATE QUEUE temporary="true"
+ACL ALLOW-LOG client CONSUME QUEUE temporary="true"
+ACL ALLOW-LOG client DELETE QUEUE temporary="true"
+ACL ALLOW-LOG client BIND EXCHANGE name="amq.direct" temporary="true"
+ACL ALLOW-LOG client UNBIND EXCHANGE name="amq.direct" temporary="true"
+ACL ALLOW-LOG client PUBLISH EXCHANGE name="amq.direct" routingKey="example.RequestQueue"
+
+# Server side
+# Allow the 'server' user to create and consume from the request queue and publish a response to the temporary response queue created by
+# client.
+ACL ALLOW-LOG server CREATE QUEUE name="example.RequestQueue"
+ACL ALLOW-LOG server CONSUME QUEUE name="example.RequestQueue"
+ACL ALLOW-LOG server BIND EXCHANGE
+ACL ALLOW-LOG server PUBLISH EXCHANGE name="amq.direct" routingKey="TempQueue*"
+
+### DEFAULT ###
+
+#Deny all users from performing all operations
+ACL DENY-LOG all all
diff --git a/java/broker/etc/config.xml b/java/broker/etc/config.xml
index d18e1392e6..389f380c31 100644
--- a/java/broker/etc/config.xml
+++ b/java/broker/etc/config.xml
@@ -80,7 +80,12 @@
</principal-database>
</pd-auth-manager>
- <allow-all />
+ <!-- By default, all authenticated users have permissions to perform all actions -->
+
+ <!-- ACL V2 Example
+ This example illustrates securing the both Management (JMX) and Messaging.
+ <aclv2>${conf}/broker_example.acl</aclv2>
+ -->
<msg-auth>false</msg-auth>
</security>
diff --git a/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java b/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java
index 400ce50bc4..94ab43c851 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java
@@ -170,11 +170,17 @@ public class BindingFactory
{
arguments = Collections.emptyMap();
}
-
- //Perform ACLs
- if (!getVirtualHost().getSecurityManager().authoriseBind(exchange, queue, new AMQShortString(bindingKey)))
+
+ // The default exchange bindings must reflect the existence of queues, allow
+ // all operations on it to succeed. It is up to the broker to prevent illegal
+ // attempts at binding to this exchange, not the ACLs.
+ if(exchange != _defaultExchange)
{
- throw new AMQSecurityException("Permission denied: binding " + bindingKey);
+ //Perform ACLs
+ if (!getVirtualHost().getSecurityManager().authoriseBind(exchange, queue, new AMQShortString(bindingKey)))
+ {
+ throw new AMQSecurityException("Permission denied: binding " + bindingKey);
+ }
}
BindingImpl b = new BindingImpl(bindingKey,queue,exchange,arguments);
@@ -238,10 +244,16 @@ public class BindingFactory
arguments = Collections.emptyMap();
}
- // Check access
- if (!getVirtualHost().getSecurityManager().authoriseUnbind(exchange, new AMQShortString(bindingKey), queue))
+ // The default exchange bindings must reflect the existence of queues, allow
+ // all operations on it to succeed. It is up to the broker to prevent illegal
+ // attempts at binding to this exchange, not the ACLs.
+ if(exchange != _defaultExchange)
{
- throw new AMQSecurityException("Permission denied: binding " + bindingKey);
+ // Check access
+ if (!getVirtualHost().getSecurityManager().authoriseUnbind(exchange, new AMQShortString(bindingKey), queue))
+ {
+ throw new AMQSecurityException("Permission denied: unbinding " + bindingKey);
+ }
}
BindingImpl b = _bindings.remove(new BindingImpl(bindingKey,queue,exchange,arguments));
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
index 0d347873c2..e13e2f4d8f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java
@@ -805,4 +805,9 @@ public class ServerConfiguration extends ConfigurationPlugin
final List<String> disabledFeatures = getListValue("disabledFeatures", Collections.emptyList());
return disabledFeatures;
}
+
+ public boolean getManagementRightsInferAllAccess()
+ {
+ return getBooleanValue("management.managementRightsInferAllAccess", true);
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
index 169195304c..0dd8c95ef3 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java
@@ -33,6 +33,7 @@ import javax.management.JMException;
import javax.management.MBeanInfo;
import javax.management.MBeanOperationInfo;
import javax.management.MBeanServer;
+import javax.management.MalformedObjectNameException;
import javax.management.Notification;
import javax.management.NotificationListener;
import javax.management.ObjectName;
@@ -45,6 +46,7 @@ import org.apache.log4j.Logger;
import org.apache.qpid.server.logging.actors.ManagementActor;
import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.access.Operation;
@@ -56,22 +58,54 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
{
private static final Logger _logger = Logger.getLogger(MBeanInvocationHandlerImpl.class);
+ private final IApplicationRegistry _appRegistry = ApplicationRegistry.getInstance();
private final static String DELEGATE = "JMImplementation:type=MBeanServerDelegate";
private MBeanServer _mbs;
- private static ManagementActor _logActor;
-
+ private final ManagementActor _logActor = new ManagementActor(_appRegistry.getRootMessageLogger());
+ private final boolean _managementRightsInferAllAccess =
+ _appRegistry.getConfiguration().getManagementRightsInferAllAccess();
+
public static MBeanServerForwarder newProxyInstance()
{
final InvocationHandler handler = new MBeanInvocationHandlerImpl();
final Class<?>[] interfaces = new Class[] { MBeanServerForwarder.class };
-
- _logActor = new ManagementActor(ApplicationRegistry.getInstance().getRootMessageLogger());
-
Object proxy = Proxy.newProxyInstance(MBeanServerForwarder.class.getClassLoader(), interfaces, handler);
return MBeanServerForwarder.class.cast(proxy);
}
+ private boolean invokeDirectly(String methodName, Object[] args, Subject subject)
+ {
+ // Allow operations performed locally on behalf of the connector server itself
+ if (subject == null)
+ {
+ return true;
+ }
+
+ if (args == null || DELEGATE.equals(args[0]))
+ {
+ return true;
+ }
+
+ // Allow querying available object names
+ if (methodName.equals("queryNames"))
+ {
+ return true;
+ }
+
+ if (args[0] instanceof ObjectName)
+ {
+ ObjectName mbean = (ObjectName) args[0];
+
+ if(!DefaultManagedObject.DOMAIN.equalsIgnoreCase(mbean.getDomain()))
+ {
+ return true;
+ }
+ }
+
+ return false;
+ }
+
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
final String methodName = getMethodName(method, args);
@@ -95,36 +129,24 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
return null;
}
+ // Restrict access to "createMBean" and "unregisterMBean" to any user
+ if (methodName.equals("createMBean") || methodName.equals("unregisterMBean"))
+ {
+ _logger.debug("User trying to create or unregister an MBean");
+ throw new SecurityException("Access denied: " + methodName);
+ }
+
// Retrieve Subject from current AccessControlContext
AccessControlContext acc = AccessController.getContext();
Subject subject = Subject.getSubject(acc);
try
{
- // Allow operations performed locally on behalf of the connector server itself
- if (subject == null)
+ if(invokeDirectly(methodName, args, subject))
{
return method.invoke(_mbs, args);
}
-
- if (args == null || DELEGATE.equals(args[0]))
- {
- return method.invoke(_mbs, args);
- }
-
- // Restrict access to "createMBean" and "unregisterMBean" to any user
- if (methodName.equals("createMBean") || methodName.equals("unregisterMBean"))
- {
- _logger.debug("User trying to create or unregister an MBean");
- throw new SecurityException("Access denied: " + methodName);
- }
-
- // Allow querying available object names
- if (methodName.equals("queryNames"))
- {
- return method.invoke(_mbs, args);
- }
-
+
// Retrieve JMXPrincipal from Subject
Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
if (principals == null || principals.isEmpty())
@@ -134,23 +156,23 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
// Save the subject
SecurityManager.setThreadSubject(subject);
-
+
// Get the component, type and impact, which may be null
String type = getType(method, args);
String vhost = getVirtualHost(method, args);
int impact = getImpact(method, args);
-
+
// Get the security manager for the virtual host (if set)
SecurityManager security;
if (vhost == null)
{
- security = ApplicationRegistry.getInstance().getSecurityManager();
+ security = _appRegistry.getSecurityManager();
}
else
{
- security = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(vhost).getSecurityManager();
+ security = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhost).getSecurityManager();
}
-
+
if (isAccessMethod(methodName) || impact == MBeanOperationInfo.INFO)
{
// Check for read-only method invocation permission
@@ -159,25 +181,33 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
throw new SecurityException("Permission denied: Access " + methodName);
}
}
- else if (isUpdateMethod(methodName))
- {
- // Check for setting properties permission
- if (!security.authoriseMethod(Operation.UPDATE, type, methodName))
- {
- throw new SecurityException("Permission denied: Update " + methodName);
- }
- }
- else
- {
- // Check for invoking/executing method action/operation permission
- if (!security.authoriseMethod(Operation.EXECUTE, type, methodName))
- {
- throw new SecurityException("Permission denied: Execute " + methodName);
- }
- }
-
- // Actually invoke the method
- return method.invoke(_mbs, args);
+ else
+ {
+ // Check for setting properties permission
+ if (!security.authoriseMethod(Operation.UPDATE, type, methodName))
+ {
+ throw new SecurityException("Permission denied: Update " + methodName);
+ }
+ }
+
+ boolean oldAccessChecksDisabled = false;
+ if(_managementRightsInferAllAccess)
+ {
+ oldAccessChecksDisabled = SecurityManager.setAccessChecksDisabled(true);
+ }
+
+ try
+ {
+ // Actually invoke the method
+ return method.invoke(_mbs, args);
+ }
+ finally
+ {
+ if(_managementRightsInferAllAccess)
+ {
+ SecurityManager.setAccessChecksDisabled(oldAccessChecksDisabled);
+ }
+ }
}
catch (InvocationTargetException e)
{
@@ -290,13 +320,6 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
return (methodName.startsWith("query") || methodName.startsWith("get") || methodName.startsWith("is"));
}
-
- private boolean isUpdateMethod(String methodName)
- {
- //handle standard set methods from MBeanServer
- return methodName.startsWith("set");
- }
-
public void handleNotification(Notification notification, Object handback)
{
assert notification instanceof JMXConnectionNotification;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java
index 8b5ff6781d..ec11e2d39c 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java
@@ -73,11 +73,6 @@ public abstract class AbstractProxyPlugin extends AbstractPlugin
return getDefault();
}
- public Result authoriseExecute(ObjectType object, ObjectProperties properties)
- {
- return getDefault();
- }
-
public Result authoriseUpdate(ObjectType object, ObjectProperties properties)
{
return getDefault();
@@ -121,8 +116,6 @@ public abstract class AbstractProxyPlugin extends AbstractPlugin
return authoriseDelete(objectType, properties);
case PURGE:
return authorisePurge(objectType, properties);
- case EXECUTE:
- return authoriseExecute(objectType, properties);
case UPDATE:
return authoriseUpdate(objectType, properties);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
index f582fed6a0..abf9e3379d 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
@@ -20,10 +20,8 @@ package org.apache.qpid.server.security;
import static org.apache.qpid.server.security.access.ObjectType.EXCHANGE;
import static org.apache.qpid.server.security.access.ObjectType.METHOD;
-import static org.apache.qpid.server.security.access.ObjectType.OBJECT;
import static org.apache.qpid.server.security.access.ObjectType.QUEUE;
import static org.apache.qpid.server.security.access.ObjectType.VIRTUALHOST;
-import static org.apache.qpid.server.security.access.Operation.ACCESS;
import static org.apache.qpid.server.security.access.Operation.BIND;
import static org.apache.qpid.server.security.access.Operation.CONSUME;
import static org.apache.qpid.server.security.access.Operation.CREATE;
@@ -67,7 +65,14 @@ public class SecurityManager
/** Container for the {@link Principal} that is using to this thread. */
private static final ThreadLocal<Subject> _subject = new ThreadLocal<Subject>();
-
+ private static final ThreadLocal<Boolean> _accessChecksDisabled = new ThreadLocal<Boolean>()
+ {
+ protected Boolean initialValue()
+ {
+ return false;
+ }
+ };
+
private PluginManager _pluginManager;
private Map<String, SecurityPluginFactory> _pluginFactories = new HashMap<String, SecurityPluginFactory>();
private Map<String, SecurityPlugin> _globalPlugins = new HashMap<String, SecurityPlugin>();
@@ -194,6 +199,11 @@ public class SecurityManager
private boolean checkAllPlugins(AccessCheck checker)
{
+ if(_accessChecksDisabled.get())
+ {
+ return true;
+ }
+
HashMap<String, SecurityPlugin> remainingPlugins = new HashMap<String, SecurityPlugin>(_globalPlugins);
for (Entry<String, SecurityPlugin> hostEntry : _hostPlugins.entrySet())
@@ -273,21 +283,6 @@ public class SecurityManager
}
});
}
-
- // TODO not implemented yet, awaiting consensus
- public boolean authoriseObject(final String packageName, final String className)
- {
- return checkAllPlugins(new AccessCheck()
- {
- Result allowed(SecurityPlugin plugin)
- {
- ObjectProperties properties = new ObjectProperties();
- properties.put(ObjectProperties.Property.PACKAGE, packageName);
- properties.put(ObjectProperties.Property.CLASS, className);
- return plugin.authorise(ACCESS, OBJECT, properties);
- }
- });
- }
public boolean authoriseMethod(final Operation operation, final String componentName, final String methodName)
{
@@ -329,17 +324,6 @@ public class SecurityManager
});
}
- public boolean authoriseConsume(final boolean exclusive, final boolean noAck, final boolean noLocal, final boolean nowait, final AMQQueue queue)
- {
- return checkAllPlugins(new AccessCheck()
- {
- Result allowed(SecurityPlugin plugin)
- {
- return plugin.authorise(CONSUME, QUEUE, new ObjectProperties(exclusive, noAck, noLocal, nowait, queue));
- }
- });
- }
-
public boolean authoriseCreateExchange(final Boolean autoDelete, final Boolean durable, final AMQShortString exchangeName,
final Boolean internal, final Boolean nowait, final Boolean passive, final AMQShortString exchangeType)
{
@@ -419,4 +403,14 @@ public class SecurityManager
}
});
}
+
+ public static boolean setAccessChecksDisabled(final boolean status)
+ {
+ //remember current value
+ boolean current = _accessChecksDisabled.get();
+
+ _accessChecksDisabled.set(status);
+
+ return current;
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
index 7103b30283..69c7ff185a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
@@ -32,14 +32,12 @@ import java.util.Set;
public enum ObjectType
{
ALL(Operation.ALL),
- VIRTUALHOST(ACCESS),
- QUEUE(CREATE, DELETE, PURGE, CONSUME),
- TOPIC(CREATE, DELETE, PURGE, CONSUME),
- EXCHANGE(ACCESS, CREATE, DELETE, BIND, UNBIND, PUBLISH),
+ VIRTUALHOST(Operation.ALL, ACCESS),
+ QUEUE(Operation.ALL, CREATE, DELETE, PURGE, CONSUME),
+ EXCHANGE(Operation.ALL, ACCESS, CREATE, DELETE, BIND, UNBIND, PUBLISH),
LINK, // Not allowed in the Java broker
ROUTE, // Not allowed in the Java broker
- METHOD(Operation.ALL, ACCESS, UPDATE, EXECUTE),
- OBJECT(ACCESS);
+ METHOD(Operation.ALL, ACCESS, UPDATE);
private EnumSet<Operation> _actions;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/Operation.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/Operation.java
index 06d7f8fd0c..21ea042eed 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/Operation.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/Operation.java
@@ -32,8 +32,7 @@ public enum Operation
UNBIND,
DELETE,
PURGE,
- UPDATE,
- EXECUTE;
+ UPDATE;
public static Operation parse(String text)
{
diff --git a/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java b/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
index 9afd2a45a9..9ee2ed3812 100644
--- a/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
+++ b/java/broker/src/test/java/org/apache/qpid/server/configuration/ServerConfigurationTest.java
@@ -303,6 +303,18 @@ public class ServerConfigurationTest extends QpidTestCase
assertEquals(false, _serverConfig.getManagementEnabled());
}
+ public void testGetManagementRightsInferAllAccess() throws Exception
+ {
+ _serverConfig.initialise();
+
+ //check default
+ assertTrue("default should be true", _serverConfig.getManagementRightsInferAllAccess());
+
+ //update it
+ _config.setProperty("management.managementRightsInferAllAccess", "false");
+ assertFalse("New value should be false", _serverConfig.getManagementRightsInferAllAccess());
+ }
+
public void testGetHeartBeatDelay() throws ConfigurationException
{
// Check default
diff --git a/java/systests/etc/config-systests-aclv2-settings.xml b/java/systests/etc/config-systests-aclv2-settings.xml
deleted file mode 100644
index fbf218fdfa..0000000000
--- a/java/systests/etc/config-systests-aclv2-settings.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - 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.
- -
- -->
-<broker>
- <security>
- <aclv2>${QPID_HOME}/etc/global-default.txt</aclv2>
- </security>
-
- <virtualhosts>${QPID_HOME}/etc/virtualhosts-systests-aclv2.xml</virtualhosts>
-</broker>
-
-
diff --git a/java/systests/etc/config-systests-aclv2.xml b/java/systests/etc/config-systests-aclv2.xml
deleted file mode 100644
index e8b971a2a0..0000000000
--- a/java/systests/etc/config-systests-aclv2.xml
+++ /dev/null
@@ -1,30 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - 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.
- -
- -->
-<configuration>
- <system/>
- <override>
- <xml fileName="${QPID_HOME}/${test.config}" optional="true"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-aclv2-settings.xml"/>
- <xml fileName="${QPID_HOME}/etc/config-systests-settings.xml"/>
- <xml fileName="${QPID_HOME}/etc/config.xml"/>
- </override>
-</configuration>
diff --git a/java/systests/etc/global-default.txt b/java/systests/etc/global-default.txt
deleted file mode 100644
index 01b2c41809..0000000000
--- a/java/systests/etc/global-default.txt
+++ /dev/null
@@ -1,31 +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.
-#
-
-CONFIG expand=true
-
-# This section grants the admin user access to all management methods
-ACL ALLOW admin ALL METHOD
-
-# This section grants the client user access to all management methods except logging
-ACL DENY client ALL METHOD component="LoggingManagement"
-ACL ALLOW client ALL METHOD
-
-# This section grants the server user access to all management methods except configuration
-ACL DENY server ALL METHOD component="ConfigurationManagement"
-ACL ALLOW server ALL METHOD
diff --git a/java/systests/etc/global-externaladminacl-changeloggerleveldenied.txt b/java/systests/etc/global-externaladminacl-changeloggerleveldenied.txt
deleted file mode 100644
index a59b3176cb..0000000000
--- a/java/systests/etc/global-externaladminacl-changeloggerleveldenied.txt
+++ /dev/null
@@ -1,24 +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.
-#
-
-# This section denies the admin user access to logging
-ACL DENY admin UPDATE METHOD component="LoggingManagement" name="setRuntimeRootLoggerLevel"
-
-# This section grants the admin user access to management methods
-ACL ALLOW admin ALL METHOD
diff --git a/java/systests/etc/global-externaladminacl-getallloggerlevelsdenied.txt b/java/systests/etc/global-externaladminacl-getallloggerlevelsdenied.txt
deleted file mode 100644
index ff024b5ee8..0000000000
--- a/java/systests/etc/global-externaladminacl-getallloggerlevelsdenied.txt
+++ /dev/null
@@ -1,25 +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.
-#
-
-# This section denies the admin user access to logging methods
-ACL DENY admin ACCESS METHOD component="LoggingManagement" name="getAvailableLoggerLevels"
-
-# This section grants the admin user access to all management methods
-ACL ALLOW admin ALL METHOD
-
diff --git a/java/systests/etc/test-default.txt b/java/systests/etc/test-default.txt
deleted file mode 100644
index 95e733d077..0000000000
--- a/java/systests/etc/test-default.txt
+++ /dev/null
@@ -1,73 +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.
-#
-
-# This section grants virtualhost access rights
-ACL ALLOW client ACCESS VIRTUALHOST
-ACL ALLOW server ACCESS VIRTUALHOST
-
-# This section grants publish rights to an exchange + routing key pair
-
-# Allow clients to publish requests
-ACL ALLOW client PUBLISH EXCHANGE name="amq.direct" routingKey="example.RequestQueue"
-
-# Allow the processor to respond to a client on their Temporary Topic
-ACL ALLOW server PUBLISH EXCHANGE name="amq.direct" routingKey="tmp_*"
-ACL ALLOW server PUBLISH EXCHANGE name="amq.direct" routingKey="TempQueue*"
-
-# This section grants users the ability to consume from the broker
-
-# Allow client to consume from temporary queues
-ACL ALLOW client CONSUME QUEUE temporary=true
-
-# Only allow the server to consume from the Request Queue
-ACL ALLOW server CONSUME QUEUE name="example.RequestQueue"
-
-# Allow client and server to consume from kipper queues
-ACL ALLOW client CONSUME QUEUE name="clientid:kipper"
-ACL ALLOW server CONSUME QUEUE name="clientid:kipper"
-
-# This section grants users the ability to create/delete queues and exchanges
-
-# Allow clients to create and delete temporary and kipper queue on this exchange
-ACL ALLOW client CREATE QUEUE temporary=true
-ACL ALLOW client DELETE QUEUE temporary=true
-ACL ALLOW client CREATE QUEUE durable="true"
-ACL ALLOW client DELETE QUEUE durable="true"
-
-# Allow the server to create the Request Queue and kipper queue
-ACL ALLOW server CREATE QUEUE name="example.RequestQueue"
-ACL ALLOW server CREATE QUEUE name="clientid:kipper"
-
-## Allow client and server exchange access for the relevant queues
-ACL ALLOW client BIND EXCHANGE name="amq.direct" temporary=true
-ACL ALLOW client UNBIND EXCHANGE name="amq.direct" temporary=true
-ACL ALLOW client BIND EXCHANGE name="amq.direct" durable=true
-ACL ALLOW client UNBIND EXCHANGE name="amq.direct" durable=true
-ACL ALLOW server BIND EXCHANGE name="amq.direct" queueName="example.RequestQueue"
-
-## Allow client and server exchange access for the relevant topics
-ACL ALLOW client BIND EXCHANGE name="amq.topic" durable=true routingKey=kipper
-ACL ALLOW client UNBIND EXCHANGE name="amq.topic" durable=true routingKey=kipper
-ACL ALLOW server BIND EXCHANGE name="amq.topic" durable=true routingKey=kipper
-
-# Action[operation=BIND,objectType=EXCHANGE,properties={OWNER=client, DURABLE=true, QUEUE_NAME=IllegalQueue, AUTO_DELETE=false, ROUTING_KEY=IllegalQueue, NAME=amq.direct, TEMPORARY=false, EXCLUSIVE=false}]
-
-
-ACL ALLOW client CREATE EXCHANGE
-ACL ALLOW server CREATE EXCHANGE
diff --git a/java/systests/etc/test-externalacljmx-deleteexchangefailure.txt b/java/systests/etc/test-externalacljmx-deleteexchangefailure.txt
deleted file mode 100644
index 197fe9dabe..0000000000
--- a/java/systests/etc/test-externalacljmx-deleteexchangefailure.txt
+++ /dev/null
@@ -1,26 +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.
-#
-
-# This section grants virtualhost management rights
-ACL ALLOW admin ALL METHOD
-
-# testDeleteExchangeFailure()
-ACL ALLOW admin CREATE EXCHANGE name="amq.kipper.delete"
-ACL DENY admin DELETE EXCHANGE name="amq.kipper.delete"
-
diff --git a/java/systests/etc/test-externalacljmx.txt b/java/systests/etc/test-externalacljmx.txt
deleted file mode 100644
index f8a94bd44a..0000000000
--- a/java/systests/etc/test-externalacljmx.txt
+++ /dev/null
@@ -1,35 +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.
-#
-
-# This section grants management access to the virtualhost
-ACL ALLOW admin ALL METHOD
-ACL ALLOW client ALL METHOD
-ACL ALLOW server ALL METHOD
-
-# Allow create kipper queue
-ACL ALLOW admin CREATE QUEUE name="kipper" owner = client # kipper
-ACL ALLOW admin BIND EXCHANGE name="amq.direct"
-
-# testCreateExchangeSuccess(), testDeleteExchangeSuccess()
-ACL ALLOW admin CREATE EXCHANGE name="amq.kipper.success"
-ACL ALLOW admin DELETE EXCHANGE name="amq.kipper.success"
-
-# testCreateExchangeFailure()
-ACL DENY admin CREATE EXCHANGE name="amq.kipper.failure"
-
diff --git a/java/systests/etc/test-logging.txt b/java/systests/etc/test-logging.txt
deleted file mode 100644
index 76c6e442e0..0000000000
--- a/java/systests/etc/test-logging.txt
+++ /dev/null
@@ -1,23 +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.
-#
-
-ACL ALLOW client CREATE QUEUE name="allow"
-ACL ALLOW-LOG client CREATE QUEUE name="allow-log"
-ACL DENY client CREATE QUEUE name="deny"
-ACL DENY-LOG client CREATE QUEUE name="deny-log"
diff --git a/java/systests/etc/test2-default.txt b/java/systests/etc/test2-default.txt
deleted file mode 100644
index 0855e631d7..0000000000
--- a/java/systests/etc/test2-default.txt
+++ /dev/null
@@ -1,21 +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.
-#
-
-# This section grants all access rights
-ACL ALLOW guest ALL ALL \ No newline at end of file
diff --git a/java/systests/etc/virtualhosts-systests-aclv2-settings.xml b/java/systests/etc/virtualhosts-systests-aclv2-settings.xml
deleted file mode 100644
index db1ad33a39..0000000000
--- a/java/systests/etc/virtualhosts-systests-aclv2-settings.xml
+++ /dev/null
@@ -1,48 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - 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.
- -
- -->
-<virtualhosts>
- <virtualhost>
- <name>test</name>
- <test>
- <queues>
- <exchange>amq.direct</exchange>
- <!-- 4Mb -->
- <maximumQueueDepth>4235264</maximumQueueDepth>
- <!-- 2Mb -->
- <maximumMessageSize>2117632</maximumMessageSize>
- <!-- 10 mins -->
- <maximumMessageAge>600000</maximumMessageAge>
- </queues>
-
- <security>
- <aclv2>${QPID_HOME}/etc/test-default.txt</aclv2>
- </security>
- </test>
- </virtualhost>
-
- <virtualhost>
- <name>test2</name>
- <test2 />
- </virtualhost>
-</virtualhosts>
-
-
diff --git a/java/systests/etc/virtualhosts-systests-aclv2.xml b/java/systests/etc/virtualhosts-systests-aclv2.xml
deleted file mode 100644
index db396d7ab1..0000000000
--- a/java/systests/etc/virtualhosts-systests-aclv2.xml
+++ /dev/null
@@ -1,29 +0,0 @@
-<?xml version="1.0" encoding="ISO-8859-1"?>
-<!--
- -
- - 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.
- -
- -->
-<configuration>
- <system/>
- <override>
- <xml fileName="${QPID_HOME}/${test.virtualhosts}" optional="true"/>
- <xml fileName="${QPID_HOME}/etc/virtualhosts-systests-aclv2-settings.xml"/>
- <xml fileName="${QPID_HOME}/etc/virtualhosts.xml"/>
- </override>
-</configuration>
diff --git a/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java b/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java
index 2629e82831..e7da4472f5 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/logging/AccessControlLoggingTest.java
@@ -18,7 +18,6 @@
*/
package org.apache.qpid.server.logging;
-import java.io.File;
import java.util.List;
import javax.jms.Connection;
@@ -29,6 +28,7 @@ import org.apache.qpid.AMQException;
import org.apache.qpid.client.AMQSession;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.security.acl.AbstractACLTestCase;
/**
* ACL version 2/3 file testing to verify that ACL actor logging works correctly.
@@ -49,13 +49,18 @@ public class AccessControlLoggingTest extends AbstractTestLogging
public void setUp() throws Exception
{
- setConfigurationProperty("virtualhosts.virtualhost.test.security.aclv2",
- QpidHome + File.separator + "etc" + File.separator + "test-logging.txt");
-
+ // Write out ACL for this test
+ AbstractACLTestCase.writeACLFileUtil(this, "test",
+ "ACL ALLOW client ACCESS VIRTUALHOST",
+ "ACL ALLOW client CREATE QUEUE name='allow'",
+ "ACL ALLOW-LOG client CREATE QUEUE name='allow-log'",
+ "ACL DENY client CREATE QUEUE name='deny'",
+ "ACL DENY-LOG client CREATE QUEUE name='deny-log'");
+
super.setUp();
+
}
- /** FIXME This comes from SimpleACLTest and makes me suspicious. */
@Override
public void tearDown() throws Exception
{
@@ -69,7 +74,7 @@ public class AccessControlLoggingTest extends AbstractTestLogging
//that we provoked with authentication failures, where the test passes - we can ignore on con close
}
}
-
+
/**
* Test that {@code allow} ACL entries do not log anything.
*/
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
index 32b0185f88..a4155d10e2 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/AbstractACLTestCase.java
@@ -24,8 +24,6 @@ import java.io.IOException;
import java.io.PrintWriter;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
-import java.util.Collections;
-import java.util.List;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
@@ -55,29 +53,24 @@ import org.apache.qpid.url.URLSyntaxException;
* @see ExternalACLTest
* @see ExternalACLFileTest
* @see ExternalACLJMXTest
- * @see ExternalAdminACLTest
* @see ExhaustiveACLTest
*/
public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements ConnectionListener
{
/** Used to synchronise {@link #tearDown()} when exceptions are thrown */
- protected CountDownLatch _exceptionReceived;
-
- /** Override this to return the name of the configuration XML file. */
- public abstract String getConfig();
+ protected CountDownLatch _exceptionReceived;
- /** Override this to setup external ACL files for virtual hosts. */
- public List<String> getHostList()
+ /** Override this to return the name of the configuration XML file. */
+ public String getConfig()
{
- return Collections.emptyList();
+ return "config-systests.xml";
}
-
+
/**
* This setup method checks {@link #getConfig()} and {@link #getHostList()} to initialise the broker with specific
* ACL configurations and then runs an optional per-test setup method, which is simply a method with the same name
* as the test, but starting with {@code setUp} rather than {@code test}.
*
- * @see #setUpACLFile(String)
* @see org.apache.qpid.test.utils.QpidBrokerTestCase#setUp()
*/
@Override
@@ -85,12 +78,7 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements
{
// Initialise ACLs.
_configFile = new File("build" + File.separator + "etc" + File.separator + getConfig());
- // Initialise ACL files
- for (String virtualHost : getHostList())
- {
- setUpACLFile(virtualHost);
- }
-
+
// run test specific setup
String testSetup = StringUtils.replace(getName(), "test", "setUp");
try
@@ -124,73 +112,27 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements
}
}
- /**
- * Configures specific ACL files for a virtual host.
- *
- * This method checks for ACL files that exist on the filesystem. If dynamically generatyed ACL files are required in a test,
- * then it is easier to use the {@code setUp} prefix on a method to generate the ACL file. In order, this method looks
- * for three files:
- * <ol>
- * <li><em>virtualhost</em>-<em>class</em>-<em>test</em>.txt
- * <li><em>virtualhost</em>-<em>class</em>.txt
- * <li><em>virtualhost</em>-default.txt
- * </ol>
- * The <em>class</em> and <em>test</em> parts are the test class and method names respectively, with the word {@code test}
- * removed and the rest of the text converted to lowercase. For example, the test class and method named
- * {@code org.apache.qpid.test.AccessExampleTest#testExampleMethod} on the {@code testhost} virtualhost would use
- * one of the following files:
- * <ol>
- * <li>testhost-accessexample-examplemethod.txt
- * <li>testhost-accessexample.txt
- * <li>testhost-default.txt
- * </ol>
- * These files should be copied to the <em>${QPID_HOME}/etc</em> directory when the test is run.
- *
- * @see #writeACLFile(String, String...)
- */
- public void setUpACLFile(String virtualHost) throws IOException, ConfigurationException
+ public void writeACLFile(final String vhost, final String...rules) throws ConfigurationException, IOException
{
- String path = "build" + File.separator + "etc";
- String className = StringUtils.substringBeforeLast(getClass().getSimpleName().toLowerCase(), "test");
- String testName = StringUtils.substringAfter(getName(), "test").toLowerCase();
-
- File aclFile = new File(path, virtualHost + "-" + className + "-" + testName + ".txt");
- if (!aclFile.exists())
- {
- aclFile = new File(path, virtualHost + "-" + className + ".txt");
- if (!aclFile.exists())
- {
- aclFile = new File(path, virtualHost + "-" + "default.txt");
- }
- }
-
- // Set the ACL file configuration property
- if (virtualHost.equals("global"))
- {
- setConfigurationProperty("security.aclv2", aclFile.getAbsolutePath());
- }
- else
- {
- setConfigurationProperty("virtualhosts.virtualhost." + virtualHost + ".security.aclv2", aclFile.getAbsolutePath());
- }
+ writeACLFileUtil(this, vhost, rules);
}
- public void writeACLFile(String vhost, String...rules) throws ConfigurationException, IOException
+ public static void writeACLFileUtil(QpidBrokerTestCase testcase, String vhost, String...rules) throws ConfigurationException, IOException
{
- File aclFile = File.createTempFile(getClass().getSimpleName(), getName());
+ File aclFile = File.createTempFile(testcase.getClass().getSimpleName(), testcase.getName());
aclFile.deleteOnExit();
- if ("global".equals(vhost))
+ if (vhost == null)
{
- setConfigurationProperty("security.aclv2", aclFile.getAbsolutePath());
+ testcase.setConfigurationProperty("security.aclv2", aclFile.getAbsolutePath());
}
else
{
- setConfigurationProperty("virtualhosts.virtualhost." + vhost + ".security.aclv2", aclFile.getAbsolutePath());
+ testcase.setConfigurationProperty("virtualhosts.virtualhost." + vhost + ".security.aclv2", aclFile.getAbsolutePath());
}
PrintWriter out = new PrintWriter(new FileWriter(aclFile));
- out.println(String.format("# %s", getTestName()));
+ out.println(String.format("# %s", testcase.getName()));
for (String line : rules)
{
out.println(line);
@@ -265,7 +207,7 @@ public abstract class AbstractACLTestCase extends QpidBrokerTestCase implements
public void check403Exception(Throwable t) throws Exception
{
assertNotNull("There was no linked exception", t);
- assertTrue("Wrong linked exception type", t instanceof AMQException);
+ assertTrue("Wrong linked exception type : " + t.getClass(), t instanceof AMQException);
assertEquals("Incorrect error code received", 403, ((AMQException) t).getErrorCode().getCode());
//use the latch to ensure the control thread waits long enough for the exception thread
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExhaustiveACLTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExhaustiveACLTest.java
index 1b2c98d30a..4f2464e186 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExhaustiveACLTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExhaustiveACLTest.java
@@ -18,9 +18,6 @@
*/
package org.apache.qpid.server.security.acl;
-import java.util.Arrays;
-import java.util.List;
-
import javax.jms.Connection;
import javax.jms.Session;
@@ -31,7 +28,7 @@ import org.apache.qpid.protocol.AMQConstant;
/**
* ACL version 2/3 file testing to verify that ACL entries control queue creation with specific properties.
- *
+ *
* Tests have their own ACL files that setup specific permissions, and then try to create queues with every possible combination
* of properties to show that rule matching works correctly. For example, a rule that specified {@code autodelete="true"} for
* queues with {@link name="temp.true.*"} as well should not affect queues that have names that do not match, or queues that
@@ -39,18 +36,7 @@ import org.apache.qpid.protocol.AMQConstant;
*/
public class ExhaustiveACLTest extends AbstractACLTestCase
{
- @Override
- public String getConfig()
- {
- return "config-systests-aclv2.xml";
- }
- @Override
- public List<String> getHostList()
- {
- return Arrays.asList("test", "test2");
- }
-
/**
* Creates a queue.
*
@@ -130,11 +116,6 @@ public class ExhaustiveACLTest extends AbstractACLTestCase
createQueueFailure("test", "client", "temp.false.07", true, false);
createQueueFailure("test", "server", "temp.true.08", true, false);
createQueueFailure("test", "client", "temp.other.09", false, false);
- createQueueSuccess("test2", "guest", "temp.true.01", false, false);
- createQueueSuccess("test2", "guest", "temp.false.02", true, false);
- createQueueSuccess("test2", "guest", "temp.true.03", true, false);
- createQueueSuccess("test2", "guest", "temp.false.04", false, false);
- createQueueSuccess("test2", "guest", "temp.other.05", false, false);
}
public void setUpAuthoriseCreateQueue() throws Exception
@@ -161,10 +142,6 @@ public class ExhaustiveACLTest extends AbstractACLTestCase
createQueueFailure("test", "server", "create.05", true, false);
createQueueFailure("test", "server", "create.06", false, true);
createQueueFailure("test", "server", "create.07", true, false);
- createQueueSuccess("test2", "guest", "create.00", true, true);
- createQueueSuccess("test2", "guest", "create.01", true, false);
- createQueueSuccess("test2", "guest", "create.02", false, true);
- createQueueSuccess("test2", "guest", "create.03", true, false);
}
public void setUpAuthoriseCreateQueueBoth() throws Exception
@@ -190,6 +167,5 @@ public class ExhaustiveACLTest extends AbstractACLTestCase
createQueueSuccess("test", "client", "tmp.00", true, false);
createQueueSuccess("test", "server", "tmp.01", true, false);
createQueueSuccess("test", "guest", "tmp.02", true, false);
- createQueueSuccess("test2", "guest", "create.02", false, false);
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLFileTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLFileTest.java
index 1d08015669..5ab2fede83 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLFileTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLFileTest.java
@@ -18,9 +18,6 @@
*/
package org.apache.qpid.server.security.acl;
-import java.util.Arrays;
-import java.util.List;
-
import javax.jms.Connection;
import javax.jms.Session;
@@ -38,18 +35,6 @@ import org.apache.qpid.framing.AMQShortString;
*/
public class ExternalACLFileTest extends AbstractACLTestCase
{
- @Override
- public String getConfig()
- {
- return "config-systests-aclv2.xml";
- }
-
- @Override
- public List<String> getHostList()
- {
- return Arrays.asList("test");
- }
-
private void createQueuePrefixList(String prefix, int count)
{
try
@@ -99,6 +84,7 @@ public class ExternalACLFileTest extends AbstractACLTestCase
{
writeACLFile(
"test",
+ "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
"acl allow client create queue name=mixed.000",
"ACL ALLOW client CREATE QUEUE NAME=mixed.001",
"Acl Allow client Create Queue Name=mixed.002",
@@ -116,6 +102,7 @@ public class ExternalACLFileTest extends AbstractACLTestCase
{
writeACLFile(
"test",
+ "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
"acl allow client create queue name=continuation.000",
"acl allow client create queue \\",
" name=continuation.001",
@@ -143,6 +130,7 @@ public class ExternalACLFileTest extends AbstractACLTestCase
{
writeACLFile(
"test",
+ "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
"acl allow client create queue name=whitespace.000",
"acl\tallow\tclient\tcreate\tqueue\tname=whitespace.001",
"acl allow client create queue name = whitespace.002",
@@ -160,6 +148,7 @@ public class ExternalACLFileTest extends AbstractACLTestCase
{
writeACLFile(
"test",
+ "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
"acl allow client create queue name='quoting.ABC.000'",
"acl allow client create queue name='quoting.*.000'",
"acl allow client create queue name='quoting.#.000'",
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java
index 4552cf7004..427d253ca5 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLJMXTest.java
@@ -18,36 +18,26 @@
*/
package org.apache.qpid.server.security.acl;
-import java.util.Arrays;
-import java.util.List;
+import java.lang.management.ManagementFactory;
+import java.lang.management.RuntimeMXBean;
-import org.apache.qpid.AMQConnectionClosedException;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.AMQSecurityException;
-import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.management.common.mbeans.ServerInformation;
+import org.apache.qpid.server.management.ManagedObject;
+import org.apache.qpid.server.security.access.ObjectType;
import org.apache.qpid.test.utils.JMXTestUtils;
/**
- * Tests that ACL entries that apply to AMQP objects also apply when those objects are accessed via JMX.
+ * Tests that access to the JMX interface is governed only by {@link ObjectType#METHOD}/{@link ObjectType#ALL}
+ * rules and AMQP rights have no effect.
+ *
+ * Ensures that objects outside the Qpid domain ({@link ManagedObject#DOMAIN}) are not governed by the ACL model.
*/
public class ExternalACLJMXTest extends AbstractACLTestCase
{
private JMXTestUtils _jmx;
-
- private static final String QUEUE_NAME = "kipper";
- private static final String EXCHANGE_NAME = "amq.kipper";
-
- @Override
- public String getConfig()
- {
- return "config-systests-aclv2.xml";
- }
- @Override
- public List<String> getHostList()
- {
- return Arrays.asList("test");
- }
+ private static final String TEST_QUEUE_OWNER = "admin";
+ private static final String TEST_VHOST = "test";
@Override
public void setUp() throws Exception
@@ -65,180 +55,264 @@ public class ExternalACLJMXTest extends AbstractACLTestCase
super.tearDown();
}
- // test-externalacljmx.txt
- // create queue owner=client # success
- public void testCreateClientQueueSuccess() throws Exception
- {
- //Queue Parameters
- String queueOwner = "client";
-
- _jmx.createQueue("test", QUEUE_NAME, queueOwner, true);
+ /**
+ * Ensure an empty ACL defaults to DENY ALL.
+ */
+ public void setUpDenyAllIsDefault() throws Exception
+ {
+ writeACLFile(null, "#Empty ACL file");
}
- // test-externalacljmx.txt
- // create queue owner=client # failure
- public void testCreateServerQueueFailure() throws Exception
- {
- //Queue Parameters
- String queueOwner = "server";
-
+ public void testDenyAllIsDefault() throws Exception
+ {
+ //try a broker-level method
+ ServerInformation info = _jmx.getServerInformation();
try
{
- _jmx.createQueue("test", QUEUE_NAME, queueOwner, true);
-
- fail("Queue create should fail");
+ info.resetStatistics();
+ fail("Exception not thrown");
}
- catch (Exception e)
+ catch (SecurityException e)
{
- assertNotNull("Cause is not set", e.getCause());
- assertEquals("Cause message incorrect",
- "org.apache.qpid.AMQSecurityException: Permission denied: queue-name 'kipper' [error code 403: access refused]", e.getCause().getMessage());
+ assertEquals("Cause message incorrect", "Permission denied: Update resetStatistics", e.getMessage());
}
- }
- // no create queue acl in file # failure
- public void testCreateQueueFailure() throws Exception
- {
- //Queue Parameters
- String queueOwner = "guest";
-
+ //try a vhost-level method
try
{
- _jmx.createQueue("test", QUEUE_NAME, queueOwner, true);
-
- fail("Queue create should fail");
+ _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true);
+ fail("Exception not thrown");
}
catch (Exception e)
{
- assertNotNull("Cause is not set", e.getCause());
- assertEquals("Cause message incorrect",
- "org.apache.qpid.AMQSecurityException: Permission denied: queue-name 'kipper' [error code 403: access refused]", e.getCause().getMessage());
+ assertEquals("Cause message incorrect", "Permission denied: Update createNewQueue", e.getMessage());
}
+
+ // Ensure that calls to MBeans outside the Qpid domain are not impeded.
+ final RuntimeMXBean runtimeBean = _jmx.getManagedObject(RuntimeMXBean.class, ManagementFactory.RUNTIME_MXBEAN_NAME);
+ runtimeBean.getName();
+ // PASS
}
- // test-externalacljmx.txt
- // allow create exchange name=amq.kipper.success
- public void testCreateExchangeSuccess() throws Exception
- {
- _jmx.createExchange("test", EXCHANGE_NAME + ".success", "direct", true);
+ /**
+ * Ensure an ALLOW ALL ALL rule allows access to both getters/setters.
+ */
+ public void setUpAllowAll() throws Exception
+ {
+ writeACLFile(null, "ACL ALLOW ALL ALL");
}
- // test-externalacljmx.txt
- // deny create exchange name=amq.kipper.failure
- public void testCreateExchangeFailure() throws Exception
- {
- try
- {
- _jmx.createExchange("test", EXCHANGE_NAME + ".failure", "direct", true);
-
- fail("Exchange create should fail");
- }
- catch (Exception e)
- {
- assertNotNull("Cause is not set", e.getCause());
- assertEquals("Cause message incorrect",
- "org.apache.qpid.AMQSecurityException: Permission denied: exchange-name 'amq.kipper.failure' [error code 403: access refused]", e.getCause().getMessage());
- }
+ public void testAllowAll() throws Exception
+ {
+ ServerInformation info = _jmx.getServerInformation();
+ info.getBuildVersion(); // getter - requires ACCESS
+ info.resetStatistics(); // setter - requires UPDATE
+ // PASS
}
- // test-externalacljmx.txt
- // allow create exchange name=amq.kipper.success
- // allow delete exchange name=amq.kipper.success
- public void testDeleteExchangeSuccess() throws Exception
- {
- _jmx.createExchange("test", EXCHANGE_NAME + ".success", "direct", true);
- _jmx.unregisterExchange("test", EXCHANGE_NAME + ".success");
+ /**
+ * admin user is denied at broker level but allowed at vhost level.
+ */
+ public void setUpVhostAllowOverridesGlobalDeny() throws Exception
+ {
+ writeACLFile(null,
+ "ACL DENY admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
+ writeACLFile(TEST_VHOST,
+ "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
}
- // test-externalacljmx-deleteexchangefailure.txt
- // allow create exchange name=amq.kipper.delete
- // deny delete exchange name=amq.kipper.delete
- public void testDeleteExchangeFailure() throws Exception
- {
- _jmx.createExchange("test", EXCHANGE_NAME + ".delete", "direct", true);
+ public void testVhostAllowOverridesGlobalDeny() throws Exception
+ {
+ //try a vhost-level method on the allowed vhost
+ _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true);
+
+ //try a vhost-level method on a different vhost
try
{
- _jmx.unregisterExchange("test", EXCHANGE_NAME + ".delete");
-
- fail("Exchange delete should fail");
+ _jmx.createQueue("development", getTestQueueName(), TEST_QUEUE_OWNER, true);
+ fail("Exception not thrown");
}
- catch (Exception e)
+ catch (SecurityException e)
{
- assertNotNull("Cause is not set", e.getCause());
- assertEquals("Cause message incorrect",
- "org.apache.qpid.AMQSecurityException: Permission denied [error code 403: access refused]", e.getCause().getMessage());
+ assertEquals("Cause message incorrect", "Permission denied: Update createNewQueue", e.getMessage());
}
}
-
+
+
/**
- * admin user has JMX right but not AMQP
+ * admin user is allowed all update methods on the component at broker level.
*/
- public void setUpCreateQueueJMXRights() throws Exception
+ public void setUpUpdateComponentOnlyAllow() throws Exception
{
- writeACLFile("test",
- "ACL ALLOW admin EXECUTE METHOD component=\"VirtualHost.VirtualHostManager\" name=\"createNewQueue\"",
- "ACL DENY admin CREATE QUEUE");
+ writeACLFile(null,
+ "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager'");
}
-
- public void testCreateQueueJMXRights() throws Exception
+
+ public void testUpdateComponentOnlyAllow() throws Exception
+ {
+ _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true);
+ // PASS
+ _jmx.deleteQueue(TEST_VHOST, getTestQueueName());
+ // PASS
+ }
+
+
+ /**
+ * admin user is allowed all update methods on all components at broker level.
+ */
+ public void setUpUpdateMethodOnlyAllow() throws Exception
+ {
+ writeACLFile(null,
+ "ACL ALLOW admin UPDATE METHOD");
+ }
+
+ public void testUpdateMethodOnlyAllow() throws Exception
+ {
+ _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true);
+ //PASS
+ _jmx.deleteQueue(TEST_VHOST, getTestQueueName());
+ // PASS
+ }
+
+
+ /**
+ * admin user has JMX right, AMPQ right is irrelevant.
+ */
+ public void setUpCreateQueueSuccess() throws Exception
+ {
+ writeACLFile(TEST_VHOST,
+ "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
+ }
+
+ public void testCreateQueueSuccess() throws Exception
+ {
+ _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true);
+ }
+
+
+ /**
+ * admin user has JMX right, verifies lack of AMPQ rights is irrelevant.
+ */
+ public void setUpCreateQueueSuccessNoAMQPRights() throws Exception
+ {
+ writeACLFile(TEST_VHOST,
+ "ACL ALLOW admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'",
+ "ACL DENY admin CREATE QUEUE");
+ }
+
+ public void testCreateQueueSuccessNoAMQPRights() throws Exception
+ {
+ _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true);
+ }
+
+
+ /**
+ * admin user does not have JMX right, AMPQ right is irrelevant.
+ */
+ public void setUpCreateQueueDenied() throws Exception
+ {
+ writeACLFile(TEST_VHOST,
+ "ACL DENY admin UPDATE METHOD component='VirtualHost.VirtualHostManager' name='createNewQueue'");
+ }
+
+ public void testCreateQueueDenied() throws Exception
{
try
{
- _jmx.createQueue("test", QUEUE_NAME, "admin", true);
-
- fail("Queue create should fail");
+ _jmx.createQueue(TEST_VHOST, getTestQueueName(), TEST_QUEUE_OWNER, true);
+ fail("Exception not thrown");
}
- catch (Exception e)
+ catch (SecurityException e)
{
- assertNotNull("Cause is not set", e.getCause());
- assertEquals("Cause message incorrect",
- "org.apache.qpid.AMQSecurityException: Permission denied: queue-name 'kipper' [error code 403: access refused]", e.getCause().getMessage());
+ assertEquals("Cause message incorrect", "Permission denied: Update createNewQueue", e.getMessage());
}
}
+
/**
- * admin user has AMQP right but not JMX
+ * admin user does not have JMX right
*/
- public void setUpCreateQueueAMQPRights() throws Exception
+ public void setUpServerInformationUpdateDenied() throws Exception
{
- writeACLFile("test",
- "ACL DENY admin EXECUTE METHOD component=\"VirtualHost.VirtualHostManager\" name=\"createNewQueue\"",
- "ACL ALLOW admin CREATE QUEUE");
+ writeACLFile(null,
+ "ACL DENY admin UPDATE METHOD component='ServerInformation' name='resetStatistics'");
}
-
- public void testCreateQueueAMQPRights() throws Exception
+
+ public void testServerInformationUpdateDenied() throws Exception
{
+ ServerInformation info = _jmx.getServerInformation();
try
{
- _jmx.createQueue("test", QUEUE_NAME, "admin", true);
-
- fail("Queue create should fail");
+ info.resetStatistics();
+ fail("Exception not thrown");
}
- catch (Exception e)
+ catch (SecurityException e)
{
- assertEquals("Cause message incorrect", "Permission denied: Execute createNewQueue", e.getMessage());
+ assertEquals("Cause message incorrect", "Permission denied: Update resetStatistics", e.getMessage());
}
}
+
/**
- * admin has both JMX and AMQP rights
+ * admin user has JMX right to check management API major version (but not minor version)
*/
- public void setUpCreateQueueJMXAMQPRights() throws Exception
+ public void setUpServerInformationAccessGranted() throws Exception
{
- writeACLFile("test",
- "ACL ALLOW admin EXECUTE METHOD component=\"VirtualHost.VirtualHostManager\" name=\"createNewQueue\"",
- "ACL ALLOW admin CREATE QUEUE");
+ writeACLFile(null,
+ "ACL ALLOW-LOG admin ACCESS METHOD component='ServerInformation' name='getManagementApiMajorVersion'");
}
-
- public void testCreateQueueJMXAMQPRights() throws Exception
+
+ public void testServerInformationAccessGranted() throws Exception
{
+ ServerInformation info = _jmx.getServerInformation();
+ info.getManagementApiMajorVersion();
+
try
{
- _jmx.createQueue("test", QUEUE_NAME, "admin", true);
+ info.getManagementApiMinorVersion();
+ fail("Exception not thrown");
}
- catch (Exception e)
+ catch (SecurityException e)
{
- fail("Queue create should succeed: " + e.getCause().getMessage());
+ assertEquals("Cause message incorrect", "Permission denied: Access getManagementApiMinorVersion", e.getMessage());
}
}
+
+
+ /**
+ * admin user has JMX right to use the update method
+ */
+ public void setUpServerInformationUpdateMethodPermission() throws Exception
+ {
+ writeACLFile(null,
+ "ACL ALLOW admin UPDATE METHOD component='ServerInformation' name='resetStatistics'");
+ }
+
+ public void testServerInformationUpdateMethodPermission() throws Exception
+ {
+ ServerInformation info = _jmx.getServerInformation();
+ info.resetStatistics();
+ // PASS
+ }
+
+
+ /**
+ * admin user has JMX right to use all types of method on ServerInformation
+ */
+ public void setUpServerInformationAllMethodPermissions() throws Exception
+ {
+ writeACLFile(null, "ACL ALLOW admin ALL METHOD component='ServerInformation'");
+ }
+
+ public void testServerInformationAllMethodPermissions() throws Exception
+ {
+ //try an update method
+ ServerInformation info = _jmx.getServerInformation();
+ info.resetStatistics();
+ // PASS
+ //try an access method
+ info.getManagementApiMinorVersion();
+ // PASS
+ }
+
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
index 254e1fe6ac..e9b8a2efd5 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalACLTest.java
@@ -18,13 +18,8 @@
*/
package org.apache.qpid.server.security.acl;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-
import javax.jms.Connection;
-import javax.jms.DeliveryMode;
-import javax.jms.IllegalStateException;
+import javax.jms.Destination;
import javax.jms.JMSException;
import javax.jms.Message;
import javax.jms.MessageConsumer;
@@ -37,9 +32,6 @@ import javax.jms.TopicSubscriber;
import javax.naming.NamingException;
import org.apache.qpid.AMQException;
-import org.apache.qpid.client.AMQConnection;
-import org.apache.qpid.client.AMQSession;
-import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.url.URLSyntaxException;
@@ -49,7 +41,13 @@ import org.apache.qpid.url.URLSyntaxException;
*/
public class ExternalACLTest extends AbstractACLTestCase
{
- public void testAccessAuthorizedSuccess() throws AMQException, URLSyntaxException, Exception
+
+ public void setUpAccessAuthorizedSuccess() throws Exception
+ {
+ writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST");
+ }
+
+ public void testAccessAuthorizedSuccess() throws Exception
{
try
{
@@ -68,43 +66,9 @@ public class ExternalACLTest extends AbstractACLTestCase
}
}
- public void testAccessVhostAuthorisedGuestSuccess() throws IOException, Exception
+ public void setUpAccessNoRightsFailure() throws Exception
{
- //The 'guest' user has no access to the 'test' vhost, as tested below in testAccessNoRights(), and so
- //is unable to perform actions such as connecting (and by extension, creating a queue, and consuming
- //from a queue etc). In order to test the vhost-wide 'access' ACL right, the 'guest' user has been given
- //this right in the 'test2' vhost.
-
- try
- {
- //get a connection to the 'test2' vhost using the guest user and perform various actions.
- Connection conn = getConnection("test2", "guest", "guest");
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
- conn.start();
-
- //create Queues and consumers for each
- Queue namedQueue = sess.createQueue("vhostAccessCreatedQueue" + getTestQueueName());
- Queue tempQueue = sess.createTemporaryQueue();
- MessageConsumer consumer = sess.createConsumer(namedQueue);
- MessageConsumer tempConsumer = sess.createConsumer(tempQueue);
-
- //send a message to each queue (also causing an exchange declare)
- MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null);
- ((org.apache.qpid.jms.MessageProducer) sender).send(namedQueue, sess.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false);
- ((org.apache.qpid.jms.MessageProducer) sender).send(tempQueue, sess.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false);
-
- //consume the messages from the queues
- consumer.receive(2000);
- tempConsumer.receive(2000);
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
+ writeACLFile("test", "ACL DENY-LOG client ACCESS VIRTUALHOST");
}
public void testAccessNoRightsFailure() throws Exception
@@ -131,228 +95,124 @@ public class ExternalACLTest extends AbstractACLTestCase
}
}
- public void testClientDeleteQueueSuccess() throws Exception
+ public void setUpClientDeleteQueueSuccess() throws Exception
{
- try
- {
- Connection conn = getConnection("test", "client", "guest");
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- conn.start();
-
- // create kipper
- Topic kipper = sess.createTopic("kipper");
- TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
-
- subscriber.close();
- sess.unsubscribe("kipper");
-
- //Do something to show connection is active.
- sess.rollback();
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
+ writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
+ "ACL ALLOW-LOG client CREATE QUEUE durable=\"true\"" ,
+ "ACL ALLOW-LOG client CONSUME QUEUE name=\"clientid:kipper\"",
+ "ACL ALLOW-LOG client BIND EXCHANGE name=\"amq.topic\" durable=true routingKey=kipper",
+ "ACL ALLOW-LOG client DELETE QUEUE durable=\"true\"",
+ "ACL ALLOW-LOG client UNBIND EXCHANGE name=\"amq.topic\" durable=true routingKey=kipper");
}
- public void testServerDeleteQueueFailure() throws Exception
+ public void testClientDeleteQueueSuccess() throws Exception
{
- try
- {
- Connection conn = getConnection("test", "server", "guest");
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- conn.start();
+ Connection conn = getConnection("test", "client", "guest");
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+ conn.start();
- // create kipper
- Topic kipper = sess.createTopic("kipper");
- TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
+ // create kipper
+ Topic kipper = sess.createTopic("kipper");
+ TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
- subscriber.close();
- sess.unsubscribe("kipper");
+ subscriber.close();
+ sess.unsubscribe("kipper");
- //Do something to show connection is active.
- sess.rollback();
- conn.close();
- }
- catch (JMSException e)
- {
- // JMSException -> linedException = AMQException.403
- check403Exception(e.getLinkedException());
- }
+ //Do something to show connection is active.
+ sess.rollback();
+ conn.close();
}
- public void testClientConsumeFromTempQueueSuccess() throws AMQException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createTemporaryQueue());
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
+ public void setUpClientDeleteQueueFailure() throws Exception
+ {
+ writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
+ "ACL ALLOW-LOG client CREATE QUEUE durable=\"true\"" ,
+ "ACL ALLOW-LOG client CONSUME QUEUE name=\"clientid:kipper\"",
+ "ACL ALLOW-LOG client BIND EXCHANGE name=\"amq.topic\" durable=true routingKey=kipper",
+ "ACL DENY-LOG client DELETE QUEUE durable=\"true\"",
+ "ACL DENY-LOG client UNBIND EXCHANGE name=\"amq.topic\" durable=true routingKey=kipper");
}
- public void testClientConsumeFromNamedQueueFailure() throws NamingException, Exception
+ public void testClientDeleteQueueFailure() throws Exception
{
- try
- {
- Connection conn = getConnection("test", "client", "guest");
+ Connection conn = getConnection("test", "client", "guest");
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+ conn.start();
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ // create kipper
+ Topic kipper = sess.createTopic("kipper");
+ TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
- conn.start();
+ subscriber.close();
+ try
+ {
+ sess.unsubscribe("kipper");
- sess.createConsumer(sess.createQueue("IllegalQueue"));
+ //Do something to show connection is active.
+ sess.rollback();
- fail("Test failed as consumer was created.");
+ fail("Exception was not thrown");
}
catch (JMSException e)
{
+ // JMSException -> linedException = AMQException.403
check403Exception(e.getLinkedException());
}
}
- public void testClientCreateTemporaryQueueSuccess() throws JMSException, URLSyntaxException, Exception
- {
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
- //Create Temporary Queue - can't use the createTempQueue as QueueName is null.
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("doesnt_matter_as_autodelete_means_tmp"),
- true, false, false);
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
- }
-
- public void testClientCreateNamedQueueFailure() throws NamingException, JMSException, AMQException, Exception
+ public void testClientConsumeFromTempQueueSuccess() throws Exception
{
- try
- {
- Connection conn = getConnection("test", "client", "guest");
+ Connection conn = getConnection("test", "client", "guest");
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
- conn.start();
+ conn.start();
- //Create a Named Queue
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false);
-
- fail("Test failed as Queue creation succeded.");
- //conn will be automatically closed
- }
- catch (AMQException e)
- {
- check403Exception(e);
- }
+ sess.createConsumer(sess.createTemporaryQueue());
}
- public void testClientPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, Exception
+ public void setUpClientConsumeFromNamedQueueValid() throws Exception
{
- try
- {
- Connection conn = getConnection("test", "client", "guest");
+ writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
+ "ACL ALLOW-LOG client CREATE QUEUE name=\"example.RequestQueue\"" ,
+ "ACL ALLOW-LOG client CONSUME QUEUE name=\"example.RequestQueue\"",
+ "ACL ALLOW-LOG client BIND EXCHANGE name=\"amq.direct\" routingKey=\"example.RequestQueue\"");
+ }
- Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- conn.start();
-
- MessageProducer sender = sess.createProducer(sess.createQueue("example.RequestQueue"));
+ public void testClientConsumeFromNamedQueueValid() throws Exception
+ {
+ Connection conn = getConnection("test", "client", "guest");
- sender.send(sess.createTextMessage("test"));
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
- //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker.
- sess.commit();
+ conn.start();
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test publish failed:" + e);
- }
+ sess.createConsumer(sess.createQueue("example.RequestQueue"));
}
- public void testClientPublishValidQueueSuccess() throws AMQException, URLSyntaxException, Exception
+ public void setUpClientConsumeFromNamedQueueFailure() throws Exception
{
- try
- {
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- MessageProducer sender = ((AMQSession<?, ?>) sess).createProducer(null);
-
- Queue queue = sess.createQueue("example.RequestQueue");
-
- // Send a message that we will wait to be sent, this should give the broker time to process the msg
- // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
- // queue existence.
- ((org.apache.qpid.jms.MessageProducer) sender).send(queue, sess.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false);
-
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test publish failed:" + e);
- }
+ writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
+ "ACL ALLOW-LOG client CREATE QUEUE" ,
+ "ACL ALLOW-LOG client BIND EXCHANGE",
+ "ACL DENY-LOG client CONSUME QUEUE name=\"IllegalQueue\"");
}
- public void testClientPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
+ public void testClientConsumeFromNamedQueueFailure() throws NamingException, Exception
{
+ Connection conn = getConnection("test", "client", "guest");
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ conn.start();
+ Destination dest = sess.createQueue("IllegalQueue");
+
try
{
- Connection conn = getConnection("test", "client", "guest");
-
- Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null);
-
- Queue queue = session.createQueue("Invalid");
-
- // Send a message that we will wait to be sent, this should give the broker time to close the connection
- // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
- // queue existence.
- ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false);
-
- // Test the connection with a valid consumer
- // This may fail as the session may be closed before the queue or the consumer created.
- Queue temp = session.createTemporaryQueue();
+ sess.createConsumer(dest);
- session.createConsumer(temp).close();
-
- //Connection should now be closed and will throw the exception caused by the above send
- conn.close();
-
- fail("Close is not expected to succeed.");
- }
- catch (IllegalStateException e)
- {
- _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error.");
+ fail("Test failed as consumer was created.");
}
catch (JMSException e)
{
@@ -360,39 +220,43 @@ public class ExternalACLTest extends AbstractACLTestCase
}
}
- public void testServerConsumeFromNamedQueueValid() throws AMQException, URLSyntaxException, Exception
+ public void setUpClientCreateTemporaryQueueSuccess() throws Exception
{
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
+ "ACL ALLOW-LOG client CREATE QUEUE temporary=\"true\"" ,
+ "ACL ALLOW-LOG client BIND EXCHANGE name=\"amq.direct\" temporary=true",
+ "ACL ALLOW-LOG client DELETE QUEUE temporary=\"true\"",
+ "ACL ALLOW-LOG client UNBIND EXCHANGE name=\"amq.direct\" temporary=true");
+ }
- conn.start();
+ public void testClientCreateTemporaryQueueSuccess() throws JMSException, URLSyntaxException, Exception
+ {
+ Connection conn = getConnection("test", "client", "guest");
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ conn.start();
- sess.createConsumer(sess.createQueue("example.RequestQueue"));
+ sess.createTemporaryQueue();
+ conn.close();
+ }
- conn.close();
- }
- catch (Exception e)
- {
- fail("Test failed due to:" + e.getMessage());
- }
+ public void setUpClientCreateTemporaryQueueFailed() throws Exception
+ {
+ writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
+ "ACL DENY-LOG client CREATE QUEUE temporary=\"true\"");
}
- public void testServerConsumeFromNamedQueueInvalid() throws AMQException, URLSyntaxException, NamingException, Exception
+ public void testClientCreateTemporaryQueueFailed() throws NamingException, Exception
{
+ Connection conn = getConnection("test", "client", "guest");
+ Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ conn.start();
+
try
{
- Connection conn = getConnection("test", "client", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
- conn.start();
-
- sess.createConsumer(sess.createQueue("Invalid"));
+ session.createTemporaryQueue();
- fail("Test failed as consumer was created.");
+ fail("Test failed as creation succeded.");
}
catch (JMSException e)
{
@@ -400,247 +264,139 @@ public class ExternalACLTest extends AbstractACLTestCase
}
}
- public void testServerConsumeFromTemporaryQueue() throws AMQException, URLSyntaxException, NamingException, Exception
+ public void setUpClientCreateNamedQueueFailure() throws Exception
{
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- sess.createConsumer(sess.createTemporaryQueue());
-
- fail("Test failed as consumer was created.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
+ writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
+ "ACL ALLOW-LOG client CREATE QUEUE name=\"ValidQueue\"",
+ "ACL ALLOW-LOG client CONSUME QUEUE");
}
- public void testServerCreateNamedQueueValid() throws JMSException, URLSyntaxException, Exception
+ public void testClientCreateNamedQueueFailure() throws NamingException, JMSException, AMQException, Exception
{
+ Connection conn = getConnection("test", "client", "guest");
+ Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ conn.start();
+ Destination dest = sess.createQueue("IllegalQueue");
+
try
{
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- //Create Temporary Queue
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("example.RequestQueue"), false, false, false);
-
- conn.close();
+ //Create a Named Queue as side effect
+ sess.createConsumer(dest);
+ fail("Test failed as Queue creation succeded.");
}
- catch (Exception e)
+ catch (JMSException e)
{
- fail("Test failed due to:" + e.getMessage());
+ check403Exception(e.getLinkedException());
}
}
- public void testServerCreateNamedQueueInvalid() throws JMSException, URLSyntaxException, AMQException, NamingException, Exception
+ public void setUpClientPublishUsingTransactionSuccess() throws Exception
{
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- Session sess = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- //Create a Named Queue
- ((AMQSession<?, ?>) sess).createQueue(new AMQShortString("IllegalQueue"), false, false, false);
-
- fail("Test failed as creation succeded.");
- }
- catch (Exception e)
- {
- check403Exception(e);
- }
+ writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
+ "ACL ALLOW-LOG client CREATE QUEUE" ,
+ "ACL ALLOW-LOG client BIND EXCHANGE",
+ "ACL ALLOW-LOG client PUBLISH EXCHANGE name=\"amq.direct\" routingKey=\"example.RequestQueue\"");
}
- public void testServerCreateTemporaryQueueInvalid() throws NamingException, Exception
+ public void testClientPublishUsingTransactionSuccess() throws Exception
{
- try
- {
- Connection conn = getConnection("test", "server", "guest");
- Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ Connection conn = getConnection("test", "client", "guest");
- conn.start();
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
- session.createTemporaryQueue();
+ conn.start();
- fail("Test failed as creation succeded.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
- }
+ MessageProducer sender = sess.createProducer(sess.createQueue("example.RequestQueue"));
- public void testServerCreateAutoDeleteQueueInvalid() throws NamingException, JMSException, AMQException, Exception
- {
- try
- {
- Connection connection = getConnection("test", "server", "guest");
+ sender.send(sess.createTextMessage("test"));
- Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+ //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker.
+ sess.commit();
- connection.start();
+ conn.close();
+ }
- ((AMQSession<?, ?>) session).createQueue(new AMQShortString("again_ensure_auto_delete_queue_for_temporary"),
- true, false, false);
- fail("Test failed as creation succeded.");
- }
- catch (Exception e)
- {
- check403Exception(e);
- }
+ public void setUpRequestResponseSuccess() throws Exception
+ {
+ writeACLFile("test", "GROUP messaging-users client server",
+ "ACL ALLOW-LOG messaging-users ACCESS VIRTUALHOST",
+ "# Server side",
+ "ACL ALLOW-LOG server CREATE QUEUE name=\"example.RequestQueue\"" ,
+ "ACL ALLOW-LOG server BIND EXCHANGE",
+ "ACL ALLOW-LOG server PUBLISH EXCHANGE name=\"amq.direct\" routingKey=\"TempQueue*\"",
+ "ACL ALLOW-LOG server CONSUME QUEUE name=\"example.RequestQueue\"",
+ "# Client side",
+ "ACL ALLOW-LOG client PUBLISH EXCHANGE name=\"amq.direct\" routingKey=\"example.RequestQueue\"",
+ "ACL ALLOW-LOG client CONSUME QUEUE temporary=true",
+ "ACL ALLOW-LOG client BIND EXCHANGE name=\"amq.direct\" temporary=true",
+ "ACL ALLOW-LOG client UNBIND EXCHANGE name=\"amq.direct\" temporary=true",
+ "ACL ALLOW-LOG client CREATE QUEUE temporary=true",
+ "ACL ALLOW-LOG client DELETE QUEUE temporary=true");
}
- /**
- * This test uses both the cilent and sender to validate that the Server is able to publish to a temporary queue.
- * The reason the client must be involved is that the Server is unable to create its own Temporary Queues.
- *
- * @throws AMQException
- * @throws URLSyntaxException
- * @throws JMSException
- */
- public void testServerPublishUsingTransactionSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
+
+ public void testRequestResponseSuccess() throws Exception
{
//Set up the Server
Connection serverConnection = getConnection("test", "server", "guest");
-
Session serverSession = serverConnection.createSession(true, Session.SESSION_TRANSACTED);
-
Queue requestQueue = serverSession.createQueue("example.RequestQueue");
-
MessageConsumer server = serverSession.createConsumer(requestQueue);
-
serverConnection.start();
//Set up the consumer
Connection clientConnection = getConnection("test", "client", "guest");
-
- //Send a test mesage
- Session clientSession = clientConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
+ Session clientSession = clientConnection.createSession(true, Session.SESSION_TRANSACTED);
Queue responseQueue = clientSession.createTemporaryQueue();
-
MessageConsumer clientResponse = clientSession.createConsumer(responseQueue);
-
clientConnection.start();
+ // Client
Message request = clientSession.createTextMessage("Request");
-
- assertNotNull("Response Queue is null", responseQueue);
-
request.setJMSReplyTo(responseQueue);
clientSession.createProducer(requestQueue).send(request);
-
- try
- {
- Message msg = null;
-
- msg = server.receive(2000);
-
- while (msg != null && !((TextMessage) msg).getText().equals("Request"))
- {
- msg = server.receive(2000);
- }
-
- assertNotNull("Message not received", msg);
-
- assertNotNull("Reply-To is Null", msg.getJMSReplyTo());
-
- MessageProducer sender = serverSession.createProducer(msg.getJMSReplyTo());
-
- sender.send(serverSession.createTextMessage("Response"));
-
- //Send the message using a transaction as this will allow us to retrieve any errors that occur on the broker.
- serverSession.commit();
-
- //Ensure Response is received.
- Message clientResponseMsg = clientResponse.receive(2000);
- assertNotNull("Client did not receive response message,", clientResponseMsg);
- assertEquals("Incorrect message received", "Response", ((TextMessage) clientResponseMsg).getText());
-
- }
- catch (Exception e)
- {
- fail("Test publish failed:" + e);
- }
- finally
- {
- try
- {
- serverConnection.close();
- }
- finally
- {
- clientConnection.close();
- }
- }
+ clientSession.commit();
+
+ // Server
+ Message msg = server.receive(2000);
+ assertNotNull("Server should have received client's request", msg);
+ assertNotNull("Received msg should have Reply-To", msg.getJMSReplyTo());
+
+ MessageProducer sender = serverSession.createProducer(msg.getJMSReplyTo());
+ sender.send(serverSession.createTextMessage("Response"));
+ serverSession.commit();
+
+ // Client
+ Message clientResponseMsg = clientResponse.receive(2000);
+ clientSession.commit();
+ assertNotNull("Client did not receive response message,", clientResponseMsg);
+ assertEquals("Incorrect message received", "Response", ((TextMessage) clientResponseMsg).getText());
}
- public void testServerPublishInvalidQueueSuccess() throws AMQException, URLSyntaxException, JMSException, NamingException, Exception
+ public void setUpClientDeleteQueueSuccessWithOnlyAllPermissions() throws Exception
{
- try
- {
- Connection conn = getConnection("test", "server", "guest");
-
- ((AMQConnection) conn).setConnectionListener(this);
-
- Session session = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
-
- conn.start();
-
- MessageProducer sender = ((AMQSession<?, ?>) session).createProducer(null);
-
- Queue queue = session.createQueue("Invalid");
-
- // Send a message that we will wait to be sent, this should give the broker time to close the connection
- // before we finish this test. Message is set !immed !mand as the queue is invalid so want to test ACLs not
- // queue existence.
- ((org.apache.qpid.jms.MessageProducer) sender).send(queue, session.createTextMessage("test"),
- DeliveryMode.NON_PERSISTENT, 0, 0L, false, false);
-
- // Test the connection with a valid consumer
- // This may not work as the session may be closed before the queue or consumer creation can occur.
- // The correct JMSexception with linked error will only occur when the close method is recevied whilst in
- // the failover safe block
- session.createConsumer(session.createQueue("example.RequestQueue")).close();
-
- //Connection should now be closed and will throw the exception caused by the above send
- conn.close();
-
- fail("Close is not expected to succeed.");
- }
- catch (IllegalStateException e)
- {
- _logger.info("QPID-2345: Session became closed and we got that error rather than the authentication error.");
- }
- catch (JMSException e)
- {
- check403Exception(e.getLinkedException());
- }
+ writeACLFile("test", "ACL ALLOW-LOG client ACCESS VIRTUALHOST",
+ "ACL ALLOW-LOG client ALL QUEUE",
+ "ACL ALLOW-LOG client ALL EXCHANGE");
}
-
- @Override
- public String getConfig()
+ public void testClientDeleteQueueSuccessWithOnlyAllPermissions() throws Exception
{
- return "config-systests-aclv2.xml";
- }
+ Connection conn = getConnection("test", "client", "guest");
+ Session sess = conn.createSession(true, Session.SESSION_TRANSACTED);
+ conn.start();
- @Override
- public List<String> getHostList()
- {
- return Arrays.asList("test", "test2");
+ // create kipper
+ Topic kipper = sess.createTopic("kipper");
+ TopicSubscriber subscriber = sess.createDurableSubscriber(kipper, "kipper");
+
+ subscriber.close();
+ sess.unsubscribe("kipper");
+
+ //Do something to show connection is active.
+ sess.rollback();
+ conn.close();
}
}
diff --git a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalAdminACLTest.java b/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalAdminACLTest.java
deleted file mode 100644
index b0bc4fd946..0000000000
--- a/java/systests/src/main/java/org/apache/qpid/server/security/acl/ExternalAdminACLTest.java
+++ /dev/null
@@ -1,186 +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.acl;
-
-import java.io.BufferedWriter;
-import java.io.File;
-import java.io.FileWriter;
-import java.io.IOException;
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.qpid.server.logging.management.LoggingManagementMBean;
-import org.apache.qpid.test.utils.JMXTestUtils;
-
-/**
- * Tests that ACLs can be applied to mangement operations that do not correspond to a specific AMQP object.
- *
- * Theses tests use the logging component, exposed as the {@link LoggingManagementMBean}, to get and set properties.
- */
-public class ExternalAdminACLTest extends AbstractACLTestCase
-{
- private static final String CATEGORY_PRIORITY = "LogManMBeanTest.category.priority";
- private static final String CATEGORY_LEVEL = "LogManMBeanTest.category.level";
- private static final String LOGGER_LEVEL = "LogManMBeanTest.logger.level";
-
- private static final String NEWLINE = System.getProperty("line.separator");
-
- private JMXTestUtils _jmx;
- private File _testConfigFile;
-
- @Override
- public String getConfig()
- {
- return "config-systests-aclv2.xml";
- }
-
- @Override
- public List<String> getHostList()
- {
- return Arrays.asList("global");
- }
-
- @Override
- public void setUp() throws Exception
- {
- _testConfigFile = createTempTestLog4JConfig();
-
- _jmx = new JMXTestUtils(this);
- _jmx.setUp();
- super.setUp();
- _jmx.open();
- }
-
- @Override
- public void tearDown() throws Exception
- {
- _jmx.close();
- super.tearDown();
- }
-
- private File createTempTestLog4JConfig()
- {
- File tmpFile = null;
- try
- {
- tmpFile = File.createTempFile("LogManMBeanTestLog4jConfig", ".tmp");
- tmpFile.deleteOnExit();
-
- FileWriter fstream = new FileWriter(tmpFile);
- BufferedWriter writer = new BufferedWriter(fstream);
-
- writer.write("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"+NEWLINE);
- writer.write("<!DOCTYPE log4j:configuration SYSTEM \"log4j.dtd\">"+NEWLINE);
-
- writer.write("<log4j:configuration xmlns:log4j=\"http://jakarta.apache.org/log4j/\" debug=\"null\" " +
- "threshold=\"null\">"+NEWLINE);
-
- writer.write(" <appender class=\"org.apache.log4j.ConsoleAppender\" name=\"STDOUT\">"+NEWLINE);
- writer.write(" <layout class=\"org.apache.log4j.PatternLayout\">"+NEWLINE);
- writer.write(" <param name=\"ConversionPattern\" value=\"%d %-5p [%t] %C{2} (%F:%L) - %m%n\"/>"+NEWLINE);
- writer.write(" </layout>"+NEWLINE);
- writer.write(" </appender>"+NEWLINE);
-
- //Example of a 'category' with a 'priority'
- writer.write(" <category additivity=\"true\" name=\"" + CATEGORY_PRIORITY +"\">"+NEWLINE);
- writer.write(" <priority value=\"info\"/>"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </category>"+NEWLINE);
-
- //Example of a 'category' with a 'level'
- writer.write(" <category additivity=\"true\" name=\"" + CATEGORY_LEVEL +"\">"+NEWLINE);
- writer.write(" <level value=\"warn\"/>"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </category>"+NEWLINE);
-
- //Example of a 'logger' with a 'level'
- writer.write(" <logger additivity=\"true\" name=\"" + LOGGER_LEVEL + "\">"+NEWLINE);
- writer.write(" <level value=\"error\"/>"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </logger>"+NEWLINE);
-
- //'root' logger
- writer.write(" <root>"+NEWLINE);
- writer.write(" <priority value=\"info\"/>"+NEWLINE);
- writer.write(" <appender-ref ref=\"STDOUT\"/>"+NEWLINE);
- writer.write(" </root>"+NEWLINE);
-
- writer.write("</log4j:configuration>"+NEWLINE);
-
- writer.flush();
- writer.close();
- }
- catch (IOException e)
- {
- fail("Unable to create temporary test log4j configuration");
- }
-
- return tmpFile;
- }
-
- public void testGetAllLoggerLevels() throws Exception
- {
- String[] levels = _jmx.getAvailableLoggerLevels();
- for (int i = 0; i < levels.length; i++)
- {
- System.out.println(levels[i]);
- }
- assertEquals("Got incorrect number of log levels", 9, levels.length);
- }
-
- public void testGetAllLoggerLevelsDenied() throws Exception
- {
- try
- {
- _jmx.getAvailableLoggerLevels();
- fail("Got list of log levels");
- }
- catch (Exception e)
- {
- // Exception throws
- e.printStackTrace();
- assertEquals("Permission denied: Access getAvailableLoggerLevels", e.getMessage());
- }
- }
-
- public void testChangeLoggerLevel() throws Exception
- {
- String oldLevel = _jmx.getRuntimeRootLoggerLevel();
- System.out.println("old level = " + oldLevel);
- _jmx.setRuntimeRootLoggerLevel("DEBUG");
- String newLevel = _jmx.getRuntimeRootLoggerLevel();
- System.out.println("new level = " + newLevel);
- assertEquals("Logging level was not changed", "DEBUG", newLevel);
- }
-
- public void testChangeLoggerLevelDenied() throws Exception
- {
- try
- {
- _jmx.setRuntimeRootLoggerLevel("DEBUG");
- fail("Logging level was changed");
- }
- catch (Exception e)
- {
- assertEquals("Permission denied: Update setRuntimeRootLoggerLevel", e.getMessage());
- }
- }
-}
diff --git a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java b/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
index 71fbf4cc81..14b9bacad4 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/utils/QpidBrokerTestCase.java
@@ -823,7 +823,7 @@ public class QpidBrokerTestCase extends QpidTestCase
* @throws ConfigurationException when loading the current config file
* @throws IOException when writing the new config file
*/
- protected void setConfigurationProperty(String property, String value)
+ public void setConfigurationProperty(String property, String value)
throws ConfigurationException, IOException
{
// Choose which file to write the property to based on prefix.