summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Godfrey <rgodfrey@apache.org>2009-10-23 22:32:46 +0000
committerRobert Godfrey <rgodfrey@apache.org>2009-10-23 22:32:46 +0000
commit7fbe6d6762ec250721558e60c75e21d7d6b4c3c3 (patch)
treed0be38fb480ea05560dc256c118469bda2871989
parent38b18d3075169584b27c32e2a49a3a1895497ea4 (diff)
downloadqpid-python-7fbe6d6762ec250721558e60c75e21d7d6b4c3c3.tar.gz
Merged from trunk up to r826646
git-svn-id: https://svn.apache.org/repos/asf/qpid/branches/java-broker-0-10@829268 13f79535-47bb-0310-9956-ffa450edef68
-rwxr-xr-xqpid/java/broker/bin/qpid-server5
-rw-r--r--qpid/java/broker/etc/log4j.xml2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java3
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java77
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java21
-rw-r--r--qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java33
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java17
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java5
-rw-r--r--qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java13
-rw-r--r--qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java58
10 files changed, 210 insertions, 24 deletions
diff --git a/qpid/java/broker/bin/qpid-server b/qpid/java/broker/bin/qpid-server
index 738fc6e084..4e11fd5fe7 100755
--- a/qpid/java/broker/bin/qpid-server
+++ b/qpid/java/broker/bin/qpid-server
@@ -26,11 +26,6 @@ fi
# Set classpath to include Qpid jar with all required jars in manifest
QPID_LIBS=$QPID_HOME/lib/qpid-all.jar:$QPID_HOME/lib/bdbstore-launch.jar
-# Default Log4j to append to its log file
-if [ -z "$QPID_LOG_APPEND" ]; then
- export QPID_LOG_APPEND="true"
-fi
-
# Set other variables used by the qpid-run script before calling
export JAVA=java \
JAVA_VM=-server \
diff --git a/qpid/java/broker/etc/log4j.xml b/qpid/java/broker/etc/log4j.xml
index 4b71772a0e..484b203df8 100644
--- a/qpid/java/broker/etc/log4j.xml
+++ b/qpid/java/broker/etc/log4j.xml
@@ -50,7 +50,7 @@
<appender class="org.apache.log4j.FileAppender" name="FileAppender">
<param name="File" value="${QPID_WORK}/log/${logprefix}qpid${logsuffix}.log"/>
- <param name="Append" value="${QPID_LOG_APPEND}"/>
+ <param name="Append" value="false"/>
<layout class="org.apache.log4j.PatternLayout">
<param name="ConversionPattern" value="%d %-5p [%t] %C{2} (%F:%L) - %m%n"/>
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
index f9641d6eab..1d0ca19e91 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolEngine.java
@@ -679,6 +679,7 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
/** This must be called when the session is _closed in order to free up any resources managed by the session. */
public void closeSession() throws AMQException
{
+ // REMOVE THIS SHOULD NOT BE HERE.
if (CurrentActor.get() == null)
{
CurrentActor.set(_actor);
@@ -694,6 +695,8 @@ public class AMQProtocolEngine implements ProtocolEngine, Managable, AMQProtocol
if (_managedObject != null)
{
_managedObject.unregister();
+ // Ensure we only do this once.
+ _managedObject = null;
}
for (Task task : _taskList)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java
index 42e662b85a..0b95d213f4 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalPermissions.java
@@ -53,6 +53,7 @@ public class PrincipalPermissions
private static final int PUBLISH_EXCHANGES_KEY = 0;
private Map _permissions;
+ private boolean _fullVHostAccess = false;
private String _user;
@@ -82,6 +83,9 @@ public class PrincipalPermissions
{
switch (permission)
{
+ case ACCESS:// Parameters : None
+ grantAccess(permission);
+ break;
case CONSUME: // Parameters : AMQShortString queueName, Boolean Temporary, Boolean ownQueueOnly
grantConsume(permission, parameters);
break;
@@ -98,7 +102,6 @@ public class PrincipalPermissions
break;
/* The other cases just fall through to no-op */
case DELETE:
- case ACCESS: // This is a no-op as the existence of this PrincipalPermission object is scoped per VHost for ACCESS
case BIND: // All the details are currently included in the create setup.
case PURGE:
case UNBIND:
@@ -107,6 +110,11 @@ public class PrincipalPermissions
}
+ private void grantAccess(Permission permission)
+ {
+ _fullVHostAccess = true;
+ }
+
private void grantPublish(Permission permission, Object... parameters) {
Map publishRights = (Map) _permissions.get(permission);
@@ -353,9 +361,8 @@ public class PrincipalPermissions
switch (permission)
{
- case ACCESS:
- return AuthzResult.ALLOWED; // This is here for completeness but the SimpleXML ACLManager never calls it.
- // The existence of this user specific PP can be validated in the map SimpleXML maintains.
+ case ACCESS://No Parameters
+ return AuthzResult.ALLOWED; // The existence of this user-specific PP infers some level of access is authorised
case BIND: // Parameters : QueueBindMethod , Exchange , AMQQueue, AMQShortString routingKey
return authoriseBind(parameters);
case CREATEQUEUE:// Parameters : boolean autodelete, AMQShortString name
@@ -371,12 +378,28 @@ public class PrincipalPermissions
case PURGE:
case UNBIND:
default:
- return AuthzResult.DENIED;
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return AuthzResult.ALLOWED;
+ }
+ else
+ {
+ //SimpleXML ACL does not implement these permissions and should abstain
+ return AuthzResult.ABSTAIN;
+ }
}
}
- private AuthzResult authoriseConsume(Permission permission, Object... parameters) {
+ private AuthzResult authoriseConsume(Permission permission, Object... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return AuthzResult.ALLOWED;
+ }
+
if (parameters.length == 1 && parameters[0] instanceof AMQQueue)
{
AMQQueue queue = ((AMQQueue) parameters[0]);
@@ -435,8 +458,15 @@ public class PrincipalPermissions
return AuthzResult.DENIED;
}
- private AuthzResult authorisePublish(Permission permission, Object... parameters) {
- Map publishRights = (Map) _permissions.get(permission);
+ private AuthzResult authorisePublish(Permission permission, Object... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return AuthzResult.ALLOWED;
+ }
+
+ Map publishRights = (Map) _permissions.get(permission);
if (publishRights == null)
{
@@ -495,7 +525,14 @@ public class PrincipalPermissions
}
}
- private AuthzResult authoriseCreateExchange(Permission permission, Object... parameters) {
+ private AuthzResult authoriseCreateExchange(Permission permission, Object... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return AuthzResult.ALLOWED;
+ }
+
Map rights = (Map) _permissions.get(permission);
AMQShortString exchangeName = (AMQShortString) parameters[0];
@@ -512,8 +549,15 @@ public class PrincipalPermissions
}
}
- private AuthzResult authoriseCreateQueue(Permission permission, Object... parameters) {
- Map createRights = (Map) _permissions.get(permission);
+ private AuthzResult authoriseCreateQueue(Permission permission, Object... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return AuthzResult.ALLOWED;
+ }
+
+ Map createRights = (Map) _permissions.get(permission);
// If there are no create rights then deny request
if (createRights == null)
@@ -550,8 +594,15 @@ public class PrincipalPermissions
}
}
- private AuthzResult authoriseBind(Object... parameters) {
- Exchange exchange = (Exchange) parameters[1];
+ private AuthzResult authoriseBind(Object... parameters)
+ {
+ if(_fullVHostAccess)
+ {
+ //user has been granted full access to the vhost
+ return AuthzResult.ALLOWED;
+ }
+
+ Exchange exchange = (Exchange) parameters[1];
AMQQueue bind_queueName = (AMQQueue) parameters[2];
AMQShortString routingKey = (AMQShortString) parameters[3];
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java
index b02e6b019c..532ff0b7d6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/SimpleXML.java
@@ -77,8 +77,29 @@ public class SimpleXML implements ACLPlugin
processConsume(config);
processCreate(config);
+
+ processAccess(config);
}
+ private void processAccess(Configuration config)
+ {
+ Configuration accessConfig = config.subset("access_control_list.access");
+
+ if(accessConfig.isEmpty())
+ {
+ //there is no access configuration to process
+ return;
+ }
+
+ // Process users that have full access permission
+ String[] users = accessConfig.getStringArray("users.user");
+
+ for (String user : users)
+ {
+ grant(Permission.ACCESS, user);
+ }
+ }
+
/**
* Publish format takes Exchange + Routing Key Pairs
*
diff --git a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
index 28161a0229..e21edd1193 100644
--- a/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
+++ b/qpid/java/broker/src/test/java/org/apache/qpid/server/security/access/PrincipalPermissionsTest.java
@@ -164,4 +164,37 @@ public class PrincipalPermissionsTest extends TestCase
assertEquals(AuthzResult.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgs));
}
+ public void testVhostAccess()
+ {
+ //Tests that granting a user Virtualhost level access allows all authorisation requests
+ //where previously they would be denied
+
+ //QPID-2133 createExchange rights currently allow all exchange creation unless rights for creating some
+ //specific exchanges are granted. Grant a specific exchange creation to cause all others to be denied.
+ Object[] createArgsCreateExchange = new Object[]{new AMQShortString("madeup"), _exchangeType};
+ Object[] authArgsCreateExchange = new Object[]{_exchangeName,_exchangeType};
+ assertEquals("Exchange creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
+ _perms.grant(Permission.CREATEEXCHANGE, createArgsCreateExchange);
+
+ Object[] authArgsPublish = new Object[]{_exchange, _routingKey};
+ Object[] authArgsConsume = new Object[]{_queue};
+ Object[] authArgsCreateQueue = new Object[]{_autoDelete, _queueName};
+ QueueBindBodyImpl bind = new QueueBindBodyImpl(_ticket, _queueName, _exchangeName, _routingKey, _nowait, _arguments);
+ Object[] authArgsBind = new Object[]{bind, _exchange, _queue, _routingKey};
+
+ assertEquals("Exchange creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
+ assertEquals("Publish was not denied", AuthzResult.DENIED, _perms.authorise(Permission.PUBLISH, authArgsPublish));
+ assertEquals("Consume creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.CONSUME, authArgsConsume));
+ assertEquals("Queue creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue));
+ //BIND pre-grant authorise check disabled due to QPID-1597
+ //assertEquals("Binding creation was not denied", AuthzResult.DENIED, _perms.authorise(Permission.BIND, authArgsBind));
+
+ _perms.grant(Permission.ACCESS);
+
+ assertEquals("Exchange creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEEXCHANGE, authArgsCreateExchange));
+ assertEquals("Publish was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.PUBLISH, authArgsPublish));
+ assertEquals("Consume creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.CONSUME, authArgsConsume));
+ assertEquals("Queue creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.CREATEQUEUE, authArgsCreateQueue));
+ assertEquals("Binding creation was not allowed", AuthzResult.ALLOWED, _perms.authorise(Permission.BIND, authArgsBind));
+ }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java b/qpid/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java
index 79bc29a4e3..6b88b6a22d 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/failover/FailoverHandler.java
@@ -23,6 +23,7 @@ package org.apache.qpid.client.failover;
import org.apache.qpid.AMQDisconnectedException;
import org.apache.qpid.client.protocol.AMQProtocolHandler;
import org.apache.qpid.client.state.AMQStateManager;
+import org.apache.qpid.client.state.AMQState;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -193,6 +194,22 @@ public class FailoverHandler implements Runnable
// Set the new Protocol Session in the StateManager.
existingStateManager.setProtocolSession(_amqProtocolHandler.getProtocolSession());
+ // Now that the ProtocolHandler has been reconnected clean up
+ // the state of the old state manager. As if we simply reinstate
+ // it any old exception that had occured prior to failover may
+ // prohibit reconnection.
+ // e.g. During testing when the broker is shutdown gracefully.
+ // The broker
+ // Clear any exceptions we gathered
+ if (existingStateManager.getCurrentState() != AMQState.CONNECTION_OPEN)
+ {
+ // Clear the state of the previous state manager as it may
+ // have received an exception
+ existingStateManager.clearLastException();
+ existingStateManager.changeState(AMQState.CONNECTION_OPEN);
+ }
+
+
//Restore Existing State Manager
_amqProtocolHandler.setStateManager(existingStateManager);
try
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java b/qpid/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java
index 70d4697f2c..9c7d62670c 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/client/state/AMQStateManager.java
@@ -213,4 +213,9 @@ public class AMQStateManager implements AMQMethodListener
{
return _lastException;
}
+
+ public void clearLastException()
+ {
+ _lastException = null;
+ }
}
diff --git a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java
index 869944dd6e..41ba4974ec 100644
--- a/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java
+++ b/qpid/java/client/src/main/java/org/apache/qpid/jms/failover/FailoverRoundRobinServers.java
@@ -95,11 +95,10 @@ public class FailoverRoundRobinServers implements FailoverMethod
public boolean failoverAllowed()
{
- System.out.println("====================================");
- System.out.println(toString());
- System.out.println("====================================");
+ _logger.info("==== Checking failoverAllowed() ====");
+ _logger.info(toString());
+ _logger.info("====================================");
return ((_currentCycleRetries < _cycleRetries) || (_currentServerRetry < _serverRetries));
- //|| (_currentBrokerIndex <= (_connectionDetails.getBrokerCount() - 1)));
}
public void attainedConnection()
@@ -175,7 +174,11 @@ public class FailoverRoundRobinServers implements FailoverMethod
}
else
{
- _logger.info("No delay between connect retries, use tcp://host:port?connectdelay='value' to enable.");
+ // Only display if option not set. Not if deDelay==false.
+ if (delayStr == null)
+ {
+ _logger.info("No delay between connect retries, use tcp://host:port?connectdelay='value' to enable.");
+ }
}
return broker;
diff --git a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java
index 6e1d68efa1..04d1ec1e72 100644
--- a/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java
+++ b/qpid/java/systests/src/main/java/org/apache/qpid/server/security/acl/SimpleACLTest.java
@@ -56,6 +56,20 @@ public class SimpleACLTest extends QpidTestCase implements ConnectionListener, E
//Each test now calls the private setUpACLTest to allow them to make
//individual customisations to the base ACL settings
}
+
+
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ catch (JMSException e)
+ {
+ //we're throwing this away as it can happen in this test as the state manager remembers exceptions
+ //that we provoked with authentication failures, where the test passes - we can ignore on con close
+ }
+ }
private void setUpACLTest() throws Exception
{
@@ -100,7 +114,51 @@ public class SimpleACLTest extends QpidTestCase implements ConnectionListener, E
fail("Connection was not created due to:" + e);
}
}
+
+ public void testAccessVhostAuthorisedGuest() throws IOException, Exception
+ {
+ //The 'guest' user normally has no access, as tested below in testAccessNoRights(), and so is unable to perform
+ //actions such as connecting (and by extension, creating a queue, and consuming from a queue etc). In order to test
+ //the vhost-wide 'access' right, we will now give the guest user 'access' ACL rights and perform various such actions.
+ setConfigurationProperty("virtualhosts.virtualhost.test.security.access_control_list.access.users.user", "guest");
+
+ setUpACLTest();
+
+ try
+ {
+ //get a connection
+ Connection conn = getConnection("guest", "guest");
+ ((AMQConnection) conn).setConnectionListener(this);
+
+ Session sesh = conn.createSession(false, Session.AUTO_ACKNOWLEDGE);
+
+ conn.start();
+
+ //create Queues and consumers for each
+ Queue namedQueue = sesh.createQueue("vhostAccessCreatedQueue" + getTestQueueName());
+ Queue tempQueue = sesh.createTemporaryQueue();
+ MessageConsumer consumer = sesh.createConsumer(namedQueue);
+ MessageConsumer tempConsumer = sesh.createConsumer(tempQueue);
+
+ //send a message to each queue (also causing an exchange declare)
+ MessageProducer sender = ((AMQSession)sesh).createProducer(null);
+ ((org.apache.qpid.jms.MessageProducer) sender).send(namedQueue, sesh.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+ ((org.apache.qpid.jms.MessageProducer) sender).send(tempQueue, sesh.createTextMessage("test"),
+ DeliveryMode.NON_PERSISTENT, 0, 0L, false, false, true);
+ //consume the messages from the queues
+ consumer.receive(2000);
+ tempConsumer.receive(2000);
+
+ conn.close();
+ }
+ catch (Exception e)
+ {
+ fail("Test failed due to:" + e.getMessage());
+ }
+ }
+
public void testAccessNoRights() throws Exception
{
setUpACLTest();