summaryrefslogtreecommitdiff
path: root/java/broker/src/main/java
diff options
context:
space:
mode:
Diffstat (limited to 'java/broker/src/main/java')
-rw-r--r--java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java9
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java52
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java10
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/Main.java19
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/binding/BindingFactory.java79
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/configuration/ServerConfiguration.java51
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java15
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java22
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java17
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java18
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java13
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java8
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java28
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java19
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java24
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java7
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeleteHandler.java9
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java10
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java22
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java7
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java33
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java288
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java70
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java3
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java21
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java120
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java69
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java139
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/Result.java46
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java384
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/SecurityPlugin.java47
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java54
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/access/AuthorizationManager.java)17
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java323
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java70
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java33
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java65
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/AccessRights.java63
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java315
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java90
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/Operation.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java)36
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/Permission.java35
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/VirtualHostAccess.java68
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AbstractACLPlugin.java99
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java68
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicACLPlugin.java110
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java51
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.java85
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java81
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccessPlugin.java71
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java16
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java)67
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java7
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactoryImpl.java18
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java35
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java1
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java326
-rwxr-xr-xjava/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java130
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java4
73 files changed, 2240 insertions, 1826 deletions
diff --git a/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java b/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
index 8bb1a6b9fa..7e999a720b 100644
--- a/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
+++ b/java/broker/src/main/java/org/apache/qpid/qmf/QMFService.java
@@ -1063,7 +1063,14 @@ public class QMFService implements ConfigStore.ConfigEventListener, Closeable
public BrokerSchema.QueueClass.PurgeMethodResponseCommand purge(final BrokerSchema.QueueClass.PurgeMethodResponseCommandFactory factory,
final Long request)
{
- _obj.purge(request);
+ try
+ {
+ _obj.purge(request);
+ } catch (AMQException e)
+ {
+ // TODO
+ throw new RuntimeException();
+ }
return factory.createResponseCommand();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java b/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
index b2e43b4f0d..811e45f4ae 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/AMQBrokerManagerMBean.java
@@ -1,5 +1,4 @@
/*
- *
* 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
@@ -16,24 +15,6 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- *
- */
-/*
- *
- * Copyright (c) 2006 The Apache Software Foundation
- *
- * Licensed 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;
@@ -189,8 +170,9 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
* @param type
* @param durable
* @throws JMException
+ * @throws MBeanException
*/
- public void createNewExchange(String exchangeName, String type, boolean durable) throws JMException
+ public void createNewExchange(String exchangeName, String type, boolean durable) throws JMException, MBeanException
{
CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger()));
try
@@ -216,7 +198,8 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
}
catch (AMQException ex)
{
- throw new MBeanException(ex, "Error in creating exchange " + exchangeName);
+ JMException jme = new JMException(ex.toString());
+ throw new MBeanException(jme, "Error in creating exchange " + exchangeName);
}
finally
{
@@ -229,8 +212,9 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
*
* @param exchangeName
* @throws JMException
+ * @throws MBeanException
*/
- public void unregisterExchange(String exchangeName) throws JMException
+ public void unregisterExchange(String exchangeName) throws JMException, MBeanException
{
// TODO
// Check if the exchange is in use.
@@ -244,7 +228,8 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
}
catch (AMQException ex)
{
- throw new MBeanException(ex, "Error in unregistering exchange " + exchangeName);
+ JMException jme = new JMException(ex.toString());
+ throw new MBeanException(jme, "Error in unregistering exchange " + exchangeName);
}
finally
{
@@ -260,8 +245,9 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
* @param durable
* @param owner
* @throws JMException
+ * @throws MBeanException
*/
- public void createNewQueue(String queueName, String owner, boolean durable) throws JMException
+ public void createNewQueue(String queueName, String owner, boolean durable) throws JMException, MBeanException
{
AMQQueue queue = _queueRegistry.getQueue(new AMQShortString(queueName));
if (queue != null)
@@ -278,8 +264,7 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
ownerShortString = new AMQShortString(owner);
}
- queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString(queueName), durable, ownerShortString, false, false,
- getVirtualHost(), null);
+ queue = AMQQueueFactory.createAMQQueueImpl(new AMQShortString(queueName), durable, ownerShortString, false, false, getVirtualHost(), null);
if (queue.isDurable() && !queue.isAutoDelete())
{
_durableConfig.createQueue(queue);
@@ -289,8 +274,7 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
}
catch (AMQException ex)
{
- JMException jme = new JMException(ex.getMessage());
- jme.initCause(ex);
+ JMException jme = new JMException(ex.toString());
throw new MBeanException(jme, "Error in creating queue " + queueName);
}
finally
@@ -309,13 +293,14 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
*
* @param queueName
* @throws JMException
+ * @throws MBeanException
*/
- public void deleteQueue(String queueName) throws JMException
+ public void deleteQueue(String queueName) throws JMException, MBeanException
{
AMQQueue queue = _queueRegistry.getQueue(new AMQShortString(queueName));
if (queue == null)
{
- throw new JMException("The Queue " + queueName + " is not a registerd queue.");
+ throw new JMException("The Queue " + queueName + " is not a registered queue.");
}
CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger()));
@@ -329,8 +314,7 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
}
catch (AMQException ex)
{
- JMException jme = new JMException(ex.getMessage());
- jme.initCause(ex);
+ JMException jme = new JMException(ex.toString());
throw new MBeanException(jme, "Error in deleting queue " + queueName);
}
finally
@@ -339,14 +323,16 @@ public class AMQBrokerManagerMBean extends AMQManagedObject implements ManagedBr
}
}
+ @Override
public ManagedObject getParentObject()
{
return _virtualHostMBean;
}
// This will have a single instance for a virtual host, so not having the name property in the ObjectName
+ @Override
public ObjectName getObjectName() throws MalformedObjectNameException
{
return getObjectNameForSingleInstanceMBean();
}
-} // End of MBean class
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
index 7d0163510a..8a0e49f537 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/AMQChannel.java
@@ -23,6 +23,7 @@ package org.apache.qpid.server;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQMethodBody;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.BasicContentHeaderProperties;
@@ -244,9 +245,12 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
return _channelId;
}
- public void setPublishFrame(MessagePublishInfo info, final Exchange e) throws AMQException
+ public void setPublishFrame(MessagePublishInfo info, final Exchange e) throws AMQSecurityException
{
-
+ if (!getVirtualHost().getSecurityManager().authorisePublish(info.isImmediate(), info.getRoutingKey().asString(), e.getName()))
+ {
+ throw new AMQSecurityException("Permission denied: " + e.getName());
+ }
_currentMessage = new IncomingMessage(info);
_currentMessage.setExchange(e);
}
@@ -421,7 +425,7 @@ public class AMQChannel implements SessionConfig, AMQSessionModel
{
throw new AMQException("Consumer already exists with same tag: " + tag);
}
-
+
Subscription subscription =
SubscriptionFactoryImpl.INSTANCE.createSubscription(_channelId, _session, tag, acks, filters, noLocal, _creditManager);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/Main.java b/java/broker/src/main/java/org/apache/qpid/server/Main.java
index 90afd2e4ac..d52267ad57 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/Main.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/Main.java
@@ -25,12 +25,12 @@ import java.io.IOException;
import java.io.InputStream;
import java.net.InetAddress;
import java.net.InetSocketAddress;
-import java.util.Properties;
-import java.util.Set;
+import java.util.Arrays;
+import java.util.EnumSet;
import java.util.HashSet;
import java.util.List;
-import java.util.Collection;
-import java.util.Arrays;
+import java.util.Properties;
+import java.util.Set;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.HelpFormatter;
@@ -42,8 +42,6 @@ import org.apache.commons.cli.PosixParser;
import org.apache.log4j.Logger;
import org.apache.log4j.PropertyConfigurator;
import org.apache.log4j.xml.QpidLog4JConfigurator;
-import org.apache.qpid.transport.network.ConnectionBinding;
-import org.apache.qpid.transport.*;
import org.apache.qpid.common.QpidProperties;
import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.server.configuration.ServerConfiguration;
@@ -56,21 +54,18 @@ import org.apache.qpid.server.logging.management.LoggingManagementMBean;
import org.apache.qpid.server.logging.messages.BrokerMessages;
import org.apache.qpid.server.protocol.AMQProtocolEngineFactory;
import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory;
+import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory.VERSION;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.ConfigurationFileApplicationRegistry;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.transport.ServerConnection;
import org.apache.qpid.server.transport.QpidAcceptor;
import org.apache.qpid.ssl.SSLContextFactory;
import org.apache.qpid.transport.NetworkDriver;
import org.apache.qpid.transport.network.mina.MINANetworkDriver;
-import org.apache.qpid.server.protocol.MultiVersionProtocolEngineFactory.VERSION;
/**
* Main entry point for AMQPD.
*
*/
-@SuppressWarnings({"AccessStaticViaInstance"})
public class Main
{
private static Logger _logger;
@@ -83,7 +78,6 @@ public class Main
private static final int IPV4_ADDRESS_LENGTH = 4;
private static final char IPV4_LITERAL_SEPARATOR = '.';
- private static final Collection<VERSION> ALL_VERSIONS = Arrays.asList(VERSION.values());
protected static class InitException extends Exception
{
@@ -123,6 +117,7 @@ public class Main
}
}
+ @SuppressWarnings("static-access")
protected void setOptions(Options options)
{
Option help = new Option("h", "help", false, "print this message");
@@ -403,7 +398,7 @@ public class Main
NetworkDriver driver = new MINANetworkDriver();
- Set<VERSION> supported = new HashSet<VERSION>(ALL_VERSIONS);
+ Set<VERSION> supported = EnumSet.allOf(VERSION.class);
if(exclude_0_10.contains(port))
{
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 5423f02107..59626a7b13 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
@@ -20,7 +20,12 @@
*/
package org.apache.qpid.server.binding;
+import java.util.Collections;
+import java.util.Map;
+import java.util.concurrent.ConcurrentHashMap;
+
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.configuration.BindingConfig;
@@ -35,13 +40,8 @@ import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import java.util.Collections;
-import java.util.Map;
-import java.util.concurrent.ConcurrentHashMap;
-
public class BindingFactory
{
-
private final VirtualHost _virtualHost;
private final DurableConfigurationStore.Source _configSource;
private final Exchange _defaultExchange;
@@ -51,14 +51,14 @@ public class BindingFactory
public BindingFactory(final VirtualHost vhost)
{
- this(vhost,vhost.getExchangeRegistry().getDefaultExchange());
+ this(vhost, vhost.getExchangeRegistry().getDefaultExchange());
}
public BindingFactory(final DurableConfigurationStore.Source configSource, final Exchange defaultExchange)
{
_configSource = configSource;
_defaultExchange = defaultExchange;
- if(configSource instanceof VirtualHost)
+ if (configSource instanceof VirtualHost)
{
_virtualHost = (VirtualHost) configSource;
}
@@ -83,7 +83,7 @@ public class BindingFactory
private BindingImpl(String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> arguments)
{
- super(queue.getVirtualHost().getConfigStore().createId(),bindingKey, queue, exchange, arguments);
+ super(queue.getVirtualHost().getConfigStore().createId(), bindingKey, queue, exchange, arguments);
_logSubject = new BindingLogSubject(bindingKey,exchange,queue);
}
@@ -94,7 +94,7 @@ public class BindingFactory
removeBinding(this);
}
- public void onClose(final Exchange exchange)
+ public void onClose(final Exchange exchange) throws AMQSecurityException
{
removeBinding(this);
}
@@ -138,7 +138,7 @@ public class BindingFactory
- public boolean addBinding(String bindingKey, AMQQueue queue, Exchange exchange, Map<String, Object> arguments)
+ public boolean addBinding(String bindingKey, AMQQueue queue, Exchange exchange, Map<String, Object> arguments) throws AMQSecurityException
{
return makeBinding(bindingKey, queue, exchange, arguments, false, false);
}
@@ -147,37 +147,43 @@ public class BindingFactory
public boolean replaceBinding(final String bindingKey,
final AMQQueue queue,
final Exchange exchange,
- final Map<String, Object> arguments)
+ final Map<String, Object> arguments) throws AMQSecurityException
{
return makeBinding(bindingKey, queue, exchange, arguments, false, true);
}
- private boolean makeBinding(String bindingKey, AMQQueue queue, Exchange exchange, Map<String, Object> arguments, boolean restore, boolean force)
+ private boolean makeBinding(String bindingKey, AMQQueue queue, Exchange exchange, Map<String, Object> arguments, boolean restore, boolean force) throws AMQSecurityException
{
assert queue != null;
- if(bindingKey == null)
+ if (bindingKey == null)
{
bindingKey = "";
}
- if(exchange == null)
+ if (exchange == null)
{
exchange = _defaultExchange;
}
- if(arguments == null)
+ if (arguments == null)
{
- arguments = Collections.EMPTY_MAP;
+ arguments = Collections.emptyMap();
}
-
+
+ //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);
BindingImpl existingMapping = _bindings.putIfAbsent(b,b);
- if(existingMapping == null || force)
+ if (existingMapping == null || force)
{
- if(existingMapping != null)
+ if (existingMapping != null)
{
removeBinding(existingMapping);
}
- if(b.isDurable() && !restore)
+ if (b.isDurable() && !restore)
{
try
{
@@ -185,7 +191,7 @@ public class BindingFactory
}
catch (AMQException e)
{
- throw new RuntimeException(e);
+ throw new RuntimeException(e); // FIXME
}
}
@@ -201,8 +207,6 @@ public class BindingFactory
{
return false;
}
-
-
}
private ConfigStore getConfigStore()
@@ -210,43 +214,49 @@ public class BindingFactory
return getVirtualHost().getConfigStore();
}
- public void restoreBinding(final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> argumentMap)
+ public void restoreBinding(final String bindingKey, final AMQQueue queue, final Exchange exchange, final Map<String, Object> argumentMap) throws AMQSecurityException
{
makeBinding(bindingKey,queue,exchange,argumentMap,true, false);
}
- public void removeBinding(final Binding b)
+ public void removeBinding(final Binding b) throws AMQSecurityException
{
removeBinding(b.getBindingKey(), b.getQueue(), b.getExchange(), b.getArguments());
}
- public Binding removeBinding(String bindingKey, AMQQueue queue, Exchange exchange, Map<String, Object> arguments)
+ public Binding removeBinding(String bindingKey, AMQQueue queue, Exchange exchange, Map<String, Object> arguments) throws AMQSecurityException
{
assert queue != null;
- if(bindingKey == null)
+ if (bindingKey == null)
{
bindingKey = "";
}
- if(exchange == null)
+ if (exchange == null)
{
exchange = _defaultExchange;
}
- if(arguments == null)
+ if (arguments == null)
{
- arguments = Collections.EMPTY_MAP;
+ arguments = Collections.emptyMap();
}
+ // Check access
+ if (!getVirtualHost().getSecurityManager().authoriseUnbind(exchange, new AMQShortString(bindingKey), queue))
+ {
+ throw new AMQSecurityException("Permission denied: binding " + bindingKey);
+ }
+
BindingImpl b = _bindings.remove(new BindingImpl(bindingKey,queue,exchange,arguments));
- if(b != null)
+ if (b != null)
{
exchange.removeBinding(b);
queue.removeBinding(b);
exchange.removeCloseTask(b);
queue.removeQueueDeleteTask(b);
- if(b.isDurable())
+ if (b.isDurable())
{
try
{
@@ -257,12 +267,11 @@ public class BindingFactory
}
catch (AMQException e)
{
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
+ throw new RuntimeException(e); // FIXME
}
}
b.logDestruction();
getConfigStore().removeConfiguredObject(b);
-
}
return b;
@@ -281,7 +290,7 @@ public class BindingFactory
}
if(arguments == null)
{
- arguments = Collections.EMPTY_MAP;
+ arguments = Collections.emptyMap();
}
BindingImpl b = new BindingImpl(bindingKey,queue,exchange,arguments);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
index 7fef4558c8..f62022922a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/configuration/QueueConfiguration.java
@@ -25,6 +25,7 @@ import java.util.List;
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.exchange.ExchangeDefaults;
import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
public class QueueConfiguration extends ConfigurationPlugin
@@ -109,7 +110,7 @@ public class QueueConfiguration extends ConfigurationPlugin
public String getExchange()
{
- return getStringValue("exchange", null);
+ return getStringValue("exchange", ExchangeDefaults.DEFAULT_EXCHANGE_NAME.asString());
}
public List getRoutingKeys()
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 9f1a4c52f2..f8fc27e86a 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
@@ -20,6 +20,15 @@
package org.apache.qpid.server.configuration;
+import java.io.File;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Locale;
+import java.util.Map;
+import java.util.Map.Entry;
+
import org.apache.commons.configuration.CompositeConfiguration;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
@@ -27,26 +36,17 @@ import org.apache.commons.configuration.ConfigurationFactory;
import org.apache.commons.configuration.HierarchicalConfiguration;
import org.apache.commons.configuration.SystemConfiguration;
import org.apache.commons.configuration.XMLConfiguration;
+import org.apache.log4j.Logger;
import org.apache.qpid.server.configuration.management.ConfigurationManagementMBean;
import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
-import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.transport.NetworkDriverConfiguration;
import sun.misc.Signal;
import sun.misc.SignalHandler;
-import java.io.File;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Locale;
-import java.util.Map;
-import java.util.Map.Entry;
-
public class ServerConfiguration extends ConfigurationPlugin implements SignalHandler
{
protected static final Logger _logger = Logger.getLogger(ServerConfiguration.class);
@@ -63,17 +63,22 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
public static final int DEFAULT_SSL_PORT = 8672;
public static final long DEFAULT_HOUSEKEEPING_PERIOD = 30000L;
public static final int DEFAULT_JMXPORT = 8999;
+
+ public static final String QPID_HOME = "QPID_HOME";
+ public static final String QPID_WORK = "QPID_WORK";
+ public static final String LIB_DIR = "lib";
+ public static final String PLUGIN_DIR = "plugins";
+ public static final String CACHE_DIR = "cache";
private Map<String, VirtualHostConfiguration> _virtualHosts = new HashMap<String, VirtualHostConfiguration>();
private File _configFile;
private File _vhostsFile;
- private Logger _log = LoggerFactory.getLogger(this.getClass());
+ private Logger _log = Logger.getLogger(this.getClass());
private ConfigurationManagementMBean _mbean;
-
// Map of environment variables to config items
private static final Map<String, String> envVarMap = new HashMap<String, String>();
@@ -142,6 +147,7 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
}
catch (IllegalArgumentException e)
{
+ _logger.error("Signal HUP not supported for OS: " + System.getProperty("os.name"));
// We're on something that doesn't handle SIGHUP, how sad, Windows.
}
}
@@ -192,7 +198,7 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
public String[] getElementsProcessed()
{
- return new String[]{""};
+ return new String[] { "" };
}
@Override
@@ -308,7 +314,6 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
*/
public Locale getLocale()
{
-
String localeString = getStringValue(ADVANCED_LOCALE);
// Expecting locale of format langauge_country_variant
@@ -432,10 +437,15 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
_logger.warn(SECURITY_CONFIG_RELOADED);
}
}
-
+
public String getQpidWork()
{
- return System.getProperty("QPID_WORK", System.getProperty("java.io.tmpdir"));
+ return System.getProperty(QPID_WORK, System.getProperty("java.io.tmpdir"));
+ }
+
+ public String getQpidHome()
+ {
+ return System.getProperty(QPID_HOME);
}
public void setJMXManagementPort(int mport)
@@ -467,11 +477,16 @@ public class ServerConfiguration extends ConfigurationPlugin implements SignalHa
{
return _virtualHosts.keySet().toArray(new String[_virtualHosts.size()]);
}
-
+
public String getPluginDirectory()
{
return getStringValue("plugin-directory");
}
+
+ public String getCacheDirectory()
+ {
+ return getStringValue("cache-directory");
+ }
public VirtualHostConfiguration getVirtualHostConfig(String name)
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
index ece8bc90fe..0dca91b7be 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/AbstractExchangeMBean.java
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.server.exchange;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.server.management.AMQManagedObject;
import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.management.ManagedObjectRegistry;
@@ -32,6 +34,7 @@ import org.apache.qpid.management.common.mbeans.ManagedExchange;
import org.apache.qpid.framing.AMQShortString;
import javax.management.openmbean.*;
+import javax.management.MBeanException;
import javax.management.NotCompliantMBeanException;
import javax.management.ObjectName;
import javax.management.MalformedObjectNameException;
@@ -133,7 +136,15 @@ public abstract class AbstractExchangeMBean<T extends AbstractExchange> extends
}
CurrentActor.set(new ManagementActor(_logActor.getRootMessageLogger()));
- vhost.getBindingFactory().addBinding(binding,queue,getExchange(),null);
+ try
+ {
+ vhost.getBindingFactory().addBinding(binding,queue,getExchange(),null);
+ }
+ catch (AMQException ex)
+ {
+ JMException jme = new JMException(ex.toString());
+ throw new MBeanException(jme, "Error creating new binding " + binding);
+ }
CurrentActor.remove();
}
-} // End of MBean class
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
index 9be8bddd28..7837a9bc38 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeFactory.java
@@ -26,9 +26,12 @@ import java.util.HashMap;
import java.util.Map;
import org.apache.log4j.Logger;
+import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.AMQUnknownExchangeType;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.qmf.ManagementExchange;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
import org.apache.qpid.server.registry.ApplicationRegistry;
@@ -79,27 +82,26 @@ public class DefaultExchangeFactory implements ExchangeFactory
public Exchange createExchange(String exchange, String type, boolean durable, boolean autoDelete)
throws AMQException
{
- ExchangeType<? extends Exchange> exchType = _exchangeClassMap.get(new AMQShortString(type));
- if (exchType == null)
- {
-
- throw new AMQUnknownExchangeType("Unknown exchange type: " + type,null);
- }
- Exchange e = exchType.newInstance(_host, (new AMQShortString(exchange)).intern(), durable, 0, autoDelete);
- return e;
-
+ return createExchange(new AMQShortString(exchange), new AMQShortString(type), durable, autoDelete, 0);
}
public Exchange createExchange(AMQShortString exchange, AMQShortString type, boolean durable, boolean autoDelete,
int ticket)
throws AMQException
{
+ // Check access
+ if (!_host.getSecurityManager().authoriseCreateExchange(autoDelete, durable, exchange, null, null, null, type))
+ {
+ String description = "Permission denied: exchange-name '" + exchange.asString() + "'";
+ throw new AMQSecurityException(description);
+ }
+
ExchangeType<? extends Exchange> exchType = _exchangeClassMap.get(type);
if (exchType == null)
{
-
throw new AMQUnknownExchangeType("Unknown exchange type: " + type,null);
}
+
Exchange e = exchType.newInstance(_host, exchange, durable, ticket, autoDelete);
return e;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
index 84444450c9..0e7459498a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/DefaultExchangeRegistry.java
@@ -20,18 +20,18 @@
*/
package org.apache.qpid.server.exchange;
+import java.util.Collection;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ConcurrentMap;
+
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.exchange.ExchangeInitialiser;
import org.apache.qpid.server.queue.IncomingMessage;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import java.util.Collection;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.ConcurrentMap;
-
public class DefaultExchangeRegistry implements ExchangeRegistry
{
private static final Logger _log = Logger.getLogger(DefaultExchangeRegistry.class);
@@ -87,7 +87,14 @@ public class DefaultExchangeRegistry implements ExchangeRegistry
public void unregisterExchange(AMQShortString name, boolean inUse) throws AMQException
{
+ // Check access
+ if (!_host.getSecurityManager().authoriseDelete(_exchangeMap.get(name)))
+ {
+ throw new AMQSecurityException();
+ }
+
// TODO: check inUse argument
+
Exchange e = _exchangeMap.remove(name);
_exchangeMapStr.remove(name.toString());
if (e != null)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
index 8a31b1bab1..13fe767d3f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/Exchange.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.exchange;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
@@ -138,6 +139,6 @@ public interface Exchange extends ExchangeReferrer, ExchangeConfig
public static interface Task
{
- public void onClose(Exchange exchange);
+ public void onClose(Exchange exchange) throws AMQSecurityException;
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
index aa4cc1ec24..92795487e4 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/exchange/ExchangeFactory.java
@@ -22,8 +22,6 @@ package org.apache.qpid.server.exchange;
import java.util.Collection;
-import org.apache.commons.configuration.Configuration;
-
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.configuration.VirtualHostConfiguration;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java b/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
index ae578eb196..a4974c75ff 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/federation/Bridge.java
@@ -674,13 +674,22 @@ public class Bridge implements BridgeConfig
options.put("qpid.trace.exclude", _link.getFederationTag());
options.put("qpid.trace.id",_link.getRemoteFederationTag());
- _queue = AMQQueueFactory.createAMQQueueImpl(_tmpQueueName,
+ try
+ {
+ _queue = AMQQueueFactory.createAMQQueueImpl(_tmpQueueName,
isDurable(),
_link.getFederationTag(),
false,
false,
- getVirtualHost(), options);
-
+ getVirtualHost(),
+ options);
+ }
+ catch (AMQException e)
+ {
+ // TODO
+ throw new RuntimeException(e);
+ }
+
FlowCreditManager_0_10 creditManager = new WindowCreditManager(0xFFFFFFFF,getMessageWindowSize());
Subscription_0_10 sub = new Subscription_0_10((ServerSession)session,
@@ -695,14 +704,13 @@ public class Bridge implements BridgeConfig
try
{
_queue.registerSubscription(sub, true);
+ getVirtualHost().getBindingFactory().addBinding(_key, _queue, exchange, Collections.<String, Object>emptyMap());
}
catch (AMQException e)
{
// TODO
throw new RuntimeException(e);
}
-
- getVirtualHost().getBindingFactory().addBinding(_key, _queue, exchange, Collections.EMPTY_MAP);
}
public void close()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
index 50019090d9..a5999711bc 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicConsumeMethodHandler.java
@@ -51,9 +51,6 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic
{
AMQProtocolSession protocolConnection = stateManager.getProtocolSession();
-
-
-
AMQChannel channel = protocolConnection.getChannel(channelId);
VirtualHost vHost = protocolConnection.getVirtualHost();
@@ -93,17 +90,9 @@ public class BasicConsumeMethodHandler implements StateAwareMethodListener<Basic
}
else
{
-
final AMQShortString consumerTagName;
- // Check authz
- if (!vHost.getAccessManager().authoriseConsume(protocolConnection,
- body.getExclusive(), body.getNoAck(),
- body.getNoLocal(), body.getNowait(), queue))
- {
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
- }
- else if (queue.isExclusive() && !queue.isDurable())
+ if (queue.isExclusive() && !queue.isDurable())
{
AMQSessionModel session = queue.getExclusiveOwningSession();
if (session == null || session.getConnectionModel() != protocolConnection)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java
index 2ab0b04fb9..83ca526578 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicGetMethodHandler.java
@@ -92,13 +92,7 @@ public class BasicGetMethodHandler implements StateAwareMethodListener<BasicGetB
}
else
{
-
- //Perform ACLs
- if (!vHost.getAccessManager().authoriseConsume(protocolConnection, body.getNoAck(), queue))
- {
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
- }
- else if (queue.isExclusive())
+ if (queue.isExclusive())
{
AMQSessionModel session = queue.getExclusiveOwningSession();
if (session == null || session.getConnectionModel() != protocolConnection)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java
index a7d3ad6217..8f23b1c4d4 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/BasicPublishMethodHandler.java
@@ -23,14 +23,13 @@ package org.apache.qpid.server.handler;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
import org.apache.qpid.exchange.ExchangeDefaults;
-import org.apache.qpid.framing.BasicPublishBody;
import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.BasicPublishBody;
+import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.framing.abstraction.MessagePublishInfo;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.security.access.Permission;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -59,18 +58,17 @@ public class BasicPublishMethodHandler implements StateAwareMethodListener<Basic
_logger.debug("Publish received on channel " + channelId);
}
- AMQShortString exchange = body.getExchange();
+ AMQShortString exchangeName = body.getExchange();
// TODO: check the delivery tag field details - is it unique across the broker or per subscriber?
- if (exchange == null)
+ if (exchangeName == null)
{
- exchange = ExchangeDefaults.DEFAULT_EXCHANGE_NAME;
-
+ exchangeName = ExchangeDefaults.DEFAULT_EXCHANGE_NAME;
}
VirtualHost vHost = session.getVirtualHost();
- Exchange e = vHost.getExchangeRegistry().getExchange(exchange);
+ Exchange exch = vHost.getExchangeRegistry().getExchange(exchangeName);
// if the exchange does not exist we raise a channel exception
- if (e == null)
+ if (exch == null)
{
throw body.getChannelException(AMQConstant.NOT_FOUND, "Unknown exchange name");
}
@@ -86,17 +84,9 @@ public class BasicPublishMethodHandler implements StateAwareMethodListener<Basic
throw body.getChannelNotFoundException(channelId);
}
- //Access Control
- if (!vHost.getAccessManager().authorisePublish(session,
- body.getImmediate(), body.getMandatory(),
- body.getRoutingKey(), e))
- {
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
- }
-
MessagePublishInfo info = session.getMethodRegistry().getProtocolVersionMethodConverter().convertToInfo(body);
- info.setExchange(exchange);
- channel.setPublishFrame(info, e);
+ info.setExchange(exchangeName);
+ channel.setPublishFrame(info, exch);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java
index f5c2b93f46..6d874ee971 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ChannelOpenHandler.java
@@ -20,15 +20,19 @@
*/
package org.apache.qpid.server.handler;
-import java.util.UUID;
import java.io.ByteArrayOutputStream;
import java.io.DataOutputStream;
import java.io.IOException;
+import java.util.UUID;
+import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.*;
-import org.apache.qpid.framing.amqp_0_91.MethodRegistry_0_91;
+import org.apache.qpid.framing.ChannelOpenBody;
+import org.apache.qpid.framing.ChannelOpenOkBody;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.framing.amqp_0_9.MethodRegistry_0_9;
+import org.apache.qpid.framing.amqp_0_91.MethodRegistry_0_91;
import org.apache.qpid.framing.amqp_8_0.MethodRegistry_8_0;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.AMQChannel;
@@ -39,6 +43,8 @@ import org.apache.qpid.server.virtualhost.VirtualHost;
public class ChannelOpenHandler implements StateAwareMethodListener<ChannelOpenBody>
{
+ private static final Logger _logger = Logger.getLogger(ChannelOpenHandler.class);
+
private static ChannelOpenHandler _instance = new ChannelOpenHandler();
public static ChannelOpenHandler getInstance()
@@ -54,19 +60,16 @@ public class ChannelOpenHandler implements StateAwareMethodListener<ChannelOpenB
{
AMQProtocolSession session = stateManager.getProtocolSession();
VirtualHost virtualHost = session.getVirtualHost();
-
// Protect the broker against out of order frame request.
if (virtualHost == null)
{
throw new AMQException(AMQConstant.COMMAND_INVALID, "Virtualhost has not yet been set. ConnectionOpen has not been called.", null);
}
+ _logger.info("Connecting to: " + virtualHost.getName());
- final AMQChannel channel = new AMQChannel(session,channelId,
- virtualHost.getMessageStore());
-
+ final AMQChannel channel = new AMQChannel(session,channelId, virtualHost.getMessageStore());
-
session.addChannel(channel);
ChannelOpenOkBody response;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java
index b5194084f2..76d1e5378f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java
@@ -20,18 +20,18 @@
*/
package org.apache.qpid.server.handler;
+import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
-import org.apache.qpid.framing.*;
-import org.apache.qpid.framing.amqp_0_91.MethodRegistry_0_91;
-import org.apache.qpid.framing.amqp_0_9.MethodRegistry_0_9;
-import org.apache.qpid.framing.amqp_8_0.MethodRegistry_8_0;
+import org.apache.qpid.framing.AMQMethodBody;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.ConnectionOpenBody;
+import org.apache.qpid.framing.MethodRegistry;
import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.log4j.Logger;
public class ConnectionOpenMethodHandler implements StateAwareMethodListener<ConnectionOpenBody>
{
@@ -57,7 +57,6 @@ public class ConnectionOpenMethodHandler implements StateAwareMethodListener<Con
{
AMQProtocolSession session = stateManager.getProtocolSession();
-
//ignore leading '/'
String virtualHostName;
if ((body.getVirtualHost() != null) && body.getVirtualHost().charAt(0) == '/')
@@ -77,14 +76,15 @@ public class ConnectionOpenMethodHandler implements StateAwareMethodListener<Con
}
else
{
- session.setVirtualHost(virtualHost);
-
- //Perform ACL
- if (!virtualHost.getAccessManager().authoriseConnect(session, virtualHost))
+ // Check virtualhost access
+ if (!virtualHost.getSecurityManager().accessVirtualhost(virtualHostName, session.getRemoteAddress().toString()))
{
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
+ throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied: '" + virtualHost.getName() + "'");
}
+ session.setVirtualHost(virtualHost);
+ _logger.error(session.getPrincipal().getName());
+
// See Spec (0.8.2). Section 3.1.2 Virtual Hosts
if (session.getContextKey() == null)
{
@@ -97,8 +97,6 @@ public class ConnectionOpenMethodHandler implements StateAwareMethodListener<Con
stateManager.changeState(AMQState.CONNECTION_OPEN);
session.writeFrame(responseBody.generateFrame(channelId));
-
-
}
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
index a2a6faf21b..cda8cff25a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
@@ -97,7 +97,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
ApplicationRegistry.getInstance().getConfiguration().getHeartBeatDelay());
session.writeFrame(tuneBody.generateFrame(0));
session.setAuthorizedID(new UsernamePrincipal(ss.getAuthorizationID()));
- disposeSaslServer(session);
+ disposeSaslServer(session);
break;
case CONTINUE:
stateManager.changeState(AMQState.CONNECTION_NOT_AUTH);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
index 6698ae888a..6512ff1a14 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
@@ -60,11 +60,11 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
public void methodReceived(AMQStateManager stateManager, ConnectionStartOkBody body, int channelId) throws AMQException
{
AMQProtocolSession session = stateManager.getProtocolSession();
-
+
_logger.info("SASL Mechanism selected: " + body.getMechanism());
_logger.info("Locale selected: " + body.getLocale());
- AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager();//session.getVirtualHost().getAuthenticationManager();
+ AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager();
SaslServer ss = null;
try
@@ -73,8 +73,7 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
if (ss == null)
{
- throw body.getConnectionException(AMQConstant.RESOURCE_ERROR, "Unable to create SASL Server:" + body.getMechanism()
- );
+ throw body.getConnectionException(AMQConstant.RESOURCE_ERROR, "Unable to create SASL Server:" + body.getMechanism());
}
session.setSaslServer(ss);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
index 7cfd1fc121..98a0d33487 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeclareHandler.java
@@ -45,8 +45,6 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange
return _instance;
}
-
-
private ExchangeDeclareHandler()
{
}
@@ -58,28 +56,15 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange
ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry();
ExchangeFactory exchangeFactory = virtualHost.getExchangeFactory();
- if (!body.getPassive())
- {
- // Perform ACL if request is not passive
- if (!virtualHost.getAccessManager().authoriseCreateExchange(session, body.getAutoDelete(),
- body.getDurable(), body.getExchange(), body.getInternal(), body.getNowait(), body.getPassive(),
- body.getType()))
- {
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
- }
-
- }
-
if (_logger.isDebugEnabled())
{
_logger.debug("Request to declare exchange of type " + body.getType() + " with name " + body.getExchange());
}
+
synchronized(exchangeRegistry)
{
Exchange exchange = exchangeRegistry.getExchange(body.getExchange());
-
-
if (exchange == null)
{
if(body.getPassive() && ((body.getType() == null) || body.getType().length() ==0))
@@ -90,7 +75,6 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange
{
try
{
-
exchange = exchangeFactory.createExchange(body.getExchange() == null ? null : body.getExchange().intern(),
body.getType() == null ? null : body.getType().intern(),
body.getDurable(),
@@ -113,14 +97,12 @@ public class ExchangeDeclareHandler implements StateAwareMethodListener<Exchange
throw new AMQConnectionException(AMQConstant.NOT_ALLOWED, "Attempt to redeclare exchange: " + body.getExchange() + " of type " + exchange.getTypeShortString() + " to " + body.getType() +".",body.getClazz(), body.getMethod(),body.getMajor(),body.getMinor(),null);
}
-
}
if(!body.getNowait())
{
MethodRegistry methodRegistry = session.getMethodRegistry();
AMQMethodBody responseBody = methodRegistry.createExchangeDeclareOkBody();
session.writeFrame(responseBody.generateFrame(channelId));
-
}
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeleteHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeleteHandler.java
index 8dbd457cc9..586aaf9336 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeleteHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/ExchangeDeleteHandler.java
@@ -27,7 +27,6 @@ import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.exchange.ExchangeInUseException;
import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.security.access.Permission;
import org.apache.qpid.server.state.AMQStateManager;
import org.apache.qpid.server.state.StateAwareMethodListener;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -51,13 +50,6 @@ public class ExchangeDeleteHandler implements StateAwareMethodListener<ExchangeD
VirtualHost virtualHost = session.getVirtualHost();
ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry();
- //Perform ACLs
- if (!virtualHost.getAccessManager().authoriseDelete(session,
- exchangeRegistry.getExchange(body.getExchange())))
- {
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
- }
-
try
{
if(exchangeRegistry.getExchange(body.getExchange()) == null)
@@ -75,6 +67,5 @@ public class ExchangeDeleteHandler implements StateAwareMethodListener<ExchangeD
throw body.getChannelException(AMQConstant.IN_USE, "Exchange in use");
// TODO: sort out consistent channel close mechanism that does all clean up etc.
}
-
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java
index 594edb090c..0eb69e4b16 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueBindHandler.java
@@ -65,7 +65,6 @@ public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody>
ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry();
QueueRegistry queueRegistry = virtualHost.getQueueRegistry();
-
final AMQQueue queue;
final AMQShortString routingKey;
@@ -113,14 +112,7 @@ public class QueueBindHandler implements StateAwareMethodListener<QueueBindBody>
try
{
-
- //Perform ACLs
- if (!virtualHost.getAccessManager().authoriseBind(protocolConnection, exch,
- queue, routingKey))
- {
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
- }
- else if (queue.isExclusive() && !queue.isDurable())
+ if (queue.isExclusive() && !queue.isDurable())
{
AMQSessionModel session = queue.getExclusiveOwningSession();
if (session == null || session.getConnectionModel() != protocolConnection)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
index 4f7d275e71..8939cfa334 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeclareHandler.java
@@ -69,21 +69,9 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
QueueRegistry queueRegistry = virtualHost.getQueueRegistry();
DurableConfigurationStore store = virtualHost.getDurableConfigurationStore();
-
- if (!body.getPassive())
- {
- // Perform ACL if request is not passive
- if (!virtualHost.getAccessManager().authoriseCreateQueue(protocolConnection, body.getAutoDelete(), body.getDurable(),
- body.getExclusive(), body.getNowait(), body.getPassive(), body.getQueue()))
- {
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
- }
- }
-
final AMQShortString queueName;
// if we aren't given a queue name, we create one which we return to the client
-
if ((body.getQueue() == null) || (body.getQueue().length() == 0))
{
queueName = createName();
@@ -94,11 +82,11 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
}
AMQQueue queue;
+
//TODO: do we need to check that the queue already exists with exactly the same "configuration"?
synchronized (queueRegistry)
{
-
queue = queueRegistry.getQueue(queueName);
AMQSessionModel owningSession = null;
@@ -110,7 +98,6 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
if (queue == null)
{
-
if (body.getPassive())
{
String msg = "Queue: " + queueName + " not found on VirtualHost(" + virtualHost + ").";
@@ -129,9 +116,8 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
queue.setDeleteOnNoConsumers(true);
}
queueRegistry.registerQueue(queue);
- if(body.getExclusive())
+ if (body.getExclusive())
{
-
queue.setExclusiveOwningSession(protocolConnection.getChannel(channelId));
queue.setPrincipalHolder(protocolConnection);
@@ -153,7 +139,6 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
}
});
}
-
}
if (autoRegister)
{
@@ -239,7 +224,6 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
final AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueName, body.getDurable(), owner, body.getAutoDelete(),
body.getExclusive(),virtualHost, body.getArguments());
-
if (body.getExclusive() && !body.getDurable())
{
final AMQProtocolSession.Task deleteQueueTask =
@@ -263,7 +247,7 @@ public class QueueDeclareHandler implements StateAwareMethodListener<QueueDeclar
session.removeSessionCloseTask(deleteQueueTask);
}
});
- }// if exclusive and not durable
+ }
return queue;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java
index 4a1940ee01..da52268e52 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueDeleteHandler.java
@@ -99,25 +99,18 @@ public class QueueDeleteHandler implements StateAwareMethodListener<QueueDeleteB
{
// TODO - Error code
throw body.getChannelException(AMQConstant.IN_USE, "Queue: " + body.getQueue() + " is still used.");
-
}
else
{
-
AMQSessionModel session = queue.getExclusiveOwningSession();
- //Perform ACLs
- if (!virtualHost.getAccessManager().authoriseDelete(protocolConnection, queue))
- {
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
- }
- else if (queue.isExclusive() && !queue.isDurable() && (session == null || session.getConnectionModel() != protocolConnection))
+ if (queue.isExclusive() && !queue.isDurable() && (session == null || session.getConnectionModel() != protocolConnection))
{
throw body.getConnectionException(AMQConstant.NOT_ALLOWED,
"Queue " + queue.getNameShortString() + " is exclusive, but not created on this Connection.");
}
+
int purged = queue.delete();
-
if (queue.isDurable())
{
store.removeQueue(queue);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java
index a465c5a20f..759eec0129 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueuePurgeHandler.java
@@ -101,12 +101,7 @@ public class QueuePurgeHandler implements StateAwareMethodListener<QueuePurgeBod
{
AMQSessionModel session = queue.getExclusiveOwningSession();
- //Perform ACLs
- if (!virtualHost.getAccessManager().authorisePurge(protocolConnection, queue))
- {
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
- }
- else if (queue.isExclusive() && (session == null || session.getConnectionModel() != protocolConnection))
+ if (queue.isExclusive() && (session == null || session.getConnectionModel() != protocolConnection))
{
throw body.getConnectionException(AMQConstant.NOT_ALLOWED,
"Queue is exclusive, but not created on this Connection.");
diff --git a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
index 29c30de9cc..8391a4b184 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/handler/QueueUnbindHandler.java
@@ -20,24 +20,23 @@ package org.apache.qpid.server.handler;
*
*/
-
import org.apache.log4j.Logger;
-
-import org.apache.qpid.framing.*;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.framing.AMQMethodBody;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.QueueUnbindBody;
import org.apache.qpid.framing.amqp_0_9.MethodRegistry_0_9;
-import org.apache.qpid.server.state.StateAwareMethodListener;
-import org.apache.qpid.server.state.AMQStateManager;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.queue.QueueRegistry;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.AMQChannel;
-import org.apache.qpid.server.security.access.Permission;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.AMQInvalidRoutingKeyException;
-import org.apache.qpid.protocol.AMQConstant;
+import org.apache.qpid.server.queue.QueueRegistry;
+import org.apache.qpid.server.state.AMQStateManager;
+import org.apache.qpid.server.state.StateAwareMethodListener;
+import org.apache.qpid.server.virtualhost.VirtualHost;
public class QueueUnbindHandler implements StateAwareMethodListener<QueueUnbindBody>
{
@@ -100,12 +99,6 @@ public class QueueUnbindHandler implements StateAwareMethodListener<QueueUnbindB
throw body.getChannelException(AMQConstant.NOT_FOUND, "Exchange " + body.getExchange() + " does not exist.");
}
- //Perform ACLs
- if (!virtualHost.getAccessManager().authoriseUnbind(session, exch, routingKey, queue))
- {
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED, "Permission denied");
- }
-
if(virtualHost.getBindingFactory().getBinding(String.valueOf(routingKey), queue, exch, FieldTable.convertToMap(body.getArguments())) == null)
{
throw body.getChannelException(AMQConstant.NOT_FOUND,"No such binding");
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 0ee5763d91..7e7ac94d06 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
@@ -20,34 +20,36 @@
*/
package org.apache.qpid.server.management;
-import org.apache.qpid.management.common.mbeans.ConfigurationManagement;
-import org.apache.qpid.management.common.mbeans.LoggingManagement;
-import org.apache.qpid.management.common.mbeans.UserManagement;
-import org.apache.qpid.server.logging.actors.CurrentActor;
-import org.apache.qpid.server.logging.actors.ManagementActor;
-import org.apache.qpid.server.logging.messages.ManagementConsoleMessages;
-import org.apache.log4j.Logger;
-
-import javax.management.remote.MBeanServerForwarder;
-import javax.management.remote.JMXPrincipal;
-import javax.management.remote.JMXConnectionNotification;
-import javax.management.MBeanServer;
-import javax.management.ObjectName;
-import javax.management.MBeanInfo;
-import javax.management.MBeanOperationInfo;
-import javax.management.JMException;
-import javax.management.NotificationListener;
-import javax.management.Notification;
-import javax.security.auth.Subject;
import java.lang.reflect.InvocationHandler;
-import java.lang.reflect.Proxy;
+import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
+import java.lang.reflect.Proxy;
+import java.security.AccessControlContext;
import java.security.AccessController;
import java.security.Principal;
-import java.security.AccessControlContext;
-import java.util.HashSet;
-import java.util.Set;
import java.util.Properties;
+import java.util.Set;
+
+import javax.management.Attribute;
+import javax.management.JMException;
+import javax.management.MBeanInfo;
+import javax.management.MBeanOperationInfo;
+import javax.management.MBeanServer;
+import javax.management.Notification;
+import javax.management.NotificationListener;
+import javax.management.ObjectName;
+import javax.management.remote.JMXConnectionNotification;
+import javax.management.remote.JMXPrincipal;
+import javax.management.remote.MBeanServerForwarder;
+import javax.security.auth.Subject;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.logging.actors.CurrentActor;
+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.security.SecurityManager;
+import org.apache.qpid.server.security.access.Operation;
/**
* This class can be used by the JMXConnectorServer as an InvocationHandler for the mbean operations. This implements
@@ -65,18 +67,11 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
private MBeanServer _mbs;
private static Properties _userRoles = new Properties();
private static ManagementActor _logActor;
-
- private static HashSet<String> _adminOnlyMethods = new HashSet<String>();
- {
- _adminOnlyMethods.add(UserManagement.TYPE);
- _adminOnlyMethods.add(LoggingManagement.TYPE);
- _adminOnlyMethods.add(ConfigurationManagement.TYPE);
- }
public static MBeanServerForwarder newProxyInstance()
{
final InvocationHandler handler = new MBeanInvocationHandlerImpl();
- final Class[] interfaces = new Class[]{MBeanServerForwarder.class};
+ final Class<?>[] interfaces = new Class[] { MBeanServerForwarder.class };
_logActor = new ManagementActor(CurrentActor.get().getRootMessageLogger());
@@ -87,7 +82,7 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
public Object invoke(Object proxy, Method method, Object[] args) throws Throwable
{
- final String methodName = method.getName();
+ final String methodName = getMethodName(method, args);
if (methodName.equals("getMBeanServer"))
{
@@ -112,145 +107,165 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
AccessControlContext acc = AccessController.getContext();
Subject subject = Subject.getSubject(acc);
- // Allow operations performed locally on behalf of the connector server itself
- if (subject == null)
- {
- 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");
- }
-
- // Retrieve JMXPrincipal from Subject
- Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class);
- if (principals == null || principals.isEmpty())
- {
- throw new SecurityException("Access denied");
- }
-
- Principal principal = principals.iterator().next();
- String identity = principal.getName();
-
- if (isAdminMethod(args))
+ try
{
- if (isAdmin(identity))
+ // Allow operations performed locally on behalf of the connector server itself
+ if (subject == null)
+ {
+ 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())
+ {
+ throw new SecurityException("Access denied: no principal");
+ }
+
+ // Save the principal
+ Principal principal = principals.iterator().next();
+ SecurityManager.setThreadPrincipal(principal);
+
+ // 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();
+ }
else
{
- throw new SecurityException("Access denied");
+ security = ApplicationRegistry.getInstance().getVirtualHostRegistry().getVirtualHost(vhost).getSecurityManager();
}
+
+ if (isAccessMethod(methodName) || impact == MBeanOperationInfo.INFO)
+ {
+ // Check for read-only method invocation permission
+ if (!security.authoriseMethod(Operation.ACCESS, type, methodName))
+ {
+ 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);
}
-
- // Following users can perform any operation other than "createMBean" and "unregisterMBean"
- if (isAllowedToModify(identity))
- {
- return method.invoke(_mbs, args);
- }
-
- // These users can only call "getAttribute" on the MBeanServerDelegate MBean
- // Here we can add other fine grained permissions like specific method for a particular mbean
- if (isReadOnlyUser(identity) && isReadOnlyMethod(method, args))
+ catch (InvocationTargetException e)
{
- return method.invoke(_mbs, args);
+ throw e.getTargetException();
}
+ }
- throw new SecurityException("Access denied");
+ private String getType(Method method, Object[] args)
+ {
+ if (args[0] instanceof ObjectName)
+ {
+ ObjectName object = (ObjectName) args[0];
+ String type = object.getKeyProperty("type");
+
+ return type;
+ }
+ return null;
}
- private boolean isAdminMethod(Object[] args)
- {
+ private String getVirtualHost(Method method, Object[] args)
+ {
if (args[0] instanceof ObjectName)
{
ObjectName object = (ObjectName) args[0];
+ String vhost = object.getKeyProperty("VirtualHost");
- return _adminOnlyMethods.contains(object.getKeyProperty("type"));
- }
- return false;
- }
-
- // Initialises the user roles
- public static void setAccessRights(Properties accessRights)
- {
- _userRoles = accessRights;
- }
-
- private boolean isAdmin(String userName)
- {
- if (ADMIN.equals(_userRoles.getProperty(userName)))
- {
- return true;
+ return vhost;
}
- return false;
+ return null;
}
-
- private boolean isAllowedToModify(String userName)
+
+ private String getMethodName(Method method, Object[] args)
{
- if (ADMIN.equals(_userRoles.getProperty(userName))
- || READWRITE.equals(_userRoles.getProperty(userName)))
- {
- return true;
- }
- return false;
- }
+ String methodName = method.getName();
- private boolean isReadOnlyUser(String userName)
- {
- if (READONLY.equals(_userRoles.getProperty(userName)))
+ // if arguments are set, try and work out real method name
+ if (args != null && args.length >= 1 && args[0] instanceof ObjectName)
{
- return true;
+ if (methodName.equals("getAttribute"))
+ {
+ methodName = "get" + (String) args[1];
+ }
+ else if (methodName.equals("setAttribute"))
+ {
+ methodName = "set" + ((Attribute) args[1]).getName();
+ }
+ else if (methodName.equals("invoke"))
+ {
+ methodName = (String) args[1];
+ }
}
- return false;
+
+ return methodName;
}
- private boolean isReadOnlyMethod(Method method, Object[] args)
+ private int getImpact(Method method, Object[] args)
{
- String methodName = method.getName();
-
- //handle standard get/set/query and select 'is' methods from MBeanServer
- if (methodName.startsWith("query") || methodName.startsWith("get")
- ||methodName.startsWith("isInstanceOf") || methodName.startsWith("isRegistered"))
- {
- return true;
- }
- else if (methodName.startsWith("set"))
- {
- return false;
- }
-
//handle invocation of other methods on mbeans
- if ((args[0] instanceof ObjectName) && (methodName.equals("invoke")))
+ if ((args[0] instanceof ObjectName) && (method.getName().equals("invoke")))
{
-
//get invoked method name
String mbeanMethod = (args.length > 1) ? (String) args[1] : null;
if (mbeanMethod == null)
{
- return false;
+ return -1;
}
-
+
try
{
- //check if the given method is tagged with an INFO impact attribute
+ //Get the impact attribute
MBeanInfo mbeanInfo = _mbs.getMBeanInfo((ObjectName) args[0]);
if (mbeanInfo != null)
{
MBeanOperationInfo[] opInfos = mbeanInfo.getOperations();
for (MBeanOperationInfo opInfo : opInfos)
{
- if (opInfo.getName().equals(mbeanMethod) && (opInfo.getImpact() == MBeanOperationInfo.INFO))
+ if (opInfo.getName().equals(mbeanMethod))
{
- return true;
+ return opInfo.getImpact();
}
}
}
@@ -261,7 +276,20 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler, Notificati
}
}
- return false;
+ return -1;
+ }
+
+ private boolean isAccessMethod(String methodName)
+ {
+ //handle standard get/query/is methods from MBeanServer
+ 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)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
index 4260307d04..25571f1022 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
@@ -20,16 +20,52 @@
*/
package org.apache.qpid.server.protocol;
+import java.io.IOException;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
+import java.nio.ByteBuffer;
+import java.security.Principal;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.UUID;
+import java.util.Map.Entry;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.concurrent.CopyOnWriteArraySet;
+import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicLong;
+
+import javax.management.JMException;
+import javax.security.sasl.SaslServer;
+
import org.apache.log4j.Logger;
import org.apache.mina.transport.vmpipe.VmPipeAddress;
-
import org.apache.qpid.AMQChannelException;
import org.apache.qpid.AMQConnectionException;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.codec.AMQCodecFactory;
import org.apache.qpid.codec.AMQDecoder;
import org.apache.qpid.common.ClientProperties;
-import org.apache.qpid.framing.*;
+import org.apache.qpid.framing.AMQBody;
+import org.apache.qpid.framing.AMQDataBlock;
+import org.apache.qpid.framing.AMQFrame;
+import org.apache.qpid.framing.AMQMethodBody;
+import org.apache.qpid.framing.AMQProtocolHeaderException;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.ChannelCloseBody;
+import org.apache.qpid.framing.ChannelCloseOkBody;
+import org.apache.qpid.framing.ConnectionCloseBody;
+import org.apache.qpid.framing.ContentBody;
+import org.apache.qpid.framing.ContentHeaderBody;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.HeartbeatBody;
+import org.apache.qpid.framing.MethodDispatcher;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.framing.ProtocolInitiation;
+import org.apache.qpid.framing.ProtocolVersion;
import org.apache.qpid.pool.Job;
import org.apache.qpid.pool.ReferenceCountingExecutorService;
import org.apache.qpid.protocol.AMQConstant;
@@ -61,25 +97,6 @@ import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
import org.apache.qpid.transport.NetworkDriver;
import org.apache.qpid.transport.Sender;
-import javax.management.JMException;
-import javax.security.sasl.SaslServer;
-import java.io.IOException;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
-import java.nio.ByteBuffer;
-import java.security.Principal;
-import java.util.ArrayList;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.UUID;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.CopyOnWriteArrayList;
-import java.util.concurrent.CopyOnWriteArraySet;
-import java.util.concurrent.atomic.AtomicBoolean;
-import java.util.concurrent.atomic.AtomicLong;
-
public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocolSession, ConnectionConfig
{
private static final Logger _logger = Logger.getLogger(AMQProtocolEngine.class);
@@ -117,6 +134,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
private Object _lastSent;
protected volatile boolean _closed;
+
// maximum number of channels this session should have
private long _maxNoOfChannels = 1000;
@@ -358,14 +376,12 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
public void methodFrameReceived(int channelId, AMQMethodBody methodBody)
{
-
final AMQMethodEvent<AMQMethodBody> evt = new AMQMethodEvent<AMQMethodBody>(channelId, methodBody);
try
{
try
{
-
boolean wasAnyoneInterested = _stateManager.methodReceived(evt);
if (!_frameListeners.isEmpty())
@@ -418,10 +434,15 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
_logger.info(e.getMessage() + " whilst processing:" + methodBody);
closeConnection(channelId, e, false);
}
+ catch (AMQSecurityException e)
+ {
+ AMQConnectionException ce = evt.getMethod().getConnectionException(AMQConstant.ACCESS_REFUSED, e.getMessage());
+ _logger.info(e.getMessage() + " whilst processing:" + methodBody);
+ closeConnection(channelId, ce, false);
+ }
}
catch (Exception e)
{
-
for (AMQMethodListener listener : _frameListeners)
{
listener.error(e);
@@ -999,7 +1020,6 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
{
if (throwable instanceof AMQProtocolHeaderException)
{
-
writeFrame(new ProtocolInitiation(ProtocolVersion.getLatestSupportedVersion()));
_networkDriver.close();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
index 366abd3f7c..8b53257e88 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueue.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.queue;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.protocol.AMQConnectionModel;
@@ -194,7 +195,7 @@ public interface AMQQueue extends Managable, Comparable<AMQQueue>, ExchangeRefer
void deleteMessageFromTop();
- long clearQueue();
+ long clearQueue() throws AMQException;
/**
* Checks the status of messages on the queue, purging expired ones, firing age related alerts etc.
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
index 3340c1e20a..a547205d27 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueFactory.java
@@ -21,6 +21,7 @@
package org.apache.qpid.server.queue;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -29,7 +30,6 @@ import org.apache.qpid.server.configuration.QueueConfiguration;
import java.util.Map;
import java.util.HashMap;
-
public class AMQQueueFactory
{
public static final AMQShortString X_QPID_PRIORITIES = new AMQShortString("x-qpid-priorities");
@@ -128,22 +128,20 @@ public class AMQQueueFactory
};
-
+ /** @see #createAMQQueueImpl(String, boolean, String, boolean, boolean, VirtualHost, Map) */
public static AMQQueue createAMQQueueImpl(AMQShortString name,
boolean durable,
AMQShortString owner,
boolean autoDelete,
- boolean exclusive,
- VirtualHost virtualHost,
- final FieldTable arguments)
+ boolean exclusive,
+ VirtualHost virtualHost, final FieldTable arguments) throws AMQException
{
return createAMQQueueImpl(name == null ? null : name.toString(),
durable,
owner == null ? null : owner.toString(),
autoDelete,
exclusive,
- virtualHost,
- FieldTable.convertToMap(arguments));
+ virtualHost, FieldTable.convertToMap(arguments));
}
@@ -152,8 +150,15 @@ public class AMQQueueFactory
String owner,
boolean autoDelete,
boolean exclusive,
- VirtualHost virtualHost, Map<String, Object> arguments)
+ VirtualHost virtualHost, Map<String, Object> arguments) throws AMQSecurityException
{
+ // Access check
+ if (!virtualHost.getSecurityManager().authoriseCreateQueue(autoDelete, durable, exclusive, null, null, new AMQShortString(queueName), owner))
+ {
+ String description = "Permission denied: queue-name '" + queueName + "'";
+ throw new AMQSecurityException(description);
+ }
+
int priorities = 1;
String conflationKey = null;
if(arguments != null)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
index af1f412843..806b7f3744 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/AMQQueueMBean.java
@@ -28,6 +28,7 @@ import org.apache.qpid.framing.ContentHeaderBody;
import org.apache.qpid.management.common.mbeans.ManagedQueue;
import org.apache.qpid.management.common.mbeans.annotations.MBeanConstructor;
import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
+import org.apache.qpid.server.logging.actors.CurrentActor;
import org.apache.qpid.server.management.AMQManagedObject;
import org.apache.qpid.server.management.ManagedObject;
import org.apache.qpid.server.message.ServerMessage;
@@ -39,6 +40,7 @@ import org.apache.qpid.server.txn.LocalTransaction;
import org.apache.qpid.transport.MessageProperties;
import javax.management.JMException;
+import javax.management.MBeanException;
import javax.management.MBeanNotificationInfo;
import javax.management.Notification;
import javax.management.OperationsException;
@@ -336,7 +338,14 @@ public class AMQQueueMBean extends AMQManagedObject implements ManagedQueue, Que
*/
public Long clearQueue() throws JMException
{
- return _queue.clearQueue();
+ try
+ {
+ return _queue.clearQueue();
+ }
+ catch (AMQException ex)
+ {
+ throw new MBeanException(ex, "Error clearing queue " + _queueName);
+ }
}
/**
diff --git a/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java b/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
index afc7fb6480..7e78fd0481 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/queue/SimpleAMQQueue.java
@@ -1,11 +1,31 @@
+/*
+ * 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.queue;
import org.apache.log4j.Logger;
import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.pool.ReadWriteRunnable;
import org.apache.qpid.pool.ReferenceCountingExecutorService;
+import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.AMQChannel;
import org.apache.qpid.server.protocol.AMQConnectionModel;
import org.apache.qpid.server.protocol.AMQSessionModel;
@@ -50,26 +70,6 @@ import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;
import java.util.concurrent.atomic.AtomicReference;
-/*
-*
-* 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.
-*
-*/
public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
{
private static final Logger _logger = Logger.getLogger(SimpleAMQQueue.class);
@@ -386,9 +386,16 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
// ------ Manage Subscriptions
- public synchronized void registerSubscription(final Subscription subscription, final boolean exclusive) throws AMQException
+ public synchronized void registerSubscription(final Subscription subscription, final boolean exclusive)
+ throws AMQSecurityException, ExistingExclusiveSubscription, ExistingSubscriptionPreventsExclusive
{
-
+ // Access control
+ if (!getVirtualHost().getSecurityManager().authoriseConsume(this))
+ {
+ throw new AMQSecurityException("Permission denied");
+ }
+
+
if (hasExclusiveSubscriber())
{
throw new ExistingExclusiveSubscription();
@@ -403,7 +410,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
else
{
_exclusiveSubscriber = subscription;
-
}
}
@@ -1212,38 +1218,9 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
- public void purge(final long request)
+ public void purge(final long request) throws AMQException
{
- if(request == 0l)
- {
- clearQueue();
- }
- else if(request > 0l)
- {
-
- QueueEntryIterator queueListIterator = _entries.iterator();
- long count = 0;
-
- ServerTransaction txn = new LocalTransaction(getVirtualHost().getTransactionLog());
-
- while (queueListIterator.advance())
- {
- QueueEntry node = queueListIterator.getNode();
- if (!node.isDeleted() && node.acquire())
- {
- dequeueEntry(node, txn);
- if(++count == request)
- {
- break;
- }
- }
-
- }
-
- txn.commit();
-
-
- }
+ clear(request);
}
public long getCreateTime()
@@ -1270,9 +1247,19 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
}
}
- public long clearQueue()
- {
+ public long clearQueue() throws AMQException
+ {
+ return clear(0l);
+ }
+ private long clear(final long request) throws AMQSecurityException
+ {
+ //Perform ACLs
+ if (!getVirtualHost().getSecurityManager().authorisePurge(this))
+ {
+ throw new AMQSecurityException("Permission denied: queue " + getName());
+ }
+
QueueEntryIterator queueListIterator = _entries.iterator();
long count = 0;
@@ -1284,7 +1271,10 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
if (!node.isDeleted() && node.acquire())
{
dequeueEntry(node, txn);
- count++;
+ if(++count == request)
+ {
+ break;
+ }
}
}
@@ -1292,7 +1282,6 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
txn.commit();
return count;
-
}
private void dequeueEntry(final QueueEntry node)
@@ -1329,12 +1318,18 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
_deleteTaskList.remove(task);
}
- public int delete() throws AMQException
+ // TODO list all thrown exceptions
+ public int delete() throws AMQSecurityException, AMQException
{
if (!_deleted.getAndSet(true))
{
+ // Check access
+ if (!_virtualHost.getSecurityManager().authoriseDelete(this))
+ {
+ throw new AMQSecurityException("Permission denied: " + getName());
+ }
- for(Binding b : getBindings())
+ for (Binding b : getBindings())
{
_virtualHost.getBindingFactory().removeBinding(b);
}
@@ -1606,6 +1601,11 @@ public class SimpleAMQQueue implements AMQQueue, Subscription.StateListener
public void flushSubscription(Subscription sub) throws AMQException
{
+ // Access control
+ if (!getVirtualHost().getSecurityManager().authoriseConsume(this))
+ {
+ throw new AMQSecurityException("Permission denied: " + getName());
+ }
flushSubscription(sub, Long.MAX_VALUE);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
index 4cb3d9e209..9adab58a0c 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
@@ -124,7 +124,6 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
@SuppressWarnings("finally")
public static void initialise(IApplicationRegistry instance, int instanceID) throws Exception
{
- _logger.error("initialise(IApplicationRegistry instance, int instanceID)");
if (instance != null)
{
_logger.info("Initialising Application Registry(" + instance + "):" + instanceID);
@@ -142,7 +141,6 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
try
{
- _logger.error("instance.initialise(instanceID)");
instance.initialise(instanceID);
}
catch (Exception e)
@@ -237,12 +235,11 @@ public abstract class ApplicationRegistry implements IApplicationRegistry
public void configure() throws ConfigurationException
{
-
_configurationManager = new ConfigurationManager();
try
{
- _pluginManager = new PluginManager(_configuration.getPluginDirectory());
+ _pluginManager = new PluginManager(_configuration.getPluginDirectory(), _configuration.getCacheDirectory());
}
catch (Exception e)
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java
new file mode 100644
index 0000000000..8c9c2050e8
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java
@@ -0,0 +1,69 @@
+/*
+ *
+ * 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;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+
+/**
+ * This is intended as the parent for all simple plugins.
+ */
+public abstract class AbstractPlugin implements SecurityPlugin
+{
+ protected final Logger _logger = Logger.getLogger(getClass());
+
+ public ConfigurationPlugin _config;
+
+ public String getPluginName()
+ {
+ return getClass().getSimpleName();
+ }
+
+ public Result getDefault()
+ {
+ return Result.ABSTAIN;
+ }
+
+ public abstract Result access(ObjectType object, Object instance);
+
+ public abstract Result authorise(Operation operation, ObjectType object, ObjectProperties properties);
+
+ public boolean isConfigured()
+ {
+ if (_config == null)
+ {
+ return false;
+ }
+
+ for (String key : _config.getElementsProcessed())
+ {
+ if (!_config.getConfig().containsKey(key) && _config.getConfig().subset(key).isEmpty())
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+}
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
new file mode 100644
index 0000000000..7f3b89b46b
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java
@@ -0,0 +1,139 @@
+/*
+ *
+ * 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;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+
+/**
+ * This {@link SecurityPlugin} proxies the authorise calls to a serries of methods, one per {@link Operation}.
+ *
+ * Plugins that extend this class should override the relevant authorise method and implement their own
+ * {@link #setConfiguration(Configuration)} method.
+ */
+public abstract class AbstractProxyPlugin extends AbstractPlugin
+{
+ public Result authoriseConsume(ObjectType object, ObjectProperties properties)
+ {
+ return getDefault();
+ }
+
+ public Result authorisePublish(ObjectType object, ObjectProperties properties)
+ {
+ return getDefault();
+ }
+
+ public Result authoriseCreate(ObjectType object, ObjectProperties properties)
+ {
+ return getDefault();
+ }
+
+ public Result authoriseAccess(ObjectType object, ObjectProperties properties)
+ {
+ return getDefault();
+ }
+
+ public Result authoriseBind(ObjectType object, ObjectProperties properties)
+ {
+ return getDefault();
+ }
+
+ public Result authoriseUnbind(ObjectType object, ObjectProperties properties)
+ {
+ return getDefault();
+ }
+
+ public Result authoriseDelete(ObjectType object, ObjectProperties properties)
+ {
+ return getDefault();
+ }
+
+ public Result authorisePurge(ObjectType object, ObjectProperties properties)
+ {
+ return getDefault();
+ }
+
+ public Result authoriseExecute(ObjectType object, ObjectProperties properties)
+ {
+ return getDefault();
+ }
+
+ public Result authoriseUpdate(ObjectType object, ObjectProperties properties)
+ {
+ return getDefault();
+ }
+
+ public Result accessBroker(Object instance)
+ {
+ return getDefault();
+ }
+
+ public Result accessVirtualhost(Object instance)
+ {
+ return getDefault();
+ }
+
+ @Override
+ public Result access(ObjectType objectType, Object instance)
+ {
+ switch (objectType)
+ {
+ case BROKER:
+ return accessBroker(instance);
+ case VIRTUALHOST:
+ return accessVirtualhost(instance);
+ }
+
+ return getDefault();
+ }
+
+ @Override
+ public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
+ {
+ switch (operation)
+ {
+ case CONSUME:
+ return authoriseConsume(objectType, properties);
+ case PUBLISH:
+ return authorisePublish(objectType, properties);
+ case CREATE:
+ return authoriseCreate(objectType, properties);
+ case ACCESS:
+ return authoriseAccess(objectType, properties);
+ case BIND:
+ return authoriseBind(objectType, properties);
+ case UNBIND:
+ return authoriseUnbind(objectType, properties);
+ case DELETE:
+ return authoriseDelete(objectType, properties);
+ case PURGE:
+ return authorisePurge(objectType, properties);
+ case EXECUTE:
+ return authoriseExecute(objectType, properties);
+ case UPDATE:
+ return authoriseUpdate(objectType, properties);
+ }
+
+ return getDefault();
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/Result.java b/java/broker/src/main/java/org/apache/qpid/server/security/Result.java
new file mode 100644
index 0000000000..f79721799e
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/Result.java
@@ -0,0 +1,46 @@
+/*
+ * 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;
+
+/**
+ * The result of a security plugin decision, normally {@link #ALLOWED} or {@link #DENIED}.
+ */
+public enum Result
+{
+ /**
+ * The request is allowed.
+ */
+ ALLOWED,
+
+ /**
+ * The request is denied.
+ */
+ DENIED,
+
+ /**
+ * Indicates that a plugin does not handle a particular type of request.
+ */
+ ABSTAIN,
+
+ /**
+ * A plugin instance cannot make a decision on a request it is able to handle,
+ * and another instance of the plugin should be checked.
+ */
+ DEFER;
+} \ No newline at end of file
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
new file mode 100755
index 0000000000..035b7fa854
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
@@ -0,0 +1,384 @@
+/*
+ * 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;
+
+import static org.apache.qpid.server.security.access.ObjectType.*;
+import static org.apache.qpid.server.security.access.Operation.*;
+
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Map.Entry;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.plugins.PluginManager;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.Operation;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+
+/**
+ * The security manager contains references to all loaded {@link SecurityPlugin}s and delegates security decisions to them based
+ * on virtual host name. The plugins can be external <em>OSGi</em> .jar files that export the required classes or just internal
+ * objects for simpler plugins.
+ *
+ * @see SecurityPlugin
+ */
+public class SecurityManager
+{
+ private static final Logger _logger = Logger.getLogger(SecurityManager.class);
+
+ /** Container for the {@link Principal} that is using to this thread. */
+ private static final ThreadLocal<Principal> _principal = new ThreadLocal<Principal>();
+
+ private PluginManager _pluginManager;
+ private Map<String, SecurityPluginFactory> _pluginFactories = new HashMap<String, SecurityPluginFactory>();
+ private Map<String, SecurityPlugin> _globalPlugins = new HashMap<String, SecurityPlugin>();
+ private Map<String, SecurityPlugin> _hostPlugins = new HashMap<String, SecurityPlugin>();
+
+ public SecurityManager(SecurityManager parent) throws ConfigurationException
+ {
+ _pluginManager = parent._pluginManager;
+ _pluginFactories = parent._pluginFactories;
+
+ // our global plugins are the parent's host plugins
+ _globalPlugins = parent._hostPlugins;
+ }
+
+ public SecurityManager(ConfigurationPlugin configuration, PluginManager manager) throws ConfigurationException
+ {
+ this(configuration, manager, null);
+ }
+
+ public SecurityManager(ConfigurationPlugin configuration, PluginManager manager, SecurityPluginFactory plugin) throws ConfigurationException
+ {
+ _pluginManager = manager;
+ if (manager == null) // No plugin manager, no plugins
+ {
+ return;
+ }
+
+ _pluginFactories = _pluginManager.getSecurityPlugins();
+ if (plugin != null)
+ {
+ _pluginFactories.put(plugin.getPluginName(), plugin);
+ }
+
+ configureHostPlugins(configuration);
+ }
+
+ public static Principal getThreadPrincipal()
+ {
+ return _principal.get();
+ }
+
+ public static void setThreadPrincipal(Principal principal)
+ {
+ _principal.set(principal);
+ }
+
+ public static void setThreadPrincipal(String authId)
+ {
+ setThreadPrincipal(new UsernamePrincipal(authId));
+ }
+
+ public void configureHostPlugins(ConfigurationPlugin hostConfig) throws ConfigurationException
+ {
+ _hostPlugins = configurePlugins(hostConfig);
+ }
+
+ public void configureGlobalPlugins(ConfigurationPlugin configuration) throws ConfigurationException
+ {
+ _globalPlugins = configurePlugins(configuration);
+ }
+
+ public Map<String, SecurityPlugin> configurePlugins(ConfigurationPlugin hostConfig) throws ConfigurationException
+ {
+ Map<String, SecurityPlugin> plugins = new HashMap<String, SecurityPlugin>();
+ for (SecurityPluginFactory<?> factory : _pluginFactories.values())
+ {
+ SecurityPlugin plugin = factory.newInstance(hostConfig);
+ if (plugin.isConfigured())
+ {
+ plugins.put(factory.getPluginName(), plugin);
+ }
+ }
+ return plugins;
+ }
+
+ public void addHostPlugin(SecurityPlugin plugin)
+ {
+ _hostPlugins.put(plugin.getClass().getName(), plugin);
+ }
+
+ public static Logger getLogger()
+ {
+ return _logger;
+ }
+
+ private abstract class AccessCheck
+ {
+ abstract Result allowed(SecurityPlugin plugin);
+ }
+
+ private boolean checkAllPlugins(AccessCheck checker)
+ {
+ HashMap<String, SecurityPlugin> remainingPlugins = new HashMap<String, SecurityPlugin>(_globalPlugins);
+
+ for (Entry<String, SecurityPlugin> hostEntry : _hostPlugins.entrySet())
+ {
+ // Create set of global only plugins
+ SecurityPlugin globalPlugin = remainingPlugins.get(hostEntry.getKey());
+ if (globalPlugin != null)
+ {
+ remainingPlugins.remove(hostEntry.getKey());
+ }
+
+ Result host = checker.allowed(hostEntry.getValue());
+
+ if (host == Result.DENIED)
+ {
+ // Something vetoed the access, we're done
+ return false;
+ }
+
+ // host allow overrides global allow, so only check global on abstain or defer
+ if (host != Result.ALLOWED)
+ {
+ if (globalPlugin == null)
+ {
+ if (host == Result.DEFER)
+ {
+ host = hostEntry.getValue().getDefault();
+ }
+ if (host == Result.DENIED)
+ {
+ return false;
+ }
+ }
+ else
+ {
+ Result global = checker.allowed(globalPlugin);
+ if (global == Result.DEFER)
+ {
+ global = globalPlugin.getDefault();
+ }
+ if (global == Result.ABSTAIN && host == Result.DEFER)
+ {
+ global = hostEntry.getValue().getDefault();
+ }
+ if (global == Result.DENIED)
+ {
+ return false;
+ }
+ }
+ }
+ }
+
+ for (SecurityPlugin plugin : remainingPlugins.values())
+ {
+ Result remaining = checker.allowed(plugin);
+ if (remaining == Result.DEFER)
+ {
+ remaining = plugin.getDefault();
+ }
+ if (remaining == Result.DENIED)
+ {
+ return false;
+ }
+ }
+
+ // getting here means either allowed or abstained from all plugins
+ return true;
+ }
+
+ public boolean authoriseBind(final Exchange exch, final AMQQueue queue, final AMQShortString routingKey)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.authorise(BIND, EXCHANGE, new ObjectProperties(exch, queue, routingKey));
+ }
+ });
+ }
+
+ // 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)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ ObjectProperties properties = new ObjectProperties();
+ properties.setName(methodName);
+ if (componentName != null)
+ {
+ // Only set the property if there is a component name
+ properties.put(ObjectProperties.Property.COMPONENT, componentName);
+ }
+ return plugin.authorise(operation, METHOD, properties);
+ }
+ });
+ }
+
+ // TODO not implemented yet, awaiting consensus
+ public boolean accessBroker(final AMQProtocolSession session)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.access(BROKER, session);
+ }
+ });
+ }
+
+ public boolean accessVirtualhost(final String vhostname, final String remoteAddress)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.access(VIRTUALHOST, remoteAddress);
+ }
+ });
+ }
+
+ public boolean authoriseConsume(final AMQQueue queue)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.authorise(CONSUME, QUEUE, new ObjectProperties(queue));
+ }
+ });
+ }
+
+ 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)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.authorise(CREATE, EXCHANGE, new ObjectProperties(autoDelete, durable, exchangeName,
+ internal, nowait, passive, exchangeType));
+ }
+ });
+ }
+
+ public boolean authoriseCreateQueue(final Boolean autoDelete, final Boolean durable, final Boolean exclusive,
+ final Boolean nowait, final Boolean passive, final AMQShortString queueName, final String owner)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.authorise(CREATE, QUEUE, new ObjectProperties(autoDelete, durable, exclusive, nowait, passive, queueName, owner));
+ }
+ });
+ }
+
+ public boolean authoriseDelete(final AMQQueue queue)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.authorise(DELETE, QUEUE, new ObjectProperties(queue));
+ }
+ });
+ }
+
+ public boolean authoriseDelete(final Exchange exchange)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.authorise(DELETE, EXCHANGE, new ObjectProperties(exchange.getName()));
+ }
+ });
+ }
+
+ public boolean authorisePublish(final boolean immediate, final String routingKey, final String exchangeName)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.authorise(PUBLISH, EXCHANGE, new ObjectProperties(exchangeName, routingKey, immediate));
+ }
+ });
+ }
+
+ public boolean authorisePurge(final AMQQueue queue)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.authorise(PURGE, QUEUE, new ObjectProperties(queue));
+ }
+ });
+ }
+
+ public boolean authoriseUnbind(final Exchange exch, final AMQShortString routingKey, final AMQQueue queue)
+ {
+ return checkAllPlugins(new AccessCheck()
+ {
+ Result allowed(SecurityPlugin plugin)
+ {
+ return plugin.authorise(UNBIND, EXCHANGE, new ObjectProperties(exch, queue, routingKey));
+ }
+ });
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPlugin.java
new file mode 100644
index 0000000000..c3c06bf206
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPlugin.java
@@ -0,0 +1,47 @@
+/*
+ * 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;
+
+import org.apache.qpid.server.plugins.Plugin;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+
+/**
+ * The two methods, {@link #access(ObjectType, Object)} and {@link #authorise(Operation, ObjectType, ObjectProperties)},
+ * return the {@link Result} of the security decision, which may be to {@link Result#ABSTAIN} if no decision is made
+ * by this plugin.
+ */
+public interface SecurityPlugin extends Plugin
+{
+ /**
+ * Default result for {@link #access(ObjectType, Object)} or {@link #authorise(Operation, ObjectType, ObjectProperties)}.
+ */
+ Result getDefault();
+
+ /**
+ * Authorise access granted to an object instance.
+ */
+ Result access(ObjectType objectType, Object instance);
+
+ /**
+ * Authorise an operation on an object defined by a set of properties.
+ */
+ Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties);
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java
new file mode 100644
index 0000000000..789bdd0073
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java
@@ -0,0 +1,54 @@
+package org.apache.qpid.server.security;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.osgi.framework.BundleActivator;
+import org.osgi.framework.BundleContext;
+
+/**
+ * An OSGi {@link BundleActivator} that loads a {@link SecurityPluginFactory}.
+ */
+public abstract class SecurityPluginActivator implements BundleActivator
+{
+ private static final Logger _logger = Logger.getLogger(SecurityPluginActivator.class);
+
+ private SecurityPluginFactory _factory;
+ private ConfigurationPluginFactory _config;
+ private BundleContext _ctx;
+ private String _bundleName;
+
+ /** Implement this to return the factory this plugin activates. */
+ public abstract SecurityPluginFactory getFactory();
+
+ /** Implement this to return the factory this plugin activates. */
+ public abstract ConfigurationPluginFactory getConfigurationFactory();
+
+ /**
+ * @see org.osgi.framework.BundleActivator#start(org.osgi.framework.BundleContext)
+ */
+ public void start(BundleContext ctx) throws Exception
+ {
+ _ctx = ctx;
+ _factory = getFactory();
+ _config = getConfigurationFactory();
+ _bundleName = ctx.getBundle().getSymbolicName();
+
+ // register the service
+ _logger.info("Registering security plugin: " + _bundleName);
+ _ctx.registerService(SecurityPluginFactory.class.getName(), _factory, null);
+ _ctx.registerService(ConfigurationPluginFactory.class.getName(), _config, null);
+ }
+
+ /**
+ * @see org.osgi.framework.BundleActivator#stop(org.osgi.framework.BundleContext)
+ */
+ public void stop(BundleContext context) throws Exception
+ {
+ _logger.info("Stopping security plugin: " + _bundleName);
+
+ // null object references
+ _factory = null;
+ _config = null;
+ _ctx = null;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/AuthorizationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java
index 895ed52222..fe81cba282 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/AuthorizationManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginFactory.java
@@ -1,6 +1,5 @@
-package org.apache.qpid.server.security.access;
/*
- *
+ *
* 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
@@ -8,20 +7,24 @@ package org.apache.qpid.server.security.access;
* 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;
+import org.apache.qpid.server.plugins.PluginFactory;
-public class AuthorizationManager
+/**
+ * The factory that generates instances of security plugins. Usually implemented as a static member class in the plugin itself.
+ */
+public interface SecurityPluginFactory<S extends SecurityPlugin> extends PluginFactory<S>
{
-
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java
deleted file mode 100644
index 7d6ae285c5..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLManager.java
+++ /dev/null
@@ -1,323 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *
- */
-package org.apache.qpid.server.security.access;
-
-import java.util.Collection;
-import java.util.HashMap;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.Map;
-import java.util.Map.Entry;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.SecurityConfiguration;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.plugins.PluginManager;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.security.access.ACLPlugin.AuthzResult;
-import org.apache.qpid.server.security.PrincipalHolder;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-
-public class ACLManager
-{
- private static final Logger _logger = Logger.getLogger(ACLManager.class);
- private PluginManager _pluginManager;
- private Map<String, ACLPluginFactory> _allSecurityPlugins = new HashMap<String, ACLPluginFactory>();
- private Map<String, ACLPlugin> _globalPlugins = new HashMap<String, ACLPlugin>();
- private Map<String, ACLPlugin> _hostPlugins = new HashMap<String, ACLPlugin>();
-
- public ACLManager(SecurityConfiguration configuration, PluginManager manager) throws ConfigurationException
- {
- this(configuration, manager, null);
- }
-
- public ACLManager(SecurityConfiguration configuration, PluginManager manager, ACLPluginFactory securityPlugin) throws ConfigurationException
- {
- _pluginManager = manager;
-
- if (manager == null) // No plugin manager, no plugins
- {
- return;
- }
-
- _allSecurityPlugins = _pluginManager.getSecurityPlugins();
- if (securityPlugin != null)
- {
- _allSecurityPlugins.put(securityPlugin.getClass().getName(), securityPlugin);
- }
-
- configureGlobalPlugins(configuration);
- }
-
- public void configureHostPlugins(SecurityConfiguration hostConfig) throws ConfigurationException
- {
- _hostPlugins = configurePlugins(hostConfig);
- }
-
- public void configureGlobalPlugins(SecurityConfiguration configuration) throws ConfigurationException
- {
- _globalPlugins = configurePlugins(configuration);
- }
-
- public Map<String, ACLPlugin> configurePlugins(SecurityConfiguration hostConfig) throws ConfigurationException
- {
- Configuration securityConfig = hostConfig.getConfiguration();
- Map<String, ACLPlugin> plugins = new HashMap<String, ACLPlugin>();
- Iterator keys = securityConfig.getKeys();
- Collection<String> handledTags = new HashSet();
- while (keys.hasNext())
- {
- // Splitting the string is necessary here because of the way that getKeys() returns only
- // bottom level children
- String tag = ((String) keys.next()).split("\\.", 2)[0];
- if (!handledTags.contains(tag))
- {
- for (ACLPluginFactory plugin : _allSecurityPlugins.values())
- {
- if (plugin.supportsTag(tag))
- {
- _logger.info("Plugin handling security section "+tag+" is "+plugin);
- handledTags.add(tag);
- plugins.put(plugin.getClass().getName(), plugin.newInstance(securityConfig));
- }
- }
- }
- if (!handledTags.contains(tag))
- {
- _logger.warn("No plugin handled security section "+tag);
- }
- }
- return plugins;
- }
-
- public static Logger getLogger()
- {
- return _logger;
- }
-
- private abstract class AccessCheck
- {
- abstract AuthzResult allowed(ACLPlugin plugin);
- }
-
- private boolean checkAllPlugins(AccessCheck checker)
- {
- AuthzResult result = AuthzResult.ABSTAIN;
- HashMap<String, ACLPlugin> remainingPlugins = new HashMap<String, ACLPlugin>();
- remainingPlugins.putAll(_globalPlugins);
- for (Entry<String, ACLPlugin> plugin : _hostPlugins.entrySet())
- {
- result = checker.allowed(plugin.getValue());
- if (result == AuthzResult.DENIED)
- {
- // Something vetoed the access, we're done
- return false;
- }
- else if (result == AuthzResult.ALLOWED)
- {
- // Remove plugin from global check list since
- // host allow overrides global allow
- remainingPlugins.remove(plugin.getKey());
- }
- }
-
- for (ACLPlugin plugin : remainingPlugins.values())
- {
- result = checker.allowed(plugin);
- if (result == AuthzResult.DENIED)
- {
- return false;
- }
- }
- return true;
- }
-
- public boolean authoriseBind(final PrincipalHolder session, final Exchange exch, final AMQQueue queue,
- final AMQShortString routingKey)
- {
- return checkAllPlugins(new AccessCheck()
- {
-
- @Override
- AuthzResult allowed(ACLPlugin plugin)
- {
- return plugin.authoriseBind(session, exch, queue, routingKey);
- }
-
- });
- }
-
- public boolean authoriseConnect(final PrincipalHolder session, final VirtualHost virtualHost)
- {
- return checkAllPlugins(new AccessCheck()
- {
-
- @Override
- AuthzResult allowed(ACLPlugin plugin)
- {
- return plugin.authoriseConnect(session, virtualHost);
- }
-
- });
- }
-
- public boolean authoriseConsume(final PrincipalHolder session, final boolean noAck, final AMQQueue queue)
- {
- return checkAllPlugins(new AccessCheck()
- {
-
- @Override
- AuthzResult allowed(ACLPlugin plugin)
- {
- return plugin.authoriseConsume(session, noAck, queue);
- }
-
- });
- }
-
- public boolean authoriseConsume(final PrincipalHolder session, final boolean exclusive, final boolean noAck,
- final boolean noLocal, final boolean nowait, final AMQQueue queue)
- {
- return checkAllPlugins(new AccessCheck()
- {
-
- @Override
- AuthzResult allowed(ACLPlugin plugin)
- {
- return plugin.authoriseConsume(session, exclusive, noAck, noLocal, nowait, queue);
- }
-
- });
- }
-
- public boolean authoriseCreateExchange(final PrincipalHolder session, final boolean autoDelete,
- final boolean durable, final AMQShortString exchangeName, final boolean internal, final boolean nowait,
- final boolean passive, final AMQShortString exchangeType)
- {
- return checkAllPlugins(new AccessCheck()
- {
-
- @Override
- AuthzResult allowed(ACLPlugin plugin)
- {
- return plugin.authoriseCreateExchange(session, autoDelete, durable, exchangeName, internal, nowait,
- passive, exchangeType);
- }
-
- });
- }
-
- public boolean authoriseCreateQueue(final PrincipalHolder session, final boolean autoDelete,
- final boolean durable, final boolean exclusive, final boolean nowait, final boolean passive,
- final AMQShortString queue)
- {
- return checkAllPlugins(new AccessCheck()
- {
-
- @Override
- AuthzResult allowed(ACLPlugin plugin)
- {
- return plugin.authoriseCreateQueue(session, autoDelete, durable, exclusive, nowait, passive, queue);
- }
-
- });
- }
-
- public boolean authoriseDelete(final PrincipalHolder session, final AMQQueue queue)
- {
- return checkAllPlugins(new AccessCheck()
- {
-
- @Override
- AuthzResult allowed(ACLPlugin plugin)
- {
- return plugin.authoriseDelete(session, queue);
- }
-
- });
- }
-
- public boolean authoriseDelete(final PrincipalHolder session, final Exchange exchange)
- {
- return checkAllPlugins(new AccessCheck()
- {
-
- @Override
- AuthzResult allowed(ACLPlugin plugin)
- {
- return plugin.authoriseDelete(session, exchange);
- }
-
- });
- }
-
- public boolean authorisePublish(final PrincipalHolder session, final boolean immediate, final boolean mandatory,
- final AMQShortString routingKey, final Exchange e)
- {
- return checkAllPlugins(new AccessCheck()
- {
-
- @Override
- AuthzResult allowed(ACLPlugin plugin)
- {
- return plugin.authorisePublish(session, immediate, mandatory, routingKey, e);
- }
-
- });
- }
-
- public boolean authorisePurge(final PrincipalHolder session, final AMQQueue queue)
- {
- return checkAllPlugins(new AccessCheck()
- {
-
- @Override
- AuthzResult allowed(ACLPlugin plugin)
- {
- return plugin.authorisePurge(session, queue);
- }
-
- });
- }
-
- public boolean authoriseUnbind(final PrincipalHolder session, final Exchange exch,
- final AMQShortString routingKey, final AMQQueue queue)
- {
- return checkAllPlugins(new AccessCheck()
- {
-
- @Override
- AuthzResult allowed(ACLPlugin plugin)
- {
- return plugin.authoriseUnbind(session, exch, routingKey, queue);
- }
-
- });
- }
-
- public void addHostPlugin(ACLPlugin aclPlugin)
- {
- _hostPlugins.put(aclPlugin.getClass().getName(), aclPlugin);
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java
deleted file mode 100644
index cf8a3fede9..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPlugin.java
+++ /dev/null
@@ -1,70 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *
- */
-package org.apache.qpid.server.security.access;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.security.PrincipalHolder;
-
-public interface ACLPlugin
-{
- public enum AuthzResult
- {
- ALLOWED,
- DENIED,
- ABSTAIN
- }
-
- void setConfiguration(Configuration config) throws ConfigurationException;
-
- // These return true if the plugin thinks the action should be allowed, and false if not.
-
- AuthzResult authoriseBind(PrincipalHolder session, Exchange exch, AMQQueue queue, AMQShortString routingKey);
-
- AuthzResult authoriseCreateExchange(PrincipalHolder session, boolean autoDelete, boolean durable,
- AMQShortString exchangeName, boolean internal, boolean nowait, boolean passive, AMQShortString exchangeType);
-
- AuthzResult authoriseCreateQueue(PrincipalHolder session, boolean autoDelete, boolean durable, boolean exclusive,
- boolean nowait, boolean passive, AMQShortString queue);
-
- AuthzResult authoriseConnect(PrincipalHolder session, VirtualHost virtualHost);
-
- AuthzResult authoriseConsume(PrincipalHolder session, boolean noAck, AMQQueue queue);
-
- AuthzResult authoriseConsume(PrincipalHolder session, boolean exclusive, boolean noAck, boolean noLocal,
- boolean nowait, AMQQueue queue);
-
- AuthzResult authoriseDelete(PrincipalHolder session, AMQQueue queue);
-
- AuthzResult authoriseDelete(PrincipalHolder session, Exchange exchange);
-
- AuthzResult authorisePublish(PrincipalHolder session, boolean immediate, boolean mandatory,
- AMQShortString routingKey, Exchange e);
-
- AuthzResult authorisePurge(PrincipalHolder session, AMQQueue queue);
-
- AuthzResult authoriseUnbind(PrincipalHolder session, Exchange exch, AMQShortString routingKey, AMQQueue queue);
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java
deleted file mode 100644
index 256f093477..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/ACLPluginFactory.java
+++ /dev/null
@@ -1,33 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.security.access;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-
-public interface ACLPluginFactory
-{
-
- public boolean supportsTag(String name);
-
- public ACLPlugin newInstance(Configuration config) throws ConfigurationException;
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java
deleted file mode 100644
index d722da4ae0..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java
+++ /dev/null
@@ -1,65 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *
- */
-package org.apache.qpid.server.security.access;
-
-public class AccessResult
-{
- public enum AccessStatus
- {
- GRANTED, REFUSED
- }
-
- private String _authorizer;
- private AccessStatus _status;
-
- public AccessResult(ACLPlugin authorizer, AccessStatus status)
- {
- _status = status;
- _authorizer = authorizer.getClass().getSimpleName();
- }
-
- public void setAuthorizer(ACLPlugin authorizer)
- {
- _authorizer += authorizer.getClass().getSimpleName();
- }
-
- public String getAuthorizer()
- {
- return _authorizer;
- }
-
- public void setStatus(AccessStatus status)
- {
- _status = status;
- }
-
- public AccessStatus getStatus()
- {
- return _status;
- }
-
- public void addAuthorizer(ACLPlugin accessManager)
- {
- _authorizer = accessManager.getClass().getSimpleName() + "->" + _authorizer;
- }
-
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessRights.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessRights.java
deleted file mode 100644
index 1b79a5a0e0..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessRights.java
+++ /dev/null
@@ -1,63 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *
- */
-package org.apache.qpid.server.security.access;
-
-public class AccessRights
-{
- public enum Rights
- {
- ANY,
- READ,
- WRITE,
- READWRITE
- }
-
- Rights _right;
-
- public AccessRights(Rights right)
- {
- _right = right;
- }
-
- public boolean allows(Rights rights)
- {
- switch (_right)
- {
- case ANY:
- return (rights.equals(Rights.WRITE)
- || rights.equals(Rights.READ)
- || rights.equals(Rights.READWRITE)
- || rights.equals(Rights.ANY));
- case READ:
- return rights.equals(Rights.READ) || rights.equals(Rights.ANY);
- case WRITE:
- return rights.equals(Rights.WRITE) || rights.equals(Rights.ANY);
- case READWRITE:
- return true;
- }
- return false;
- }
-
- public Rights getRights()
- {
- return _right;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
new file mode 100644
index 0000000000..af47ed6bf9
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
@@ -0,0 +1,315 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.queue.AMQQueue;
+
+/**
+ * An set of properties for an access control v2 rule {@link ObjectType}.
+ *
+ * The {@link #matches(ObjectProperties)} method is intended to be used when determining precedence of rules, and
+ * {@link #equals(Object)} and {@link #hashCode()} are intended for use in maps. This is due to the wildcard matching
+ * described above.
+ */
+public class ObjectProperties extends HashMap<ObjectProperties.Property, String>
+{
+ /** serialVersionUID */
+ private static final long serialVersionUID = -1356019341374170495L;
+
+ public static final String STAR= "*";
+
+ public static final ObjectProperties EMPTY = new ObjectProperties();
+
+ public enum Property
+ {
+ ROUTING_KEY,
+ NAME,
+ QUEUE_NAME,
+ OWNER,
+ TYPE,
+ ALTERNATE,
+ IMMEDIATE,
+ INTERNAL,
+ NO_WAIT,
+ NO_LOCAL,
+ NO_ACK,
+ PASSIVE,
+ DURABLE,
+ EXCLUSIVE,
+ TEMPORARY,
+ AUTO_DELETE,
+ COMPONENT,
+ PACKAGE,
+ CLASS;
+
+ public static Property parse(String text)
+ {
+ for (Property property : values())
+ {
+ if (property.getName().equalsIgnoreCase(text))
+ {
+ return property;
+ }
+ }
+ throw new IllegalArgumentException("Not a valid property: " + text);
+ }
+
+ public String getName()
+ {
+ return StringUtils.remove(name(), '_').toLowerCase();
+ }
+
+ public static List<String> getPropertyNames()
+ {
+ List<String> properties = new ArrayList<String>();
+ for (Property property : values())
+ {
+ properties.add(property.getName());
+ }
+ return properties;
+ }
+ }
+
+ public static List<String> getAllPropertyNames()
+ {
+ List<String> properties = new ArrayList<String>();
+ for (Property property : Property.values())
+ {
+ properties.add(StringUtils.remove(property.name(), '_').toLowerCase());
+ }
+ return properties;
+ }
+
+ public ObjectProperties()
+ {
+ super();
+ }
+
+ public ObjectProperties(ObjectProperties copy)
+ {
+ super();
+
+ putAll(copy);
+ }
+
+ public ObjectProperties(String name)
+ {
+ super();
+
+ setName(name);
+ }
+
+
+ public ObjectProperties(AMQShortString name)
+ {
+ super();
+
+ setName(name);
+ }
+
+ public ObjectProperties(AMQQueue queue)
+ {
+ super();
+
+ setName(queue.getName());
+
+ put(Property.AUTO_DELETE, queue.isAutoDelete());
+ put(Property.TEMPORARY, queue.isAutoDelete());
+ put(Property.DURABLE, queue.isDurable());
+ put(Property.EXCLUSIVE, queue.isExclusive());
+ if (queue.getAlternateExchange() != null)
+ {
+ put(Property.ALTERNATE, queue.getAlternateExchange().getName());
+ }
+ if (queue.getOwner() != null)
+ {
+ put(Property.OWNER, queue.getOwner());
+ }
+ else if (queue.getPrincipalHolder() != null)
+ {
+ put(Property.OWNER, queue.getPrincipalHolder().getPrincipal().getName());
+ }
+ }
+
+ public ObjectProperties(Exchange exch, AMQQueue queue, AMQShortString routingKey)
+ {
+ this(queue);
+
+ setName(exch.getName());
+
+ put(Property.QUEUE_NAME, queue.getName());
+ put(Property.ROUTING_KEY, routingKey);
+ }
+
+ public ObjectProperties(Exchange exch, AMQShortString routingKey)
+ {
+ this(exch.getName(), routingKey.asString());
+ }
+
+ public ObjectProperties(String exchangeName, String routingKey, Boolean immediate)
+ {
+ this(exchangeName, routingKey);
+
+ put(Property.IMMEDIATE, immediate);
+ }
+
+ public ObjectProperties(String exchangeName, String routingKey)
+ {
+ super();
+
+ setName(exchangeName);
+
+ put(Property.ROUTING_KEY, routingKey);
+ }
+
+ public ObjectProperties(Boolean autoDelete, Boolean durable, AMQShortString exchangeName,
+ Boolean internal, Boolean nowait, Boolean passive, AMQShortString exchangeType)
+ {
+ super();
+
+ setName(exchangeName);
+
+ put(Property.AUTO_DELETE, autoDelete);
+ put(Property.TEMPORARY, autoDelete);
+ put(Property.DURABLE, durable);
+ put(Property.INTERNAL, internal);
+ put(Property.NO_WAIT, nowait);
+ put(Property.PASSIVE, passive);
+ put(Property.TYPE, exchangeType);
+ }
+
+ public ObjectProperties(Boolean autoDelete, Boolean durable, Boolean exclusive, Boolean nowait, Boolean passive,
+ AMQShortString queueName, String owner)
+ {
+ super();
+
+ setName(queueName);
+
+ put(Property.AUTO_DELETE, autoDelete);
+ put(Property.TEMPORARY, autoDelete);
+ put(Property.DURABLE, durable);
+ put(Property.EXCLUSIVE, exclusive);
+ put(Property.NO_WAIT, nowait);
+ put(Property.PASSIVE, passive);
+ put(Property.OWNER, owner);
+ }
+
+ public ObjectProperties(Boolean exclusive, Boolean noAck, Boolean noLocal, Boolean nowait, AMQQueue queue)
+ {
+ this(queue);
+
+ put(Property.NO_LOCAL, noLocal);
+ put(Property.NO_ACK, noAck);
+ put(Property.EXCLUSIVE, exclusive);
+ put(Property.NO_WAIT, nowait);
+ }
+
+ public List<String> getPropertyNames()
+ {
+ List<String> properties = new ArrayList<String>();
+ for (Property property : keySet())
+ {
+ properties.add(property.getName());
+ }
+ return properties;
+ }
+
+ public Boolean isSet(Property key)
+ {
+ return containsKey(key) && Boolean.valueOf(get(key));
+ }
+
+ public String getName()
+ {
+ return get(Property.NAME);
+ }
+
+ public void setName(String name)
+ {
+ put(Property.NAME, name);
+ }
+
+ public void setName(AMQShortString name)
+ {
+ put(Property.NAME, name);
+ }
+
+ public String put(Property key, AMQShortString value)
+ {
+ return put(key, value == null ? "" : value.asString());
+ }
+
+ @Override
+ public String put(Property key, String value)
+ {
+ return super.put(key, value == null ? "" : value.trim());
+ }
+
+ public void put(Property key, Boolean value)
+ {
+ if (value != null)
+ {
+ super.put(key, Boolean.toString(value));
+ }
+ }
+
+ public boolean matches(ObjectProperties properties)
+ {
+ if (properties.keySet().isEmpty())
+ {
+ return true;
+ }
+
+ if (!keySet().containsAll(properties.keySet()))
+ {
+ return false;
+ }
+
+ for (Property key : properties.keySet())
+ {
+ String ruleValue = properties.get(key);
+ String thisValue = get(key);
+
+ if (!valueMatches(thisValue, ruleValue))
+ {
+ return false;
+ }
+ }
+
+ return true;
+ }
+
+ private boolean valueMatches(String thisValue, String ruleValue)
+ {
+ return (StringUtils.isEmpty(ruleValue)
+ || StringUtils.equals(thisValue, ruleValue))
+ || ruleValue.equals(STAR)
+ || (ruleValue.endsWith(STAR)
+ && thisValue != null
+ && thisValue.length() > ruleValue.length()
+ && thisValue.startsWith(ruleValue.substring(0, ruleValue.length() - 2)));
+ }
+}
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
new file mode 100644
index 0000000000..66ef388976
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
@@ -0,0 +1,90 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access;
+
+import static org.apache.qpid.server.security.access.Operation.*;
+
+import java.util.EnumSet;
+import java.util.Set;
+
+/**
+ * An enumeration of all possible object types that can form part of an access control v2 rule.
+ *
+ * Each object type is valid only for a certain set of {@link Operation}s, which are passed as a list to
+ * the constructor, and can be checked using the {@link #isAllowed(Operation)} method.
+ */
+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),
+ BROKER(ACCESS),
+ LINK, // Not allowed in the Java broker
+ ROUTE, // Not allowed in the Java broker
+ METHOD(Operation.ALL, ACCESS, UPDATE, EXECUTE),
+ OBJECT(ACCESS);
+
+ private EnumSet<Operation> _actions;
+
+ private ObjectType()
+ {
+ _actions = EnumSet.noneOf(Operation.class);
+ }
+
+ private ObjectType(Operation operation)
+ {
+ if (operation == Operation.ALL)
+ {
+ _actions = EnumSet.allOf(Operation.class);
+ }
+ else
+ {
+ _actions = EnumSet.of(operation);
+ }
+ }
+
+ private ObjectType(Operation first, Operation...rest)
+ {
+ _actions = EnumSet.of(first, rest);
+ }
+
+ public Set<Operation> getActions()
+ {
+ return _actions;
+ }
+
+ public boolean isAllowed(Operation operation)
+ {
+ return _actions.contains(operation);
+ }
+
+ public static ObjectType parse(String text)
+ {
+ for (ObjectType object : values())
+ {
+ if (object.name().equalsIgnoreCase(text))
+ {
+ return object;
+ }
+ }
+ throw new IllegalArgumentException("Not a valid object type: " + text);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/Operation.java
index f51cf24caa..7077257d01 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/Operation.java
@@ -14,14 +14,36 @@
* "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.
- *
- *
+ * under the License.
*/
package org.apache.qpid.server.security.access;
-public interface Accessable
+/**
+ * An enumeration of all possible actions that can form part of an access control v2 rule.
+ */
+public enum Operation
{
- void setAccessableName(String name);
- String getAccessableName();
-}
+ ALL,
+ CONSUME,
+ PUBLISH,
+ CREATE,
+ ACCESS,
+ BIND,
+ UNBIND,
+ DELETE,
+ PURGE,
+ UPDATE,
+ EXECUTE;
+
+ public static Operation parse(String text)
+ {
+ for (Operation operation : values())
+ {
+ if (operation.name().equalsIgnoreCase(text))
+ {
+ return operation;
+ }
+ }
+ throw new IllegalArgumentException("Not a valid operation: " + text);
+ }
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/Permission.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/Permission.java
index b65b0cdc6c..49b3a331f9 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/Permission.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/Permission.java
@@ -20,19 +20,28 @@
*/
package org.apache.qpid.server.security.access;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.commons.lang.StringUtils;
+/**
+ * An enumeration of all possible permissions that can be applied to an access control v2 rule.
+ */
public enum Permission
{
- CONSUME,
- PUBLISH,
- CREATEQUEUE,
- CREATEEXCHANGE,
- ACCESS,
- BIND,
- UNBIND,
- DELETE,
- PURGE
-}
+ ALLOW,
+ ALLOW_LOG,
+ DENY,
+ DENY_LOG;
+
+ public static Permission parse(String text)
+ {
+
+ for (Permission permission : values())
+ {
+ if (permission.name().equalsIgnoreCase(StringUtils.replaceChars(text, '-', '_')))
+ {
+ return permission;
+ }
+ }
+ throw new IllegalArgumentException("Not a valid permission: " + text);
+ }
+} \ No newline at end of file
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/VirtualHostAccess.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/VirtualHostAccess.java
deleted file mode 100644
index 13151a66b8..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/VirtualHostAccess.java
+++ /dev/null
@@ -1,68 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *
- */
-package org.apache.qpid.server.security.access;
-
-public class VirtualHostAccess
-{
- private String _vhost;
- private AccessRights _rights;
-
- public VirtualHostAccess(String vhostaccess)
- {
- //format <vhost>(<rights>)
- int hostend = vhostaccess.indexOf('(');
-
- if (hostend == -1)
- {
- throw new IllegalArgumentException("VirtualHostAccess format string contains no access _rights");
- }
-
- _vhost = vhostaccess.substring(0, hostend);
-
- String rights = vhostaccess.substring(hostend);
-
- if (rights.indexOf('r') != -1)
- {
- if (rights.indexOf('w') != -1)
- {
- _rights = new AccessRights(AccessRights.Rights.READWRITE);
- }
- else
- {
- _rights = new AccessRights(AccessRights.Rights.READ);
- }
- }
- else if (rights.indexOf('w') != -1)
- {
- _rights = new AccessRights(AccessRights.Rights.WRITE);
- }
- }
-
- public AccessRights getAccessRights()
- {
- return _rights;
- }
-
- public String getVirtualHost()
- {
- return _vhost;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AbstractACLPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AbstractACLPlugin.java
deleted file mode 100644
index f99f3a60f7..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AbstractACLPlugin.java
+++ /dev/null
@@ -1,99 +0,0 @@
-/*
- *
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- */
-package org.apache.qpid.server.security.access.plugins;
-
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.security.access.ACLPlugin;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.security.PrincipalHolder;
-
-/**
- * This ACLPlugin abstains from all votes. Useful if your plugin only cares about a few operations.
- */
-public abstract class AbstractACLPlugin implements ACLPlugin
-{
-
- private static final AuthzResult DEFAULT_ANSWER = AuthzResult.ABSTAIN;
-
- public AuthzResult authoriseBind(PrincipalHolder session, Exchange exch, AMQQueue queue,
- AMQShortString routingKey)
- {
- return DEFAULT_ANSWER;
- }
-
- public AuthzResult authoriseConnect(PrincipalHolder session, VirtualHost virtualHost)
- {
- return DEFAULT_ANSWER;
- }
-
- public AuthzResult authoriseConsume(PrincipalHolder session, boolean noAck, AMQQueue queue)
- {
- return DEFAULT_ANSWER;
- }
-
- public AuthzResult authoriseConsume(PrincipalHolder session, boolean exclusive, boolean noAck, boolean noLocal,
- boolean nowait, AMQQueue queue)
- {
- return DEFAULT_ANSWER;
- }
-
- public AuthzResult authoriseCreateExchange(PrincipalHolder session, boolean autoDelete, boolean durable,
- AMQShortString exchangeName, boolean internal, boolean nowait, boolean passive, AMQShortString exchangeType)
- {
- // TODO Auto-generated method stub
- return null;
- }
-
- public AuthzResult authoriseCreateQueue(PrincipalHolder session, boolean autoDelete, boolean durable,
- boolean exclusive, boolean nowait, boolean passive, AMQShortString queue)
- {
- return DEFAULT_ANSWER;
- }
-
- public AuthzResult authoriseDelete(PrincipalHolder session, AMQQueue queue)
- {
- return DEFAULT_ANSWER;
- }
-
- public AuthzResult authoriseDelete(PrincipalHolder session, Exchange exchange)
- {
- return DEFAULT_ANSWER;
- }
-
- public AuthzResult authorisePublish(PrincipalHolder session, boolean immediate, boolean mandatory,
- AMQShortString routingKey, Exchange e)
- {
- return DEFAULT_ANSWER;
- }
-
- public AuthzResult authorisePurge(PrincipalHolder session, AMQQueue queue)
- {
- return DEFAULT_ANSWER;
- }
-
- public AuthzResult authoriseUnbind(PrincipalHolder session, Exchange exch, AMQShortString routingKey,
- AMQQueue queue)
- {
- return DEFAULT_ANSWER;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java
index 4af178574b..82963bbadc 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java
@@ -15,40 +15,72 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- *
- *
*/
package org.apache.qpid.server.security.access.plugins;
+import java.util.Arrays;
+import java.util.List;
+
import org.apache.commons.configuration.Configuration;
-import org.apache.qpid.server.security.access.ACLPlugin;
-import org.apache.qpid.server.security.access.ACLPluginFactory;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.security.Result;
+import org.apache.qpid.server.security.SecurityPluginFactory;
-public class AllowAll extends BasicACLPlugin
+/** Always allow. */
+public class AllowAll extends BasicPlugin
{
+ public static class AllowAllConfiguration extends ConfigurationPlugin {
+ public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
+ {
+ public List<String> getParentPaths()
+ {
+ return Arrays.asList("security", "virtualhosts.virtualhost.security");
+ }
- public static final ACLPluginFactory FACTORY = new ACLPluginFactory()
+ public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
+ {
+ ConfigurationPlugin instance = new AllowAllConfiguration();
+ instance.setConfiguration(path, config);
+ return instance;
+ }
+ };
+
+ public String[] getElementsProcessed()
+ {
+ return new String[] { "allow-all" };
+ }
+ }
+
+ public static final SecurityPluginFactory<AllowAll> FACTORY = new SecurityPluginFactory<AllowAll>()
{
- public boolean supportsTag(String name)
+ public AllowAll newInstance(ConfigurationPlugin config) throws ConfigurationException
{
- return false;
+ AllowAll plugin = new AllowAll(config);
+ plugin.configure();
+ return plugin;
}
- public ACLPlugin newInstance(Configuration config)
+ public String getPluginName()
{
- return new AllowAll();
+ return AllowAll.class.getName();
}
- };
- public String getPluginName()
- {
- return this.getClass().getSimpleName();
+ public Class<AllowAll> getPluginClass()
+ {
+ return AllowAll.class;
+ }
+ };
+
+ @Override
+ public Result getDefault()
+ {
+ return Result.ALLOWED;
}
- @Override
- protected AuthzResult getResult()
+ public AllowAll(ConfigurationPlugin config)
{
- // Always allow
- return AuthzResult.ALLOWED;
+ _config = config.getConfiguration(AllowAllConfiguration.class);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicACLPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicACLPlugin.java
deleted file mode 100644
index d0df354d78..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicACLPlugin.java
+++ /dev/null
@@ -1,110 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *
- */
-package org.apache.qpid.server.security.access.plugins;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.security.access.ACLPlugin;
-import org.apache.qpid.server.security.PrincipalHolder;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-
-public abstract class BasicACLPlugin implements ACLPlugin
-{
-
- // Returns true or false if the plugin should authorise or deny the request
- protected abstract AuthzResult getResult();
-
- public AuthzResult authoriseBind(PrincipalHolder session, Exchange exch,
- AMQQueue queue, AMQShortString routingKey)
- {
- return getResult();
- }
-
- public AuthzResult authoriseConnect(PrincipalHolder session,
- VirtualHost virtualHost)
- {
- return getResult();
- }
-
- public AuthzResult authoriseConsume(PrincipalHolder session, boolean noAck,
- AMQQueue queue)
- {
- return getResult();
- }
-
- public AuthzResult authoriseConsume(PrincipalHolder session,
- boolean exclusive, boolean noAck, boolean noLocal, boolean nowait,
- AMQQueue queue)
- {
- return getResult();
- }
-
- public AuthzResult authoriseCreateExchange(PrincipalHolder session,
- boolean autoDelete, boolean durable, AMQShortString exchangeName,
- boolean internal, boolean nowait, boolean passive,
- AMQShortString exchangeType)
- {
- return getResult();
- }
-
- public AuthzResult authoriseCreateQueue(PrincipalHolder session,
- boolean autoDelete, boolean durable, boolean exclusive,
- boolean nowait, boolean passive, AMQShortString queue)
- {
- return getResult();
- }
-
- public AuthzResult authoriseDelete(PrincipalHolder session, AMQQueue queue)
- {
- return getResult();
- }
-
- public AuthzResult authoriseDelete(PrincipalHolder session, Exchange exchange)
- {
- return getResult();
- }
-
- public AuthzResult authorisePublish(PrincipalHolder session,
- boolean immediate, boolean mandatory, AMQShortString routingKey,
- Exchange e)
- {
- return getResult();
- }
-
- public AuthzResult authorisePurge(PrincipalHolder session, AMQQueue queue)
- {
- return getResult();
- }
-
- public AuthzResult authoriseUnbind(PrincipalHolder session, Exchange exch,
- AMQShortString routingKey, AMQQueue queue)
- {
- return getResult();
- }
-
- public void setConfiguration(Configuration config)
- {
- // no-op
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java
new file mode 100644
index 0000000000..5fc1ef7795
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java
@@ -0,0 +1,51 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.security.access.plugins;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.security.AbstractPlugin;
+import org.apache.qpid.server.security.Result;
+import org.apache.qpid.server.security.SecurityPlugin;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.ObjectType;
+import org.apache.qpid.server.security.access.Operation;
+
+/**
+ * This {@link SecurityPlugin} simply abstains from all authorisation requests and ignores configuration.
+ */
+public class BasicPlugin extends AbstractPlugin
+{
+ public Result access(ObjectType objectType, Object instance)
+ {
+ return getDefault();
+ }
+
+ public Result authorise(Operation operation, ObjectType objectType, ObjectProperties properties)
+ {
+ return getDefault();
+ }
+
+ @Override
+ public void configure() throws ConfigurationException
+ {
+ // Not used
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.java
index 77d3c4bcdf..24af215a0c 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.java
@@ -15,61 +15,72 @@
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
- *
- *
*/
package org.apache.qpid.server.security.access.plugins;
+import java.util.Arrays;
+import java.util.List;
+
import org.apache.commons.configuration.Configuration;
-import org.apache.qpid.AMQConnectionException;
-import org.apache.qpid.framing.AMQMethodBody;
-import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.security.access.ACLManager;
-import org.apache.qpid.server.security.access.ACLPlugin;
-import org.apache.qpid.server.security.access.ACLPluginFactory;
-import org.apache.qpid.server.security.access.AccessResult;
-import org.apache.qpid.server.security.access.Permission;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.security.Result;
+import org.apache.qpid.server.security.SecurityPluginFactory;
-public class DenyAll extends BasicACLPlugin
+/** Always Deny. */
+public class DenyAll extends BasicPlugin
{
- public static final ACLPluginFactory FACTORY = new ACLPluginFactory()
- {
- public boolean supportsTag(String name)
+ public static class DenyAllConfiguration extends ConfigurationPlugin {
+ public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
{
- return false;
- }
+ public List<String> getParentPaths()
+ {
+ return Arrays.asList("security", "virtualhosts.virtualhost.security");
+ }
- public ACLPlugin newInstance(Configuration config)
+ public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
+ {
+ ConfigurationPlugin instance = new DenyAllConfiguration();
+ instance.setConfiguration(path, config);
+ return instance;
+ }
+ };
+
+ public String[] getElementsProcessed()
{
- return new DenyAll();
+ return new String[] { "deny-all" };
}
- };
+ }
- public AccessResult authorise(AMQProtocolSession session,
- Permission permission, AMQMethodBody body, Object... parameters)
- throws AMQConnectionException
+ public static final SecurityPluginFactory<DenyAll> FACTORY = new SecurityPluginFactory<DenyAll>()
{
+ public DenyAll newInstance(ConfigurationPlugin config) throws ConfigurationException
+ {
+ DenyAll plugin = new DenyAll(config);
+ plugin.configure();
+ return plugin;
+ }
- if (ACLManager.getLogger().isInfoEnabled())
+ public String getPluginName()
{
- ACLManager.getLogger().info(
- "Denying user:" + session.getPrincipal());
+ return DenyAll.class.getName();
}
- throw body.getConnectionException(AMQConstant.ACCESS_REFUSED,
- "DenyAll Plugin");
- }
- public String getPluginName()
- {
- return getClass().getSimpleName();
+ public Class<DenyAll> getPluginClass()
+ {
+ return DenyAll.class;
+ }
+ };
+
+ @Override
+ public Result getDefault()
+ {
+ return Result.DENIED;
}
- @Override
- protected AuthzResult getResult()
+ public DenyAll(ConfigurationPlugin config) throws ConfigurationException
{
- // Always deny
- return AuthzResult.DENIED;
+ _config = config.getConfiguration(DenyAllConfiguration.class);
}
-
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java
new file mode 100644
index 0000000000..2c0994b52a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java
@@ -0,0 +1,81 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+package org.apache.qpid.server.security.access.plugins;
+
+import java.util.Arrays;
+import java.util.List;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.VirtualHostConfiguration;
+import org.apache.qpid.server.configuration.ServerConfiguration;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.security.SecurityPluginFactory;
+
+/** Always Abstain. */
+public class LegacyAccess extends BasicPlugin
+{
+ public static class LegacyAccessConfiguration extends ConfigurationPlugin {
+ public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
+ {
+ public List<String> getParentPaths()
+ {
+ return Arrays.asList("security", "virtualhosts.virtualhost.security");
+ }
+
+ public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
+ {
+ ConfigurationPlugin instance = new LegacyAccessConfiguration();
+ instance.setConfiguration(path, config);
+ return instance;
+ }
+ };
+
+ public String[] getElementsProcessed()
+ {
+ return new String[] { "principal-databases", "access", "msg-auth", "false", "jmx" };
+ }
+ }
+
+ public static final SecurityPluginFactory<LegacyAccess> FACTORY = new SecurityPluginFactory<LegacyAccess>()
+ {
+ public LegacyAccess newInstance(ConfigurationPlugin config) throws ConfigurationException
+ {
+ LegacyAccess plugin = new LegacyAccess(config);
+ plugin.configure();
+ return plugin;
+ }
+
+ public String getPluginName()
+ {
+ return LegacyAccess.class.getName();
+ }
+
+ public Class<LegacyAccess> getPluginClass()
+ {
+ return LegacyAccess.class;
+ }
+ };
+
+ public LegacyAccess(ConfigurationPlugin config) throws ConfigurationException
+ {
+ _config = config.getConfiguration(LegacyAccessConfiguration.class);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccessPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccessPlugin.java
deleted file mode 100644
index fc1bc048d4..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccessPlugin.java
+++ /dev/null
@@ -1,71 +0,0 @@
-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements. See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership. The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License. You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied. See the License for the
- * specific language governing permissions and limitations
- * under the License.
- *
- *
- */
-package org.apache.qpid.server.security.access.plugins;
-
-import java.util.Collection;
-import java.util.HashSet;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.qpid.server.security.access.ACLPlugin;
-import org.apache.qpid.server.security.access.ACLPluginFactory;
-
-/**
- *
- * Used to suppress warnings in legacy config files that have things in <security> which aren't handled by a plugin directly.
- *
- */
-public class LegacyAccessPlugin extends BasicACLPlugin
-{
- public static final ACLPluginFactory FACTORY = new ACLPluginFactory()
- {
- private Collection maskedTags = new HashSet<String>();
- {
- maskedTags.add("principal-databases");
- maskedTags.add("access");
- maskedTags.add("msg-auth");
- maskedTags.add("false");
- maskedTags.add("jmx");
- }
-
- public boolean supportsTag(String name)
- {
- return maskedTags .contains(name);
- }
-
- public ACLPlugin newInstance(Configuration config)
- {
- return new LegacyAccessPlugin();
- }
- };
-
- public String getPluginName()
- {
- return getClass().getSimpleName();
- }
-
- @Override
- protected AuthzResult getResult()
- {
- // Always abstain
- return AuthzResult.ABSTAIN;
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
index 3f846b9dd0..62967ef7eb 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
@@ -20,8 +20,6 @@
*/
package org.apache.qpid.server.security.auth;
-import javax.security.sasl.SaslException;
-
public class AuthenticationResult
{
public enum AuthenticationStatus
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
index 889ce815f4..6ca9c8e762 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
@@ -21,7 +21,7 @@
package org.apache.qpid.server.security.auth.database;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.security.access.management.AMQUserManagementMBean;
+import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexInitialiser;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
index 2619a69cfd..5cebb7d2d8 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
@@ -38,7 +38,7 @@ import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
-import org.apache.qpid.server.security.access.management.AMQUserManagementMBean;
+import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean;
import org.apache.qpid.AMQException;
import javax.management.JMException;
@@ -51,7 +51,7 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
public ConfigurationFilePrincipalDatabaseManager(ServerConfiguration _configuration) throws Exception
{
- _logger.info("Initialising PrincipleDatabase authentication manager");
+ _logger.info("Initialising PrincipalDatabase authentication manager");
_databases = initialisePrincipalDatabases(_configuration);
}
@@ -171,16 +171,13 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
AMQUserManagementMBean _mbean = new AMQUserManagementMBean();
List<String> principalDBs = config.getManagementPrincipalDBs();
-
- if (principalDBs.size() == 0)
+ if (principalDBs.isEmpty())
{
throw new ConfigurationException("No principal-database specified for jmx security");
}
String databaseName = principalDBs.get(0);
-
PrincipalDatabase database = getDatabases().get(databaseName);
-
if (database == null)
{
throw new ConfigurationException("Principal-database '" + databaseName + "' not found");
@@ -189,14 +186,13 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
_mbean.setPrincipalDatabase(database);
List<String> jmxaccesslist = config.getManagementAccessList();
-
- if (jmxaccesslist.size() == 0)
+ if (jmxaccesslist.isEmpty())
{
throw new ConfigurationException("No access control files specified for jmx security");
}
String jmxaccesssFile = null;
-
+
try
{
jmxaccesssFile = PropertyUtils.replaceProperties(jmxaccesslist.get(0));
@@ -205,7 +201,7 @@ public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatab
{
throw new ConfigurationException("Unable to parse access control filename '" + jmxaccesssFile + "'");
}
-
+
try
{
_mbean.setAccessFile(jmxaccesssFile);
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
index 5a2965cb32..153b8c25db 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/access/management/AMQUserManagementMBean.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
@@ -18,51 +18,50 @@
*
*
*/
-package org.apache.qpid.server.security.access.management;
+package org.apache.qpid.server.security.auth.management;
-import org.apache.qpid.management.common.mbeans.UserManagement;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.management.MBeanInvocationHandlerImpl;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
-import org.apache.qpid.util.FileUtils;
-import org.apache.log4j.Logger;
-import org.apache.commons.configuration.ConfigurationException;
-
-import javax.management.JMException;
-import javax.management.remote.JMXPrincipal;
-import javax.management.openmbean.TabularData;
-import javax.management.openmbean.TabularDataSupport;
-import javax.management.openmbean.TabularType;
-import javax.management.openmbean.SimpleType;
-import javax.management.openmbean.CompositeType;
-import javax.management.openmbean.OpenType;
-import javax.management.openmbean.OpenDataException;
-import javax.management.openmbean.CompositeData;
-import javax.management.openmbean.CompositeDataSupport;
-import javax.security.auth.login.AccountNotFoundException;
-import javax.security.auth.Subject;
import java.io.File;
import java.io.FileInputStream;
-import java.io.IOException;
import java.io.FileOutputStream;
-import java.util.Properties;
-import java.util.List;
+import java.io.IOException;
+import java.security.AccessControlContext;
+import java.security.AccessController;
+import java.security.Principal;
import java.util.Enumeration;
+import java.util.List;
+import java.util.Properties;
import java.util.Random;
import java.util.Set;
import java.util.concurrent.locks.ReentrantLock;
-import java.security.Principal;
-import java.security.AccessControlContext;
-import java.security.AccessController;
+
+import javax.management.JMException;
+import javax.management.openmbean.CompositeData;
+import javax.management.openmbean.CompositeDataSupport;
+import javax.management.openmbean.CompositeType;
+import javax.management.openmbean.OpenDataException;
+import javax.management.openmbean.OpenType;
+import javax.management.openmbean.SimpleType;
+import javax.management.openmbean.TabularData;
+import javax.management.openmbean.TabularDataSupport;
+import javax.management.openmbean.TabularType;
+import javax.management.remote.JMXPrincipal;
+import javax.security.auth.Subject;
+import javax.security.auth.login.AccountNotFoundException;
+
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+import org.apache.qpid.management.common.mbeans.UserManagement;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
+import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.management.MBeanInvocationHandlerImpl;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
/** MBean class for AMQUserManagementMBean. It implements all the management features exposed for managing users. */
@MBeanDescription("User Management Interface")
public class AMQUserManagementMBean extends AMQManagedObject implements UserManagement
{
-
private static final Logger _logger = Logger.getLogger(AMQUserManagementMBean.class);
private PrincipalDatabase _principalDatabase;
@@ -533,6 +532,8 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana
{
_logger.debug("Setting Access Rights:" + accessRights);
_accessRights = accessRights;
- MBeanInvocationHandlerImpl.setAccessRights(_accessRights);
+
+ // TODO check where this is used
+ // MBeanInvocationHandlerImpl.setAccessRights(_accessRights);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
index d34d0c4d27..bc771162fd 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
@@ -20,13 +20,12 @@
*/
package org.apache.qpid.server.security.auth.manager;
-import org.apache.qpid.common.Closeable;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.security.auth.AuthenticationResult;
-
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
+import org.apache.qpid.common.Closeable;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+
public interface AuthenticationManager extends Closeable
{
String getMechanisms();
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
index 98c060599a..2a967f02af 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -64,7 +64,7 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
public PrincipalDatabaseAuthenticationManager(String name, VirtualHostConfiguration hostConfig) throws Exception
{
_logger.info("Initialising " + (name == null ? "Default" : "'" + name + "'")
- + " PrincipleDatabase authentication manager.");
+ + " PrincipalDatabase authentication manager.");
// Fixme This should be done per Vhost but allowing global hack isn't right but ...
// required as authentication is done before Vhost selection
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
index 77040e896c..0cbbccb3b8 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
@@ -99,7 +99,7 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
}
catch (AccountNotFoundException e)
{
- throw new SecurityException(INVALID_CREDENTIALS);
+ throw new SecurityException(INVALID_CREDENTIALS); // XXX
}
if (authenticated)
diff --git a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
index 6850724b10..6cc5e7b019 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/state/AMQStateManager.java
@@ -62,6 +62,7 @@ import org.apache.qpid.server.handler.TxCommitHandler;
import org.apache.qpid.server.handler.TxRollbackHandler;
import org.apache.qpid.server.handler.TxSelectHandler;
import org.apache.qpid.server.protocol.AMQProtocolSession;
+import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
/**
@@ -258,6 +259,7 @@ public class AMQStateManager implements AMQMethodListener
public AMQProtocolSession getProtocolSession()
{
+ SecurityManager.setThreadPrincipal(_protocolSession.getPrincipal());
return _protocolSession;
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactoryImpl.java b/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactoryImpl.java
index 5badbad642..1bba2529c6 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactoryImpl.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/subscription/SubscriptionFactoryImpl.java
@@ -20,25 +20,17 @@
*/
package org.apache.qpid.server.subscription;
-import org.apache.qpid.server.protocol.AMQProtocolSession;
-import org.apache.qpid.server.flow.FlowCreditManager;
-import org.apache.qpid.server.subscription.Subscription;
-import org.apache.qpid.server.subscription.SubscriptionFactory;
-import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.AMQException;
+import org.apache.qpid.common.AMQPFilterTypes;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.AMQException;
import org.apache.qpid.protocol.AMQConstant;
-import org.apache.qpid.common.AMQPFilterTypes;
+import org.apache.qpid.server.AMQChannel;
+import org.apache.qpid.server.flow.FlowCreditManager;
+import org.apache.qpid.server.protocol.AMQProtocolSession;
public class SubscriptionFactoryImpl implements SubscriptionFactory
{
-
- /* private SubscriptionFactoryImpl()
- {
-
- }*/
-
public Subscription createSubscription(int channelId, AMQProtocolSession protocolSession,
AMQShortString consumerTag, boolean acks, FieldTable filters,
boolean noLocal, FlowCreditManager creditManager) throws AMQException
diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
index a56951cf5c..38040ecfce 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerConnectionDelegate.java
@@ -22,6 +22,7 @@ package org.apache.qpid.server.transport;
import org.apache.qpid.transport.*;
+import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.registry.IApplicationRegistry;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -29,16 +30,13 @@ import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslException;
import java.util.*;
-
public class ServerConnectionDelegate extends ServerDelegate
{
-
private String _localFQDN;
private final IApplicationRegistry _appRegistry;
- public ServerConnectionDelegate(IApplicationRegistry appRegistry,
- String localFQDN)
+ public ServerConnectionDelegate(IApplicationRegistry appRegistry, String localFQDN)
{
this(new HashMap<String,Object>(Collections.singletonMap("qpid.federation_tag",appRegistry.getBroker().getFederationTag())), Collections.singletonList((Object)"en_US"), appRegistry, localFQDN);
}
@@ -50,6 +48,7 @@ public class ServerConnectionDelegate extends ServerDelegate
String localFQDN)
{
super(properties, parseToList(appRegistry.getAuthenticationManager().getMechanisms()), locales);
+
_appRegistry = appRegistry;
_localFQDN = localFQDN;
}
@@ -65,9 +64,9 @@ public class ServerConnectionDelegate extends ServerDelegate
return list;
}
- @Override public ServerSession getSession(Connection conn, SessionAttach atc)
+ @Override
+ public ServerSession getSession(Connection conn, SessionAttach atc)
{
-
SessionDelegate serverSessionDelegate = new ServerSessionDelegate(_appRegistry);
ServerSession ssn = new ServerSession(conn, serverSessionDelegate, new Binary(atc.getName()), 0);
@@ -75,9 +74,6 @@ public class ServerConnectionDelegate extends ServerDelegate
return ssn;
}
-
-
-
@Override
protected SaslServer createSaslServer(String mechanism) throws SaslException
{
@@ -85,11 +81,10 @@ public class ServerConnectionDelegate extends ServerDelegate
}
-
@Override public void connectionOpen(Connection conn, ConnectionOpen open)
{
ServerConnection sconn = (ServerConnection) conn;
-
+
VirtualHost vhost;
String vhostName;
if(open.hasVirtualHost())
@@ -102,19 +97,27 @@ public class ServerConnectionDelegate extends ServerDelegate
}
vhost = _appRegistry.getVirtualHostRegistry().getVirtualHost(vhostName);
+ SecurityManager.setThreadPrincipal(conn.getAuthorizationID());
+
if(vhost != null)
{
sconn.setVirtualHost(vhost);
- sconn.invoke(new ConnectionOpenOk(Collections.emptyList()));
-
- sconn.setState(Connection.State.OPEN);
+ if (!vhost.getSecurityManager().accessVirtualhost(vhostName, sconn.getConfig().getAddress()))
+ {
+ sconn.invoke(new ConnectionClose(ConnectionCloseCode.CONNECTION_FORCED, "Permission denied '"+vhostName+"'"));
+ sconn.setState(Connection.State.CLOSING);
+ }
+ else
+ {
+ sconn.invoke(new ConnectionOpenOk(Collections.emptyList()));
+ sconn.setState(Connection.State.OPEN);
+ }
}
else
{
- sconn.invoke(new ConnectionClose(ConnectionCloseCode.INVALID_PATH, "Unknown virtualhost '" + vhostName + "'"));
+ sconn.invoke(new ConnectionClose(ConnectionCloseCode.INVALID_PATH, "Unknown virtualhost '"+vhostName+"'"));
sconn.setState(Connection.State.CLOSING);
}
-
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
index 8a16867ad8..bc7ba085fc 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSession.java
@@ -157,7 +157,6 @@ public class ServerSession extends Session implements PrincipalHolder, SessionCo
catch (AMQException e)
{
// TODO
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
throw new RuntimeException(e);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
index 541810d2fe..73ec7f1231 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/transport/ServerSessionDelegate.java
@@ -20,31 +20,78 @@
*/
package org.apache.qpid.server.transport;
-import org.apache.qpid.transport.*;
-import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.virtualhost.VirtualHost;
-import org.apache.qpid.server.exchange.*;
-import org.apache.qpid.server.queue.QueueRegistry;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Map;
+
+import org.apache.qpid.AMQException;
+import org.apache.qpid.AMQSecurityException;
+import org.apache.qpid.AMQUnknownExchangeType;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.exchange.ExchangeFactory;
+import org.apache.qpid.server.exchange.ExchangeInUseException;
+import org.apache.qpid.server.exchange.ExchangeRegistry;
+import org.apache.qpid.server.exchange.HeadersExchange;
+import org.apache.qpid.server.flow.FlowCreditManager_0_10;
+import org.apache.qpid.server.flow.WindowCreditManager;
+import org.apache.qpid.server.message.MessageMetaData_0_10;
+import org.apache.qpid.server.message.MessageTransferMessage;
+import org.apache.qpid.server.protocol.AMQSessionModel;
import org.apache.qpid.server.queue.AMQQueue;
import org.apache.qpid.server.queue.AMQQueueFactory;
import org.apache.qpid.server.queue.BaseQueue;
-import org.apache.qpid.server.message.MessageTransferMessage;
-import org.apache.qpid.server.message.MessageMetaData_0_10;
-import org.apache.qpid.server.subscription.Subscription_0_10;
-import org.apache.qpid.server.flow.*;
+import org.apache.qpid.server.queue.QueueRegistry;
+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.store.DurableConfigurationStore;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.StoredMessage;
-import org.apache.qpid.server.store.DurableConfigurationStore;
-import org.apache.qpid.server.protocol.AMQSessionModel;
-import org.apache.qpid.AMQException;
-import org.apache.qpid.AMQUnknownExchangeType;
-import org.apache.qpid.framing.*;
-
-import java.util.ArrayList;
-import java.util.Collection;
-import java.util.Map;
-import java.nio.ByteBuffer;
+import org.apache.qpid.server.subscription.Subscription_0_10;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.transport.Acquired;
+import org.apache.qpid.transport.DeliveryProperties;
+import org.apache.qpid.transport.ExchangeBind;
+import org.apache.qpid.transport.ExchangeBound;
+import org.apache.qpid.transport.ExchangeBoundResult;
+import org.apache.qpid.transport.ExchangeDeclare;
+import org.apache.qpid.transport.ExchangeDelete;
+import org.apache.qpid.transport.ExchangeQuery;
+import org.apache.qpid.transport.ExchangeQueryResult;
+import org.apache.qpid.transport.ExchangeUnbind;
+import org.apache.qpid.transport.ExecutionErrorCode;
+import org.apache.qpid.transport.ExecutionException;
+import org.apache.qpid.transport.MessageAccept;
+import org.apache.qpid.transport.MessageAcceptMode;
+import org.apache.qpid.transport.MessageAcquire;
+import org.apache.qpid.transport.MessageAcquireMode;
+import org.apache.qpid.transport.MessageCancel;
+import org.apache.qpid.transport.MessageFlow;
+import org.apache.qpid.transport.MessageFlowMode;
+import org.apache.qpid.transport.MessageFlush;
+import org.apache.qpid.transport.MessageReject;
+import org.apache.qpid.transport.MessageRejectCode;
+import org.apache.qpid.transport.MessageRelease;
+import org.apache.qpid.transport.MessageResume;
+import org.apache.qpid.transport.MessageSetFlowMode;
+import org.apache.qpid.transport.MessageStop;
+import org.apache.qpid.transport.MessageSubscribe;
+import org.apache.qpid.transport.MessageTransfer;
+import org.apache.qpid.transport.Method;
+import org.apache.qpid.transport.QueueDeclare;
+import org.apache.qpid.transport.QueueDelete;
+import org.apache.qpid.transport.QueuePurge;
+import org.apache.qpid.transport.QueueQuery;
+import org.apache.qpid.transport.QueueQueryResult;
+import org.apache.qpid.transport.RangeSet;
+import org.apache.qpid.transport.Session;
+import org.apache.qpid.transport.SessionDelegate;
+import org.apache.qpid.transport.TxCommit;
+import org.apache.qpid.transport.TxRollback;
+import org.apache.qpid.transport.TxSelect;
public class ServerSessionDelegate extends SessionDelegate
{
@@ -58,6 +105,8 @@ public class ServerSessionDelegate extends SessionDelegate
@Override
public void command(Session session, Method method)
{
+ SecurityManager.setThreadPrincipal(session.getConnection().getAuthorizationID());
+
super.command(session, method);
if (method.isSync())
{
@@ -317,7 +366,6 @@ public class ServerSessionDelegate extends SessionDelegate
catch (AMQException e)
{
//TODO
- e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates.
throw new RuntimeException(e);
}
}
@@ -371,19 +419,7 @@ public class ServerSessionDelegate extends SessionDelegate
}
else
{
- if (!virtualHost.getAccessManager().authoriseCreateExchange((ServerSession)session, method.getAutoDelete(),
- method.getDurable(), new AMQShortString(method.getExchange()), false, false, method.getPassive(),
- new AMQShortString(method.getType())))
- {
-
- ExecutionErrorCode errorCode = ExecutionErrorCode.NOT_ALLOWED;
- String description = "permission denied: exchange-name '" + exchangeName + "'";
-
- exception(session, method, errorCode, description);
-
-
- }
- else if(exchange == null)
+ if (exchange == null)
{
ExchangeRegistry exchangeRegistry = getExchangeRegistry(session);
ExchangeFactory exchangeFactory = virtualHost.getExchangeFactory();
@@ -417,12 +453,18 @@ public class ServerSessionDelegate extends SessionDelegate
{
exception(session, method, ExecutionErrorCode.NOT_FOUND, "Unknown Exchange Type: " + method.getType());
}
+ catch (AMQSecurityException e)
+ {
+ ExecutionErrorCode errorCode = ExecutionErrorCode.NOT_ALLOWED;
+ String description = "Permission denied: exchange-name '" + exchangeName + "'";
+
+ exception(session, method, errorCode, description);
+ }
catch (AMQException e)
{
//TODO
throw new RuntimeException(e);
}
-
}
else
{
@@ -478,47 +520,38 @@ public class ServerSessionDelegate extends SessionDelegate
VirtualHost virtualHost = getVirtualHost(session);
ExchangeRegistry exchangeRegistry = virtualHost.getExchangeRegistry();
- //Perform ACLs
- if (!virtualHost.getAccessManager().authoriseDelete((ServerSession)session,
- exchangeRegistry.getExchange(method.getExchange())))
- {
- exception(session,method, ExecutionErrorCode.NOT_ALLOWED, "Permission denied");
-
- }
- else
+ try
{
+ Exchange exchange = getExchange(session, method.getExchange());
- try
+ if(exchange != null && exchange.hasReferrers())
+ {
+ exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Exchange in use as an alternate exchange");
+ }
+ else
{
- Exchange exchange = getExchange(session, method.getExchange());
+ exchangeRegistry.unregisterExchange(method.getExchange(), method.getIfUnused());
- if(exchange != null && exchange.hasReferrers())
- {
- exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Exchange in use as an alternate exchange");
- }
- else
+ if (exchange.isDurable() && !exchange.isAutoDelete())
{
- exchangeRegistry.unregisterExchange(method.getExchange(), method.getIfUnused());
-
- if (exchange.isDurable() && !exchange.isAutoDelete())
- {
- DurableConfigurationStore store = virtualHost.getDurableConfigurationStore();
- store.removeExchange(exchange);
- }
-
+ DurableConfigurationStore store = virtualHost.getDurableConfigurationStore();
+ store.removeExchange(exchange);
}
}
- catch (ExchangeInUseException e)
- {
- exception(session, method, ExecutionErrorCode.PRECONDITION_FAILED, "Exchange in use");
- }
- catch (AMQException e)
- {
- // TODO
- throw new RuntimeException(e);
- }
}
-
+ catch (ExchangeInUseException e)
+ {
+ exception(session, method, ExecutionErrorCode.PRECONDITION_FAILED, "Exchange in use");
+ }
+ catch (AMQSecurityException e)
+ {
+ exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Permission denied: " + method.getExchange());
+ }
+ catch (AMQException e)
+ {
+ // TODO
+ throw new RuntimeException(e);
+ }
}
@Override
@@ -582,13 +615,6 @@ public class ServerSessionDelegate extends SessionDelegate
{
exception(session, method, ExecutionErrorCode.NOT_FOUND, "Exchange: '" + method.getExchange() + "' not found");
}
- else if (!virtualHost.getAccessManager().authoriseBind((ServerSession)session, exchange,
- queue, new AMQShortString(method.getBindingKey())))
- {
- exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Bind Exchange: '" + method.getExchange()
- + "' to Queue: '" + method.getQueue()
- + "' not allowed");
- }
else if(exchange.getTypeShortString().equals(HeadersExchange.TYPE.getName()) && (!method.hasArguments() || method.getArguments() == null || !method.getArguments().containsKey("x-match")))
{
exception(session, method, ExecutionErrorCode.INTERNAL_ERROR, "Bindings to an exchange of type " + HeadersExchange.TYPE.getName() + " require an x-match header");
@@ -600,8 +626,15 @@ public class ServerSessionDelegate extends SessionDelegate
if (!exchange.isBound(routingKey, fieldTable, queue))
{
- virtualHost.getBindingFactory().addBinding(method.getBindingKey(), queue, exchange, method.getArguments());
-
+ try
+ {
+ virtualHost.getBindingFactory().addBinding(method.getBindingKey(), queue, exchange, method.getArguments());
+ }
+ catch (AMQSecurityException e)
+ {
+ exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Bind Exchange: '" + method.getExchange()
+ + "' to Queue: '" + method.getQueue() + "' not allowed");
+ }
}
else
{
@@ -649,7 +682,14 @@ public class ServerSessionDelegate extends SessionDelegate
}
else
{
- virtualHost.getBindingFactory().removeBinding(method.getBindingKey(), queue, exchange, null);
+ try
+ {
+ virtualHost.getBindingFactory().removeBinding(method.getBindingKey(), queue, exchange, null);
+ }
+ catch (AMQSecurityException e)
+ {
+ exception(session,method, ExecutionErrorCode.NOT_ALLOWED, "Permission denied");
+ }
}
}
@@ -768,25 +808,6 @@ public class ServerSessionDelegate extends SessionDelegate
DurableConfigurationStore store = virtualHost.getDurableConfigurationStore();
String queueName = method.getQueue();
-
- if (!method.getPassive())
- {
- // Perform ACL if request is not passive
-
- if (!virtualHost.getAccessManager().authoriseCreateQueue(((ServerSession)session), method.getAutoDelete(), method.getDurable(),
- method.getExclusive(), false, method.getPassive(), new AMQShortString(queueName)))
- {
- ExecutionErrorCode errorCode = ExecutionErrorCode.NOT_ALLOWED;
- String description = "permission denied: queue-name '" + queueName + "'";
-
- exception(session, method, errorCode, description);
-
- // TODO control flow
- return;
- }
- }
-
-
AMQQueue queue;
QueueRegistry queueRegistry = getQueueRegistry(session);
//TODO: do we need to check that the queue already exists with exactly the same "configuration"?
@@ -879,34 +900,32 @@ public class ServerSessionDelegate extends SessionDelegate
{
final AMQQueue q = queue;
final ServerSession.Task deleteQueueTask = new ServerSession.Task()
- {
-
- public void doTask(ServerSession session)
{
- try
+ public void doTask(ServerSession session)
{
- q.delete();
+ try
+ {
+ q.delete();
+ }
+ catch (AMQException e)
+ {
+ // TODO
+ throw new RuntimeException(e);
+ }
}
- catch (AMQException e)
- {
- throw new RuntimeException(e);
- }
- }
- };
+ };
final ServerSession s = (ServerSession) session;
s.addSessionCloseTask(deleteQueueTask);
queue.addQueueDeleteTask(new AMQQueue.Task()
- {
-
- public void doTask(AMQQueue queue) throws AMQException
{
- s.removeSessionCloseTask(deleteQueueTask);
- }
- });
+ public void doTask(AMQQueue queue) throws AMQException
+ {
+ s.removeSessionCloseTask(deleteQueueTask);
+ }
+ });
}
else if(method.getExclusive())
{
- {
final AMQQueue q = queue;
final ServerSession.Task removeExclusive = new ServerSession.Task()
{
@@ -928,31 +947,34 @@ public class ServerSessionDelegate extends SessionDelegate
}
});
}
- }
+ }
+ catch (AMQSecurityException e)
+ {
+ String description = "Cannot declare queue('" + queueName + "'), permission denied";
+ ExecutionErrorCode errorCode = ExecutionErrorCode.NOT_ALLOWED;
+ exception(session, method, errorCode, description);
}
catch (AMQException e)
{
+ // TODO
throw new RuntimeException(e);
}
}
}
else if (method.getExclusive() && (queue.getPrincipalHolder() != null && !queue.getPrincipalHolder().equals(session)))
{
-
String description = "Cannot declare queue('" + queueName + "'),"
+ " as exclusive queue with same name "
+ "declared on another session";
ExecutionErrorCode errorCode = ExecutionErrorCode.RESOURCE_LOCKED;
-
+
exception(session, method, errorCode, description);
-
+
return;
}
-
}
}
-
protected AMQQueue createQueue(final String queueName,
QueueDeclare body,
VirtualHost virtualHost,
@@ -963,15 +985,14 @@ public class ServerSessionDelegate extends SessionDelegate
String owner = body.getExclusive() ? session.getClientID() : null;
- final AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueName, body.getDurable(), owner, body.getAutoDelete(),
+ final AMQQueue queue = AMQQueueFactory.createAMQQueueImpl(queueName, body.getDurable(), owner, body.getAutoDelete(),
body.getExclusive(), virtualHost, body.getArguments());
-
if (body.getExclusive() && !body.getDurable())
{
final ServerSession.Task deleteQueueTask =
new ServerSession.Task()
- {
+ {
public void doTask(ServerSession session)
{
if (registry.getQueue(queueName) == queue)
@@ -1006,7 +1027,6 @@ public class ServerSessionDelegate extends SessionDelegate
@Override
public void queueDelete(Session session, QueueDelete method)
{
-
String queueName = method.getQueue();
if(queueName == null || queueName.length()==0)
{
@@ -1041,36 +1061,28 @@ public class ServerSessionDelegate extends SessionDelegate
else
{
VirtualHost virtualHost = getVirtualHost(session);
-
- //Perform ACLs
- if (!virtualHost.getAccessManager().authoriseDelete(((ServerSession)session), queue))
- {
- exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Cannot delete queue " + queueName);
- }
- else
+
+ try
{
- try
- {
- int purged = queue.delete();
- if (queue.isDurable() && !queue.isAutoDelete())
- {
- DurableConfigurationStore store = virtualHost.getDurableConfigurationStore();
- store.removeQueue(queue);
- }
-
- }
- catch (AMQException e)
+ queue.delete();
+ if (queue.isDurable() && !queue.isAutoDelete())
{
- //TODO
- throw new RuntimeException(e);
+ DurableConfigurationStore store = virtualHost.getDurableConfigurationStore();
+ store.removeQueue(queue);
}
-
}
-
+ catch (AMQSecurityException e)
+ {
+ exception(session, method, ExecutionErrorCode.NOT_ALLOWED, "Permission denied: " + queueName);
+ }
+ catch (AMQException e)
+ {
+ // TODO
+ throw new RuntimeException(e);
+ }
}
}
}
-
}
@Override
@@ -1080,24 +1092,32 @@ public class ServerSessionDelegate extends SessionDelegate
if(queueName == null || queueName.length()==0)
{
exception(session, method, ExecutionErrorCode.ILLEGAL_ARGUMENT, "No queue name supplied");
-
}
else
{
AMQQueue queue = getQueue(session, queueName);
-
if (queue == null)
{
exception(session, method, ExecutionErrorCode.NOT_FOUND, "No queue " + queueName + " found");
}
else
{
- //TODO
- queue.clearQueue();
+ try
+ {
+ queue.clearQueue();
+ }
+ catch (AMQSecurityException e)
+ {
+ exception(session,method, ExecutionErrorCode.NOT_ALLOWED, "Permission denied: " + queueName);
+ }
+ catch (AMQException e)
+ {
+ // TODO
+ throw new RuntimeException(e);
+ }
}
}
-
}
@Override
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
index 675a6f6a91..98d231a7ea 100755
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostConfigRecoveryHandler.java
@@ -102,7 +102,7 @@ public class VirtualHostConfigRecoveryHandler implements ConfigurationRecoveryHa
if (q == null)
{
- q = AMQQueueFactory.createAMQQueueImpl(queueNameShortString, true, owner == null ? null : new AMQShortString(owner), false, _virtualHost,
+ q = AMQQueueFactory.createAMQQueueImpl(queueNameShortString, true, owner == null ? null : new AMQShortString(owner), false, false, _virtualHost,
arguments);
_virtualHost.getQueueRegistry().registerQueue(q);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
index 44d178602f..d104209e98 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHostImpl.java
@@ -20,16 +20,25 @@
*/
package org.apache.qpid.server.virtualhost;
+import java.util.Collections;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.TimerTask;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+import java.util.concurrent.ScheduledThreadPoolExecutor;
+import java.util.concurrent.TimeUnit;
+
+import javax.management.NotCompliantMBeanException;
+
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
-
import org.apache.qpid.AMQException;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
import org.apache.qpid.server.AMQBrokerManagerMBean;
-import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory;
-import org.apache.qpid.server.virtualhost.plugins.VirtualHostHouseKeepingPlugin;
import org.apache.qpid.server.binding.BindingFactory;
import org.apache.qpid.server.configuration.BrokerConfig;
import org.apache.qpid.server.configuration.ConfigStore;
@@ -58,29 +67,17 @@ import org.apache.qpid.server.queue.DefaultQueueRegistry;
import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.registry.IApplicationRegistry;
-import org.apache.qpid.server.security.access.ACLManager;
-import org.apache.qpid.server.security.access.Accessable;
+import org.apache.qpid.server.security.SecurityManager;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
import org.apache.qpid.server.store.ConfigurationRecoveryHandler;
import org.apache.qpid.server.store.DurableConfigurationStore;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.TransactionLog;
+import org.apache.qpid.server.virtualhost.plugins.VirtualHostPlugin;
+import org.apache.qpid.server.virtualhost.plugins.VirtualHostPluginFactory;
-import javax.management.NotCompliantMBeanException;
-import java.util.Collections;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.TimerTask;
-import java.util.UUID;
-import java.util.Map;
-import java.util.concurrent.BlockingQueue;
-import java.util.concurrent.ConcurrentHashMap;
-import java.util.concurrent.FutureTask;
-import java.util.concurrent.ScheduledThreadPoolExecutor;
-import java.util.concurrent.TimeUnit;
-
-public class VirtualHostImpl implements Accessable, VirtualHost
+public class VirtualHostImpl implements VirtualHost
{
private static final Logger _logger = Logger.getLogger(VirtualHostImpl.class);
@@ -102,7 +99,7 @@ public class VirtualHostImpl implements Accessable, VirtualHost
private AuthenticationManager _authenticationManager;
- private ACLManager _accessManager;
+ private SecurityManager _securityManager;
private final ScheduledThreadPoolExecutor _houseKeepingTasks;
private final IApplicationRegistry _appRegistry;
@@ -117,17 +114,6 @@ public class VirtualHostImpl implements Accessable, VirtualHost
private final ConcurrentHashMap<BrokerLink,BrokerLink> _links = new ConcurrentHashMap<BrokerLink, BrokerLink>();
private static final int HOUSEKEEPING_SHUTDOWN_TIMEOUT = 5;
- public void setAccessableName(String name)
- {
- _logger.warn("Setting Accessable Name for VirualHost is not allowed. ("
- + name + ") ignored remains :" + getAccessableName());
- }
-
- public String getAccessableName()
- {
- return _name;
- }
-
public IConnectionRegistry getConnectionRegistry()
{
return _connectionRegistry;
@@ -140,7 +126,7 @@ public class VirtualHostImpl implements Accessable, VirtualHost
public UUID getId()
{
- return _id; //To change body of implemented methods use File | Settings | File Templates.
+ return _id;
}
public VirtualHostConfigType getConfigType()
@@ -200,12 +186,17 @@ public class VirtualHostImpl implements Accessable, VirtualHost
private VirtualHostImpl(IApplicationRegistry appRegistry, VirtualHostConfiguration hostConfig, MessageStore store) throws Exception
{
+ if (hostConfig == null)
+ {
+ throw new IllegalAccessException("HostConfig and MessageStore cannot be null");
+ }
+
_appRegistry = appRegistry;
- _broker = appRegistry.getBroker();
+ _broker = _appRegistry.getBroker();
_configuration = hostConfig;
- _name = hostConfig.getName();
+ _name = _configuration.getName();
- _id = appRegistry.getConfigStore().createId();
+ _id = _appRegistry.getConfigStore().createId();
CurrentActor.get().message(VirtualHostMessages.VHT_CREATED(_name));
@@ -214,6 +205,9 @@ public class VirtualHostImpl implements Accessable, VirtualHost
throw new IllegalArgumentException("Illegal name (" + _name + ") for virtualhost.");
}
+ _securityManager = new SecurityManager(_appRegistry.getSecurityManager());
+ _securityManager.configureHostPlugins(_configuration);
+
_virtualHostMBean = new VirtualHostMBean();
_connectionRegistry = new ConnectionRegistry();
@@ -223,15 +217,10 @@ public class VirtualHostImpl implements Accessable, VirtualHost
_queueRegistry = new DefaultQueueRegistry(this);
_exchangeFactory = new DefaultExchangeFactory(this);
- _exchangeFactory.initialise(hostConfig);
+ _exchangeFactory.initialise(_configuration);
_exchangeRegistry = new DefaultExchangeRegistry(this);
-
- //Create a temporary RT to store the durable entries from the config file
- // so we can replay them in to the real _RT after it has been loaded.
- /// This should be removed after the _RT has been fully split from the the TL
-
StartupRoutingTable configFileRT = new StartupRoutingTable();
_durableConfigurationStore = configFileRT;
@@ -241,7 +230,7 @@ public class VirtualHostImpl implements Accessable, VirtualHost
_bindingFactory = new BindingFactory(this);
- initialiseModel(hostConfig);
+ initialiseModel(_configuration);
if (store != null)
{
@@ -250,36 +239,10 @@ public class VirtualHostImpl implements Accessable, VirtualHost
}
else
{
- if (hostConfig == null)
- {
- throw new IllegalAccessException("HostConfig and MessageStore cannot be null");
- }
- initialiseMessageStore(hostConfig);
- }
-
-
-
- //Now that the RT has been initialised loop through the persistent queues/exchanges created from the config
- // file and write them in to the new routing Table.
-/* for (StartupRoutingTable.CreateQueueTuple cqt : configFileRT.queue)
- {
- getDurableConfigurationStore().createQueue(cqt.queue, cqt.arguments);
+ initialiseMessageStore(hostConfig);
}
-
- for (Exchange exchange : configFileRT.exchange)
- {
- getDurableConfigurationStore().createExchange(exchange);
- }
-
- for (StartupRoutingTable.CreateBindingTuple cbt : configFileRT.bindings)
- {
- getDurableConfigurationStore().bindQueue(cbt.exchange, cbt.routingKey, cbt.queue, cbt.arguments);
- }*/
-
- _authenticationManager = new PrincipalDatabaseAuthenticationManager(_name, hostConfig);
-
- _accessManager = ApplicationRegistry.getInstance().getAccessManager();
- _accessManager.configureHostPlugins(hostConfig.getSecurityConfiguration());
+
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(_name, _configuration);
_brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean);
_brokerMBean.register();
@@ -330,8 +293,7 @@ public class VirtualHostImpl implements Accessable, VirtualHost
}
Map<String, VirtualHostPluginFactory> plugins =
- ApplicationRegistry.getInstance().
- getPluginManager().getVirtualHostPlugins();
+ ApplicationRegistry.getInstance().getPluginManager().getVirtualHostPlugins();
if (plugins != null)
{
@@ -340,24 +302,6 @@ public class VirtualHostImpl implements Accessable, VirtualHost
try
{
VirtualHostPlugin plugin = plugins.get(pluginName).newInstance(this);
-
- TimeUnit units = TimeUnit.MILLISECONDS;
-
- if (plugin.getTimeUnit() != null)
- {
- try
- {
- units = TimeUnit.valueOf(plugin.getTimeUnit());
- }
- catch (IllegalArgumentException iae)
- {
- _logger.warn("Plugin:" + pluginName +
- " provided an illegal TimeUnit value:"
- + plugin.getTimeUnit());
- // Warn and use default of millseconds
- // Should not occur in a well behaved plugin
- }
- }
_houseKeepingTasks.scheduleAtFixedRate(plugin, plugin.getDelay() / 2,
plugin.getDelay(), plugin.getTimeUnit());
@@ -600,9 +544,9 @@ public class VirtualHostImpl implements Accessable, VirtualHost
return _authenticationManager;
}
- public ACLManager getAccessManager()
+ public SecurityManager getSecurityManager()
{
- return _accessManager;
+ return _securityManager;
}
public void close()
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java
index 59ab7ec673..26eb5bbd7f 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/plugins/VirtualHostPlugin.java
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.server.virtualhost.plugins;
+import java.util.concurrent.TimeUnit;
+
import org.apache.qpid.server.plugins.Plugin;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -39,5 +41,5 @@ public interface VirtualHostPlugin extends Runnable, Plugin
* @see java.util.concurrent.TimeUnit for valid value.
* @return
*/
- public String getTimeUnit();
+ public TimeUnit getTimeUnit();
}