summaryrefslogtreecommitdiff
path: root/java
diff options
context:
space:
mode:
Diffstat (limited to 'java')
-rw-r--r--java/broker/etc/config.xml169
-rw-r--r--java/broker/etc/md5passwd1
-rw-r--r--java/broker/etc/passwdVhost1
-rw-r--r--java/broker/etc/virtualhosts.xml2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java34
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java6
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java24
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java20
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java5
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java58
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java8
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java29
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java136
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java66
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java27
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java35
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java34
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java84
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/NullAuthenticationManager.java82
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/SASLAuthenticationManager.java228
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainInitialiser.java38
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java129
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServerFactory.java60
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java148
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/PasswordFilePrincipalDatabase.java)105
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java163
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java241
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/PrincipalDatabase.java)24
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java30
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java83
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java41
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationManager.java)6
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java246
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainInitialiser.java38
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainSaslServer.java149
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainSaslServerFactory.java60
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationProviderInitialiser.java)11
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/JCAProvider.java)2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePasswordInitialiser.java)23
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java)2
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java (renamed from java/broker/src/main/java/org/apache/qpid/server/security/auth/CRAMMD5Initialiser.java)37
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java42
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java134
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java2
-rw-r--r--java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java2
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/DispatcherTest.java2
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java2
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java2
-rw-r--r--java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java2
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java9
-rw-r--r--java/client/src/test/java/org/apache/qpid/test/unit/close/CloseBeforeAckTest.java43
-rw-r--r--java/client/src/test/java/org/apache/qpid/testutil/Config.java2
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java10
-rw-r--r--java/systests/src/main/java/org/apache/qpid/server/util/TestApplicationRegistry.java39
-rw-r--r--java/systests/src/main/java/org/apache/qpid/test/VMTestCase.java2
55 files changed, 1924 insertions, 1054 deletions
diff --git a/java/broker/etc/config.xml b/java/broker/etc/config.xml
index ab6daef62d..da0d13b72f 100644
--- a/java/broker/etc/config.xml
+++ b/java/broker/etc/config.xml
@@ -49,73 +49,108 @@
<framesize>65535</framesize>
<compressBufferOnQueue>false</compressBufferOnQueue>
</advanced>
- <security>
- <principal-databases>
- <principal-database>
- <name>passwordfile</name>
- <class>org.apache.qpid.server.security.auth.PasswordFilePrincipalDatabase</class>
- <attributes>
- <attribute>
- <name>passwordFile</name>
- <value>${conf}/passwd</value>
- </attribute>
- </attributes>
- </principal-database>
- </principal-databases>
- <sasl>
- <mechanisms>
- <mechanism>
- <initialiser>
- <class>org.apache.qpid.server.security.auth.CRAMMD5Initialiser</class>
- <principal-database>passwordfile</principal-database>
- </initialiser>
- </mechanism>
- <mechanism>
- <initialiser>
- <class>org.apache.qpid.server.security.auth.amqplain.AmqPlainInitialiser</class>
- <principal-database>passwordfile</principal-database>
- </initialiser>
- </mechanism>
- <mechanism>
- <initialiser>
- <class>org.apache.qpid.server.security.auth.plain.PlainInitialiser</class>
- <principal-database>passwordfile</principal-database>
- </initialiser>
- </mechanism>
- </mechanisms>
- </sasl>
- </security>
- <virtualhosts>
- <virtualhost>
- <name>localhost</name>
- <localhost>
- <store>
- <!-- <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class> -->
- <class>org.apache.qpid.server.store.MemoryMessageStore</class>
- <environment-path>localhost-store</environment-path>
- </store>
- </localhost>
- </virtualhost>
-
- <virtualhost>
- <name>development</name>
- <development>
- <store>
- <class>org.apache.qpid.server.store.MemoryMessageStore</class>
- </store>
- </development>
- </virtualhost>
-
- <virtualhost>
- <name>test</name>
- <test>
- <store>
- <class>org.apache.qpid.server.store.MemoryMessageStore</class>
- </store>
- </test>
- </virtualhost>
-
- </virtualhosts>
+
+ <principal-databases>
+ <principal-database>
+ <name>passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.PlainPasswordVhostFilePrincipalDatabase</class>
+ <attributes>
+ <attribute>
+ <name>passwordFile</name>
+ <value>${conf}/passwdVhost</value>
+ </attribute>
+ </attributes>
+ </principal-database>
+
+ <principal-database>
+ <name>md5passwordfile</name>
+ <class>org.apache.qpid.server.security.auth.database.MD5PasswordFilePrincipalDatabase</class>
+ <attributes>
+ <attribute>
+ <name>passwordFile</name>
+ <value>${conf}/md5passwd</value>
+ </attribute>
+ </attributes>
+ </principal-database>
+ </principal-databases>
+
+ <access>
+ <class>org.apache.qpid.server.security.access.AllowAll</class>
+ </access>
+
+ <virtualhosts>
+ <virtualhost>
+ <name>localhost</name>
+ <localhost>
+ <store>
+ <!-- <class>org.apache.qpid.server.store.berkeleydb.BDBMessageStore</class> -->
+ <class>org.apache.qpid.server.store.MemoryMessageStore</class>
+ <environment-path>localhost-store</environment-path>
+ </store>
+
+ <security>
+ <!-- Need protocol changes to allow this-->
+ <authentication>
+ <name>passwordfile</name>
+ <!-- Currently this can't be used as Vhost isn't specified at connection start only connection open -->
+ <mechanism>PLAIN</mechanism>
+ </authentication>
+ <access>
+ <class>org.apache.qpid.server.security.access.PrincipalDatabaseAccessManager</class>
+ <attributes>
+ <attribute>
+ <name>principalDatabase</name>
+ <value>passwordfile</value>
+ </attribute>
+ <attribute>
+ <name>defaultAccessManager</name>
+ <value>DenyAll</value>
+ </attribute>
+ </attributes>
+ </access>
+ </security>
+ </localhost>
+ </virtualhost>
+
+ <virtualhost>
+ <name>development</name>
+ <development>
+ <store>
+ <class>org.apache.qpid.server.store.MemoryMessageStore</class>
+ </store>
+ <security>
+ <name>passwordfile-notusedyet</name>
+ <mechanism>PLAIN</mechanism>
+ <mechanism>CRAM-MD5</mechanism>
+ </security>
+ </development>
+ </virtualhost>
+
+ <virtualhost>
+ <name>test</name>
+ <test>
+ <store>
+ <class>org.apache.qpid.server.store.MemoryMessageStore</class>
+ </store>
+ <security>
+ <name>passwordfile-notusedyet</name>
+ <mechanism>PLAIN</mechanism>
+ <mechanism>CRAM-MD5</mechanism>
+ </security>
+ <access>
+ <class>org.apache.qpid.server.security.access.PrincipalDatabaseAccessManager</class>
+ <attributes>
+ <attribute>
+ <name>principalDatabase</name>
+ <value>rubbish-to-cause-default</value>
+ </attribute>
+ </attributes>
+ </access>
+
+ </test>
+ </virtualhost>
+
+ </virtualhosts>
<heartbeat>
<delay>0</delay>
<timeoutFactor>2.0</timeoutFactor>
diff --git a/java/broker/etc/md5passwd b/java/broker/etc/md5passwd
new file mode 100644
index 0000000000..f6839898bf
--- /dev/null
+++ b/java/broker/etc/md5passwd
@@ -0,0 +1 @@
+guest:qfgyy4ewnVMBg
diff --git a/java/broker/etc/passwdVhost b/java/broker/etc/passwdVhost
new file mode 100644
index 0000000000..5db304e12c
--- /dev/null
+++ b/java/broker/etc/passwdVhost
@@ -0,0 +1 @@
+guest:guest:localhost,test
diff --git a/java/broker/etc/virtualhosts.xml b/java/broker/etc/virtualhosts.xml
index c6dedd6433..f62ec3f5d7 100644
--- a/java/broker/etc/virtualhosts.xml
+++ b/java/broker/etc/virtualhosts.xml
@@ -23,7 +23,7 @@
<default>test</default>
<virtualhost>
<name>localhost</name>
- <localhost>
+ <localhost>
<exchanges>
<exchange>
<type>direct</type>
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 a85af61327..2ecb39254f 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
@@ -7,9 +7,9 @@
* 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
@@ -32,9 +32,13 @@ 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.qpid.server.security.access.AccessResult;
+import org.apache.log4j.Logger;
public class ConnectionOpenMethodHandler implements StateAwareMethodListener<ConnectionOpenBody>
{
+ private static final Logger _logger = Logger.getLogger(ConnectionOpenMethodHandler.class);
+
private static ConnectionOpenMethodHandler _instance = new ConnectionOpenMethodHandler();
public static ConnectionOpenMethodHandler getInstance()
@@ -58,9 +62,9 @@ public class ConnectionOpenMethodHandler implements StateAwareMethodListener<Con
//ignore leading '/'
String virtualHostName;
- if((body.virtualHost != null) && body.virtualHost.charAt(0) == '/')
+ if ((body.virtualHost != null) && body.virtualHost.charAt(0) == '/')
{
- virtualHostName = new StringBuilder(body.virtualHost.subSequence(1,body.virtualHost.length())).toString();
+ virtualHostName = new StringBuilder(body.virtualHost.subSequence(1, body.virtualHost.length())).toString();
}
else
{
@@ -69,15 +73,27 @@ public class ConnectionOpenMethodHandler implements StateAwareMethodListener<Con
VirtualHost virtualHost = stateManager.getVirtualHostRegistry().getVirtualHost(virtualHostName);
- if(virtualHost == null)
+ if (virtualHost == null)
{
throw body.getConnectionException(AMQConstant.NOT_FOUND, "Unknown virtual host: " + virtualHostName);
}
else
{
- session.setVirtualHost( virtualHost );
+ session.setVirtualHost(virtualHost);
+ AccessResult result = virtualHost.getAccessManager().isAuthorized(virtualHost, session.getAuthorizedID());
+ switch (result.getStatus())
+ {
+ default:
+ case REFUSED:
+ throw body.getConnectionException(AMQConstant.ACCESS_REFUSED,
+ "Access denied to vHost '" + virtualHostName + "' by "
+ + result.getAuthorizer());
+ case GRANTED:
+ _logger.info("Granted access to vHost '" + virtualHostName + "' for " + session.getAuthorizedID()
+ + " by '" + result.getAuthorizer() + "'");
+ }
// See Spec (0.8.2). Section 3.1.2 Virtual Hosts
if (session.getContextKey() == null)
@@ -88,9 +104,9 @@ public class ConnectionOpenMethodHandler implements StateAwareMethodListener<Con
// AMQP version change: Hardwire the version to 0-8 (major=8, minor=0)
// TODO: Connect this to the session version obtained from ProtocolInitiation for this session.
// Be aware of possible changes to parameter order as versions change.
- AMQFrame response = ConnectionOpenOkBody.createAMQFrame((short)0,
- (byte)8, (byte)0, // AMQP version (major, minor)
- body.virtualHost);
+ AMQFrame response = ConnectionOpenOkBody.createAMQFrame((short) 0,
+ (byte) 8, (byte) 0, // AMQP version (major, minor)
+ body.virtualHost);
stateManager.changeState(AMQState.CONNECTION_OPEN);
session.writeFrame(response);
}
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 4ad6dcde71..6029a023e5 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
@@ -35,7 +35,7 @@ import org.apache.qpid.protocol.AMQMethodEvent;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.protocol.HeartbeatConfig;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
@@ -61,7 +61,10 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
AMQProtocolSession session = stateManager.getProtocolSession();
ConnectionSecureOkBody body = evt.getMethod();
+ //fixme Vhost not defined yet
+ //session.getVirtualHost().getAuthenticationManager();
AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager();
+
SaslServer ss = session.getSaslServer();
if (ss == null)
{
@@ -103,6 +106,7 @@ public class ConnectionSecureOkMethodHandler implements StateAwareMethodListener
ConnectionStartOkMethodHandler.getConfiguredFrameSize(), // frameMax
HeartbeatConfig.getInstance().getDelay()); // heartbeat
session.writeFrame(tune);
+ session.setAuthorizedID(ss.getAuthorizationID());
disposeSaslServer(session);
break;
case CONTINUE:
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 65b79cf8e7..d8a20071b9 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
@@ -31,10 +31,11 @@ import org.apache.qpid.framing.ConnectionSecureBody;
import org.apache.qpid.framing.ConnectionStartOkBody;
import org.apache.qpid.framing.ConnectionTuneBody;
import org.apache.qpid.protocol.AMQMethodEvent;
+import org.apache.qpid.protocol.AMQConstant;
import org.apache.qpid.server.protocol.AMQProtocolSession;
import org.apache.qpid.server.protocol.HeartbeatConfig;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.state.AMQState;
import org.apache.qpid.server.state.AMQStateManager;
@@ -65,12 +66,18 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
_logger.info("SASL Mechanism selected: " + body.mechanism);
_logger.info("Locale selected: " + body.locale);
- AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager();
+ AuthenticationManager authMgr = ApplicationRegistry.getInstance().getAuthenticationManager();//session.getVirtualHost().getAuthenticationManager();
SaslServer ss = null;
try
{
ss = authMgr.createSaslServer(String.valueOf(body.mechanism), session.getLocalFQDN());
+
+ if (ss == null)
+ {
+ throw body.getConnectionException(AMQConstant.RESOURCE_ERROR, "Unable to create SASL Server");
+ }
+
session.setSaslServer(ss);
AuthenticationResult authResult = authMgr.authenticate(ss, body.response);
@@ -87,16 +94,17 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
throw new AMQException("Authentication failed");
case SUCCESS:
_logger.info("Connected as: " + ss.getAuthorizationID());
+ session.setAuthorizedID(ss.getAuthorizationID());
stateManager.changeState(AMQState.CONNECTION_NOT_TUNED);
// AMQP version change: Hardwire the version to 0-8 (major=8, minor=0)
// TODO: Connect this to the session version obtained from ProtocolInitiation for this session.
// Be aware of possible changes to parameter order as versions change.
AMQFrame tune = ConnectionTuneBody.createAMQFrame(0,
- (byte)8, (byte)0, // AMQP version (major, minor)
- Integer.MAX_VALUE, // channelMax
- getConfiguredFrameSize(), // frameMax
- HeartbeatConfig.getInstance().getDelay()); // heartbeat
+ (byte) 8, (byte) 0, // AMQP version (major, minor)
+ Integer.MAX_VALUE, // channelMax
+ getConfiguredFrameSize(), // frameMax
+ HeartbeatConfig.getInstance().getDelay()); // heartbeat
session.writeFrame(tune);
break;
case CONTINUE:
@@ -105,8 +113,8 @@ public class ConnectionStartOkMethodHandler implements StateAwareMethodListener<
// TODO: Connect this to the session version obtained from ProtocolInitiation for this session.
// Be aware of possible changes to parameter order as versions change.
AMQFrame challenge = ConnectionSecureBody.createAMQFrame(0,
- (byte)8, (byte)0, // AMQP version (major, minor)
- authResult.challenge); // challenge
+ (byte) 8, (byte) 0, // AMQP version (major, minor)
+ authResult.challenge); // challenge
session.writeFrame(challenge);
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
index 133f4809b4..1c741ead1e 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
@@ -106,6 +106,7 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
private VersionSpecificRegistry _registry = MainRegistry.getVersionSpecificRegistry(_protocolVersion);
private List<Integer> _closingChannelsList = new ArrayList<Integer>();
private ProtocolOutputConverter _protocolOutputConverter;
+ private String _authorizedID;
public ManagedObject getManagedObject()
@@ -205,22 +206,22 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
int channelId = frame.getChannel();
AMQBody body = frame.getBodyFrame();
- if(_logger.isDebugEnabled())
+ if (_logger.isDebugEnabled())
{
_logger.debug("Frame Received: " + frame);
}
if (body instanceof AMQMethodBody)
{
- methodFrameReceived(channelId, (AMQMethodBody)body);
+ methodFrameReceived(channelId, (AMQMethodBody) body);
}
else if (body instanceof ContentHeaderBody)
{
- contentHeaderReceived(channelId, (ContentHeaderBody)body);
+ contentHeaderReceived(channelId, (ContentHeaderBody) body);
}
else if (body instanceof ContentBody)
{
- contentBodyReceived(channelId, (ContentBody)body);
+ contentBodyReceived(channelId, (ContentBody) body);
}
else if (body instanceof HeartbeatBody)
{
@@ -674,7 +675,7 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
private void setProtocolVersion(byte major, byte minor)
{
- _protocolVersion = new ProtocolVersion(major,minor);
+ _protocolVersion = new ProtocolVersion(major, minor);
_registry = MainRegistry.getVersionSpecificRegistry(_protocolVersion);
@@ -735,5 +736,14 @@ public class AMQMinaProtocolSession implements AMQProtocolSession,
return _protocolOutputConverter;
}
+ public void setAuthorizedID(String authorizedID)
+ {
+ _authorizedID = authorizedID;
+ }
+
+ public String getAuthorizedID()
+ {
+ return _authorizedID;
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
index 4cfee06850..79421dd497 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
@@ -165,4 +165,9 @@ public interface AMQProtocolSession extends AMQVersionAwareProtocolSession
public ProtocolOutputConverter getProtocolOutputConverter();
+ void setAuthorizedID(String authorizedID);
+
+ /** @return a username string that was used to authorized this session */
+ String getAuthorizedID();
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
index 70248a8e52..739ed9db42 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
@@ -34,8 +34,12 @@ import org.apache.qpid.server.management.JMXManagedObjectRegistry;
import org.apache.qpid.server.management.ManagedObjectRegistry;
import org.apache.qpid.server.management.ManagementConfiguration;
import org.apache.qpid.server.management.NoopManagedObjectRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationManager;
-import org.apache.qpid.server.security.auth.SASLAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.database.ConfigurationFilePrincipalDatabaseManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.access.AccessManager;
+import org.apache.qpid.server.security.access.AccessManagerImpl;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
@@ -46,6 +50,10 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
private AuthenticationManager _authenticationManager;
+ private AccessManager _accessManager;
+
+ private PrincipalDatabaseManager _databaseManager;
+
private VirtualHostRegistry _virtualHostRegistry;
@@ -59,26 +67,33 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
// Our configuration class needs to make the interpolate method
// public so it can be called below from the config method.
- private static class MyConfiguration extends CompositeConfiguration {
- public String interpolate(String obj) {
+ private static class MyConfiguration extends CompositeConfiguration
+ {
+ public String interpolate(String obj)
+ {
return super.interpolate(obj);
}
}
- private static final Configuration config(File url) throws ConfigurationException {
+ private static final Configuration config(File url) throws ConfigurationException
+ {
// We have to override the interpolate methods so that
// interpolation takes place accross the entirety of the
// composite configuration. Without doing this each
// configuration object only interpolates variables defined
// inside itself.
final MyConfiguration conf = new MyConfiguration();
- conf.addConfiguration(new SystemConfiguration() {
- protected String interpolate(String o) {
+ conf.addConfiguration(new SystemConfiguration()
+ {
+ protected String interpolate(String o)
+ {
return conf.interpolate(o);
}
});
- conf.addConfiguration(new XMLConfiguration(url) {
- protected String interpolate(String o) {
+ conf.addConfiguration(new XMLConfiguration(url)
+ {
+ protected String interpolate(String o)
+ {
return conf.interpolate(o);
}
});
@@ -89,17 +104,22 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
{
initialiseManagedObjectRegistry();
_virtualHostRegistry = new VirtualHostRegistry();
- _authenticationManager = new SASLAuthenticationManager();
+
+ _accessManager = new AccessManagerImpl("default", _configuration);
+
+ _databaseManager = new ConfigurationFilePrincipalDatabaseManager();
+
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null);
initialiseVirtualHosts();
}
private void initialiseVirtualHosts() throws Exception
{
- for(String name : getVirtualHostNames())
+ for (String name : getVirtualHostNames())
{
-
- _virtualHostRegistry.registerVirtualHost(new VirtualHost(name,getConfiguration().subset("virtualhosts.virtualhost."+name)));
+
+ _virtualHostRegistry.registerVirtualHost(new VirtualHost(name, getConfiguration().subset("virtualhosts.virtualhost." + name)));
}
}
@@ -122,11 +142,21 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
return _virtualHostRegistry;
}
+ public AccessManager getAccessManager()
+ {
+ return _accessManager;
+ }
+
public ManagedObjectRegistry getManagedObjectRegistry()
{
return _managedObjectRegistry;
}
+ public PrincipalDatabaseManager getDatabaseManager()
+ {
+ return _databaseManager;
+ }
+
public AuthenticationManager getAuthenticationManager()
{
return _authenticationManager;
@@ -134,6 +164,6 @@ public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
public Collection<String> getVirtualHostNames()
{
- return getConfiguration().getList("virtualhosts.virtualhost.name");
+ return getConfiguration().getList("virtualhosts.virtualhost.name");
}
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
index 5924cdb178..5a48431288 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
@@ -24,7 +24,9 @@ import java.util.Collection;
import org.apache.commons.configuration.Configuration;
import org.apache.qpid.server.management.ManagedObjectRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
+import org.apache.qpid.server.security.access.AccessManager;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
public interface IApplicationRegistry
@@ -57,9 +59,13 @@ public interface IApplicationRegistry
ManagedObjectRegistry getManagedObjectRegistry();
+ PrincipalDatabaseManager getDatabaseManager();
+
AuthenticationManager getAuthenticationManager();
Collection<String> getVirtualHostNames();
VirtualHostRegistry getVirtualHostRegistry();
+
+ AccessManager getAccessManager();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java
new file mode 100644
index 0000000000..0c0de88182
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java
@@ -0,0 +1,29 @@
+/*
+ * 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 interface AccessManager
+{
+ AccessResult isAuthorized(Accessable accessObject, String username);
+
+ String getName();
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java
new file mode 100644
index 0000000000..0b022aa8f7
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java
@@ -0,0 +1,136 @@
+/*
+ * 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.server.registry.ApplicationRegistry;
+import org.apache.qpid.configuration.PropertyUtils;
+import org.apache.qpid.configuration.PropertyException;
+import org.apache.log4j.Logger;
+
+import java.util.List;
+import java.lang.reflect.Method;
+import java.lang.reflect.InvocationTargetException;
+
+public class AccessManagerImpl implements AccessManager
+{
+ private static final Logger _logger = Logger.getLogger(AccessManagerImpl.class);
+
+ AccessManager _accessManager;
+
+ public AccessManagerImpl(String name, Configuration hostConfig) throws ConfigurationException
+ {
+ String accessClass = hostConfig.getString("security.access.class");
+
+ if (accessClass == null)
+ {
+ _logger.warn("No access control specified. Using default access controls for VirtualHost:'" + name + "'");
+ return;
+ }
+
+ Object o;
+ try
+ {
+ o = Class.forName(accessClass).newInstance();
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException("Error initialising access control: " + e, e);
+ }
+
+ if (!(o instanceof AccessManager))
+ {
+ throw new ConfigurationException("Access control must implement the VirtualHostAccess interface");
+ }
+
+ initialiseAccessControl((AccessManager) o, hostConfig);
+
+ _accessManager = (AccessManager) o;
+
+ _logger.info("Initialised access control for virtualhost '" + name + "' successfully");
+
+ }
+
+
+ private void initialiseAccessControl(AccessManager accessManager, Configuration config)
+ throws ConfigurationException
+ {
+ String baseName = "access.attributes.attribute.";
+ List<String> argumentNames = config.getList(baseName + "name");
+ List<String> argumentValues = config.getList(baseName + "value");
+ for (int i = 0; i < argumentNames.size(); i++)
+ {
+ String argName = argumentNames.get(i);
+ if (argName == null || argName.length() == 0)
+ {
+ throw new ConfigurationException("Access Control argument names must have length >= 1 character");
+ }
+ if (Character.isLowerCase(argName.charAt(0)))
+ {
+ argName = Character.toUpperCase(argName.charAt(0)) + argName.substring(1);
+ }
+ String methodName = "set" + argName;
+ Method method = null;
+ try
+ {
+ method = accessManager.getClass().getMethod(methodName, String.class);
+ }
+ catch (NoSuchMethodException e)
+ {
+ //do nothing as method will be null
+ }
+
+ if (method == null)
+ {
+ throw new ConfigurationException("No method " + methodName + " found in class " + accessManager.getClass() +
+ " hence unable to configure access control. The method must be public and " +
+ "have a single String argument with a void return type");
+ }
+ try
+ {
+ method.invoke(accessManager, PropertyUtils.replaceProperties(argumentValues.get(i)));
+ }
+ catch (Exception e)
+ {
+ throw new ConfigurationException(e.getCause());
+ }
+ }
+ }
+
+
+ public AccessResult isAuthorized(Accessable accessObject, String username)
+ {
+ if (_accessManager == null)
+ {
+ return ApplicationRegistry.getInstance().getAccessManager().isAuthorized(accessObject, username);
+ }
+ else
+ {
+ return _accessManager.isAuthorized(accessObject, username);
+ }
+ }
+
+ public String getName()
+ {
+ return "AccessManagerImpl";
+ }
+}
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
new file mode 100644
index 0000000000..b8d8fc605a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java
@@ -0,0 +1,66 @@
+/*
+ * 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
+ }
+
+ StringBuilder _authorizer;
+ AccessStatus _status;
+
+ public AccessResult(AccessManager authorizer, AccessStatus status)
+ {
+ _status = status;
+ _authorizer = new StringBuilder(authorizer.getName());
+ }
+
+ public void setAuthorizer(AccessManager authorizer)
+ {
+ _authorizer.append(authorizer.getName());
+ }
+
+ public String getAuthorizer()
+ {
+ return _authorizer.toString();
+ }
+
+ public void setStatus(AccessStatus status)
+ {
+ _status = status;
+ }
+
+ public AccessStatus getStatus()
+ {
+ return _status;
+ }
+
+ public void addAuthorizer(AccessManager accessManager)
+ {
+ _authorizer.insert(0, "->");
+ _authorizer.insert(0, accessManager.getName());
+ }
+
+
+}
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/Accessable.java
new file mode 100644
index 0000000000..f51cf24caa
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java
@@ -0,0 +1,27 @@
+/*
+ * 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 interface Accessable
+{
+ void setAccessableName(String name);
+ String getAccessableName();
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java
new file mode 100644
index 0000000000..b2e4094edd
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java
@@ -0,0 +1,35 @@
+/*
+ * 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 AllowAll implements AccessManager
+{
+
+ public AccessResult isAuthorized(Accessable accessObject, String username)
+ {
+ return new AccessResult(this, AccessResult.AccessStatus.GRANTED);
+ }
+
+ public String getName()
+ {
+ return "AllowAll";
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java
new file mode 100644
index 0000000000..0e62d2657f
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java
@@ -0,0 +1,34 @@
+/*
+ * 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 DenyAll implements AccessManager
+{
+ public AccessResult isAuthorized(Accessable accessObject, String username)
+ {
+ return new AccessResult(this, AccessResult.AccessStatus.REFUSED);
+ }
+
+ public String getName()
+ {
+ return "DenyAll";
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java
new file mode 100644
index 0000000000..d41e5dfb94
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java
@@ -0,0 +1,84 @@
+/*
+ * 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.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.log4j.Logger;
+
+public class PrincipalDatabaseAccessManager implements AccessManager
+{
+ private static final Logger _logger = Logger.getLogger(PrincipalDatabaseAccessManager.class);
+
+ PrincipalDatabase _database;
+ AccessManager _default;
+
+ public PrincipalDatabaseAccessManager()
+ {
+ _default = ApplicationRegistry.getInstance().getAccessManager();
+ }
+
+ public void setDefaultAccessManager(String defaultAM)
+ {
+ if (defaultAM.equals("AllowAll"))
+ {
+ _default = new AllowAll();
+ }
+
+ if (defaultAM.equals("DenyAll"))
+ {
+ _default = new DenyAll();
+ }
+ }
+
+ public void setPrincipalDatabase(String database)
+ {
+ _database = ApplicationRegistry.getInstance().getDatabaseManager().getDatabases().get(database);
+ if (!(_database instanceof AccessManager))
+ {
+ _logger.warn("Database '" + database + "' cannot perform access management");
+ }
+ }
+
+ public AccessResult isAuthorized(Accessable accessObject, String username)
+ {
+ AccessResult result;
+
+ if (_database == null)
+ {
+ result = _default.isAuthorized(accessObject, username);
+ }
+ else
+ {
+ result = ((AccessManager) _database).isAuthorized(accessObject, username);
+ }
+
+ result.addAuthorizer(this);
+
+ return result;
+ }
+
+ public String getName()
+ {
+ return "PrincipalDatabaseFileAccessManager";
+ }
+
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/NullAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/NullAuthenticationManager.java
deleted file mode 100644
index 20f190876f..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/NullAuthenticationManager.java
+++ /dev/null
@@ -1,82 +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.auth;
-
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
-public class NullAuthenticationManager implements AuthenticationManager
-{
- public String getMechanisms()
- {
- return "PLAIN";
- }
-
- public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException
- {
- return new SaslServer()
- {
- public String getMechanismName()
- {
- return "PLAIN";
- }
-
- public byte[] evaluateResponse(byte[] response) throws SaslException
- {
- return new byte[0];
- }
-
- public boolean isComplete()
- {
- return true;
- }
-
- public String getAuthorizationID()
- {
- return "guest";
- }
-
- public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
- {
- return new byte[0];
- }
-
- public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
- {
- return new byte[0];
- }
-
- public Object getNegotiatedProperty(String propName)
- {
- return null;
- }
-
- public void dispose() throws SaslException
- {
- }
- };
- }
-
- public AuthenticationResult authenticate(SaslServer server, byte[] response)
- {
- return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.SUCCESS);
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/SASLAuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/SASLAuthenticationManager.java
deleted file mode 100644
index 66923e371b..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/SASLAuthenticationManager.java
+++ /dev/null
@@ -1,228 +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.auth;
-
-import java.lang.reflect.Method;
-import java.security.Security;
-import java.util.HashMap;
-import java.util.List;
-import java.util.Map;
-import java.util.TreeMap;
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-import javax.security.sasl.SaslServerFactory;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.log4j.Logger;
-import org.apache.qpid.configuration.PropertyUtils;
-import org.apache.qpid.server.registry.ApplicationRegistry;
-
-public class SASLAuthenticationManager implements AuthenticationManager
-{
- private static final Logger _log = Logger.getLogger(SASLAuthenticationManager.class);
-
- /**
- * The list of mechanisms, in the order in which they are configured (i.e. preferred order)
- */
- private String _mechanisms;
-
- /**
- * Maps from the mechanism to the callback handler to use for handling those requests
- */
- private Map<String, CallbackHandler> _callbackHandlerMap = new HashMap<String, CallbackHandler>();
-
- /**
- * Maps from the mechanism to the properties used to initialise the server. See the method
- * Sasl.createSaslServer for details of the use of these properties. This map is populated during initialisation
- * of each provider.
- */
- private Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>();
-
- public SASLAuthenticationManager() throws Exception
- {
- _log.info("Initialising SASL authentication manager");
- Map<String, PrincipalDatabase> databases = initialisePrincipalDatabases();
- initialiseAuthenticationMechanisms(databases);
- }
-
- private Map<String, PrincipalDatabase> initialisePrincipalDatabases() throws Exception
- {
- Configuration config = ApplicationRegistry.getInstance().getConfiguration();
- List<String> databaseNames = config.getList("security.principal-databases.principal-database.name");
- List<String> databaseClasses = config.getList("security.principal-databases.principal-database.class");
- Map<String, PrincipalDatabase> databases = new HashMap<String, PrincipalDatabase>();
- for (int i = 0; i < databaseNames.size(); i++)
- {
- Object o;
- try
- {
- o = Class.forName(databaseClasses.get(i)).newInstance();
- }
- catch (Exception e)
- {
- throw new Exception("Error initialising principal database: " + e, e);
- }
-
- if (!(o instanceof PrincipalDatabase))
- {
- throw new Exception("Principal databases must implement the PrincipalDatabase interface");
- }
-
- initialisePrincipalDatabase((PrincipalDatabase) o, config, i);
-
- String name = databaseNames.get(i);
- if (name == null || name.length() == 0)
- {
- throw new Exception("Principal database names must have length greater than or equal to one character");
- }
- PrincipalDatabase pd = databases.get(name);
- if (pd != null)
- {
- throw new Exception("Duplicate principal database name provided");
- }
- _log.info("Initialised principal database " + name + " successfully");
- databases.put(name, (PrincipalDatabase) o);
- }
- return databases;
- }
-
- private void initialisePrincipalDatabase(PrincipalDatabase principalDatabase, Configuration config, int index)
- throws Exception
- {
- String baseName = "security.principal-databases.principal-database(" + index + ").attributes.attribute.";
- List<String> argumentNames = config.getList(baseName + "name");
- List<String> argumentValues = config.getList(baseName + "value");
- for (int i = 0; i < argumentNames.size(); i++)
- {
- String argName = argumentNames.get(i);
- if (argName == null || argName.length() == 0)
- {
- throw new Exception("Argument names must have length >= 1 character");
- }
- if (Character.isLowerCase(argName.charAt(0)))
- {
- argName = Character.toUpperCase(argName.charAt(0)) + argName.substring(1);
- }
- String methodName = "set" + argName;
- Method method = principalDatabase.getClass().getMethod(methodName, String.class);
- if (method == null)
- {
- throw new Exception("No method " + methodName + " found in class " + principalDatabase.getClass() +
- " hence unable to configure principal database. The method must be public and " +
- "have a single String argument with a void return type");
- }
- method.invoke(principalDatabase, PropertyUtils.replaceProperties(argumentValues.get(i)));
- }
- }
-
- private void initialiseAuthenticationMechanisms(Map<String, PrincipalDatabase> databases) throws Exception
- {
- Configuration config = ApplicationRegistry.getInstance().getConfiguration();
- List<String> mechanisms = config.getList("security.sasl.mechanisms.mechanism.initialiser.class");
-
- // Maps from the mechanism to the properties used to initialise the server. See the method
- // Sasl.createSaslServer for details of the use of these properties. This map is populated during initialisation
- // of each provider.
- Map<String, Class<? extends SaslServerFactory>> providerMap = new TreeMap<String, Class<? extends SaslServerFactory>>();
-
- for (int i = 0; i < mechanisms.size(); i++)
- {
- String baseName = "security.sasl.mechanisms.mechanism(" + i + ").initialiser";
- String clazz = config.getString(baseName + ".class");
- initialiseAuthenticationMechanism(baseName, clazz, databases, config, providerMap);
- }
- if (providerMap.size() > 0)
- {
- Security.addProvider(new JCAProvider(providerMap));
- }
- }
-
- private void initialiseAuthenticationMechanism(String baseName, String clazz,
- Map<String, PrincipalDatabase> databases,
- Configuration configuration,
- Map<String, Class<? extends SaslServerFactory>> providerMap)
- throws Exception
- {
- Class initialiserClazz = Class.forName(clazz);
- Object o = initialiserClazz.newInstance();
- if (!(o instanceof AuthenticationProviderInitialiser))
- {
- throw new Exception("The class " + clazz + " must be an instance of " +
- AuthenticationProviderInitialiser.class);
- }
- AuthenticationProviderInitialiser initialiser = (AuthenticationProviderInitialiser) o;
- initialiser.initialise(baseName, configuration, databases);
- String mechanism = initialiser.getMechanismName();
- if (_mechanisms == null)
- {
- _mechanisms = mechanism;
- }
- else
- {
- // simple append should be fine since the number of mechanisms is small and this is a one time initialisation
- _mechanisms = _mechanisms + " " + mechanism;
- }
- _callbackHandlerMap.put(mechanism, initialiser.getCallbackHandler());
- _serverCreationProperties.put(mechanism, initialiser.getProperties());
- Class<? extends SaslServerFactory> factory = initialiser.getServerFactoryClassForJCARegistration();
- if (factory != null)
- {
- providerMap.put(mechanism, factory);
- }
- _log.info("Initialised " + mechanism + " SASL provider successfully");
- }
-
- public String getMechanisms()
- {
- return _mechanisms;
- }
-
- public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException
- {
- return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, _serverCreationProperties.get(mechanism),
- _callbackHandlerMap.get(mechanism));
- }
-
- public AuthenticationResult authenticate(SaslServer server, byte[] response)
- {
- try
- {
- // Process response from the client
- byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
-
- if (server.isComplete())
- {
- return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.SUCCESS);
- }
- else
- {
- return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE);
- }
- }
- catch (SaslException e)
- {
- return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
- }
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainInitialiser.java
deleted file mode 100644
index 543115fd90..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainInitialiser.java
+++ /dev/null
@@ -1,38 +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.auth.amqplain;
-
-import javax.security.sasl.SaslServerFactory;
-
-import org.apache.qpid.server.security.auth.UsernamePasswordInitialiser;
-
-public class AmqPlainInitialiser extends UsernamePasswordInitialiser
-{
- public String getMechanismName()
- {
- return "AMQPLAIN";
- }
-
- public Class<? extends SaslServerFactory> getServerFactoryClassForJCARegistration()
- {
- return AmqPlainSaslServerFactory.class;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java
deleted file mode 100644
index 9e5a8f9a08..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServer.java
+++ /dev/null
@@ -1,129 +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.auth.amqplain;
-
-import java.io.IOException;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.sasl.AuthorizeCallback;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
-import org.apache.mina.common.ByteBuffer;
-import org.apache.qpid.framing.AMQFrameDecodingException;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.framing.FieldTableFactory;
-
-public class AmqPlainSaslServer implements SaslServer
-{
- public static final String MECHANISM = "AMQPLAIN";
-
- private CallbackHandler _cbh;
-
- private String _authorizationId;
-
- private boolean _complete = false;
-
- public AmqPlainSaslServer(CallbackHandler cbh)
- {
- _cbh = cbh;
- }
-
- public String getMechanismName()
- {
- return MECHANISM;
- }
-
- public byte[] evaluateResponse(byte[] response) throws SaslException
- {
- try
- {
- final FieldTable ft = FieldTableFactory.newFieldTable(ByteBuffer.wrap(response), response.length);
- String username = (String) ft.getString("LOGIN");
- // we do not care about the prompt but it throws if null
- NameCallback nameCb = new NameCallback("prompt", username);
- // we do not care about the prompt but it throws if null
- PasswordCallback passwordCb = new PasswordCallback("prompt", false);
- // TODO: should not get pwd as a String but as a char array...
- String pwd = (String) ft.getString("PASSWORD");
- passwordCb.setPassword(pwd.toCharArray());
- AuthorizeCallback authzCb = new AuthorizeCallback(username, username);
- Callback[] callbacks = new Callback[]{nameCb, passwordCb, authzCb};
- _cbh.handle(callbacks);
- _complete = true;
- if (authzCb.isAuthorized())
- {
- _authorizationId = authzCb.getAuthenticationID();
- return null;
- }
- else
- {
- throw new SaslException("Authentication failed");
- }
- }
- catch (AMQFrameDecodingException e)
- {
- throw new SaslException("Unable to decode response: " + e, e);
- }
- catch (IOException e)
- {
- throw new SaslException("Error processing data: " + e, e);
- }
- catch (UnsupportedCallbackException e)
- {
- throw new SaslException("Unable to obtain data from callback handler: " + e, e);
- }
- }
-
- public boolean isComplete()
- {
- return _complete;
- }
-
- public String getAuthorizationID()
- {
- return _authorizationId;
- }
-
- public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
- {
- throw new SaslException("Unsupported operation");
- }
-
- public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
- {
- throw new SaslException("Unsupported operation");
- }
-
- public Object getNegotiatedProperty(String propName)
- {
- return null;
- }
-
- public void dispose() throws SaslException
- {
- _cbh = null;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServerFactory.java
deleted file mode 100644
index 2569314a4a..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/AmqPlainSaslServerFactory.java
+++ /dev/null
@@ -1,60 +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.auth.amqplain;
-
-import java.util.Map;
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-import javax.security.sasl.SaslServerFactory;
-
-public class AmqPlainSaslServerFactory implements SaslServerFactory
-{
- public SaslServer createSaslServer(String mechanism, String protocol, String serverName, Map props,
- CallbackHandler cbh) throws SaslException
- {
- if (AmqPlainSaslServer.MECHANISM.equals(mechanism))
- {
- return new AmqPlainSaslServer(cbh);
- }
- else
- {
- return null;
- }
- }
-
- public String[] getMechanismNames(Map props)
- {
- if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
- props.containsKey(Sasl.POLICY_NODICTIONARY) ||
- props.containsKey(Sasl.POLICY_NOACTIVE))
- {
- // returned array must be non null according to interface documentation
- return new String[0];
- }
- else
- {
- return new String[]{AmqPlainSaslServer.MECHANISM};
- }
- }
-}
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
new file mode 100644
index 0000000000..dde4ce7c4d
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
@@ -0,0 +1,148 @@
+/*
+ * 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.auth.database;
+
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.configuration.PropertyUtils;
+import org.apache.log4j.Logger;
+
+import java.util.Map;
+import java.util.List;
+import java.util.HashMap;
+import java.lang.reflect.Method;
+import java.io.FileNotFoundException;
+
+public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatabaseManager
+{
+ private static final Logger _logger = Logger.getLogger(ConfigurationFilePrincipalDatabaseManager.class);
+
+ private static final String _base = "principal-databases.principal-database";
+
+ Map<String, PrincipalDatabase> _databases;
+
+ public ConfigurationFilePrincipalDatabaseManager() throws Exception
+ {
+ _logger.info("Initialising PrincipleDatabase authentication manager");
+ _databases = initialisePrincipalDatabases();
+ }
+
+ private Map<String, PrincipalDatabase> initialisePrincipalDatabases() throws Exception
+ {
+ Configuration config = ApplicationRegistry.getInstance().getConfiguration();
+ List<String> databaseNames = config.getList(_base + ".name");
+ List<String> databaseClasses = config.getList(_base + ".class");
+ Map<String, PrincipalDatabase> databases = new HashMap<String, PrincipalDatabase>();
+
+ if (databaseNames.size() == 0)
+ {
+ _logger.warn("No Principal databases specified. Broker running with NO AUTHENTICATION");
+ }
+
+ for (int i = 0; i < databaseNames.size(); i++)
+ {
+ Object o;
+ try
+ {
+ o = Class.forName(databaseClasses.get(i)).newInstance();
+ }
+ catch (Exception e)
+ {
+ throw new Exception("Error initialising principal database: " + e, e);
+ }
+
+ if (!(o instanceof PrincipalDatabase))
+ {
+ throw new Exception("Principal databases must implement the PrincipalDatabase interface");
+ }
+
+ initialisePrincipalDatabase((PrincipalDatabase) o, config, i);
+
+ String name = databaseNames.get(i);
+ if (name == null || name.length() == 0)
+ {
+ throw new Exception("Principal database names must have length greater than or equal to one character");
+ }
+ PrincipalDatabase pd = databases.get(name);
+ if (pd != null)
+ {
+ throw new Exception("Duplicate principal database name not provided");
+ }
+ _logger.info("Initialised principal database '" + name + "' successfully");
+ databases.put(name, (PrincipalDatabase) o);
+ }
+ return databases;
+ }
+
+ private void initialisePrincipalDatabase(PrincipalDatabase principalDatabase, Configuration config, int index)
+ throws FileNotFoundException, ConfigurationException
+ {
+ String baseName = _base + "(" + index + ").attributes.attribute.";
+ List<String> argumentNames = config.getList(baseName + "name");
+ List<String> argumentValues = config.getList(baseName + "value");
+ for (int i = 0; i < argumentNames.size(); i++)
+ {
+ String argName = argumentNames.get(i);
+ if (argName == null || argName.length() == 0)
+ {
+ throw new ConfigurationException("Argument names must have length >= 1 character");
+ }
+ if (Character.isLowerCase(argName.charAt(0)))
+ {
+ argName = Character.toUpperCase(argName.charAt(0)) + argName.substring(1);
+ }
+ String methodName = "set" + argName;
+ Method method = null;
+ try
+ {
+ method = principalDatabase.getClass().getMethod(methodName, String.class);
+ }
+ catch (Exception e)
+ {
+ // do nothing.. as on error method will be null
+ }
+
+ if (method == null)
+ {
+ throw new ConfigurationException("No method " + methodName + " found in class " + principalDatabase.getClass() +
+ " hence unable to configure principal database. The method must be public and " +
+ "have a single String argument with a void return type");
+ }
+
+ try
+ {
+ method.invoke(principalDatabase, PropertyUtils.replaceProperties(argumentValues.get(i)));
+ }
+ catch (Exception ite)
+ {
+ throw new ConfigurationException(ite.getCause());
+ }
+ }
+ }
+
+ public Map<String, PrincipalDatabase> getDatabases()
+ {
+ return _databases;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/PasswordFilePrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java
index b0592a7173..98fca99aa3 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/PasswordFilePrincipalDatabase.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java
@@ -1,61 +1,77 @@
/*
+ * 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
*
- * 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.
+ * 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.auth;
+package org.apache.qpid.server.security.auth.database;
-import java.io.BufferedReader;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
+import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
+
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.AccountNotFoundException;
import java.io.File;
import java.io.FileNotFoundException;
-import java.io.FileReader;
import java.io.IOException;
-import java.security.Principal;
+import java.io.BufferedReader;
+import java.io.FileReader;
import java.util.regex.Pattern;
-
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.login.AccountNotFoundException;
-
-import org.apache.log4j.Logger;
+import java.util.Map;
+import java.util.HashMap;
+import java.security.Principal;
/**
* Represents a user database where the account information is stored in a simple flat file.
*
- * The file is expected to be in the form:
- * username:password
- * username1:password1
- * ...
- * usernamen:passwordn
- *
- * where a carriage return separates each username/password pair. Passwords are assumed to be in
- * plain text.
+ * The file is expected to be in the form: username:password username1:password1 ... usernamen:passwordn
*
+ * where a carriage return separates each username/password pair. Passwords are assumed to be in plain text.
*/
-public class PasswordFilePrincipalDatabase implements PrincipalDatabase
+public class MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
{
- private static final Logger _logger = Logger.getLogger(PasswordFilePrincipalDatabase.class);
+ private static final Logger _logger = Logger.getLogger(MD5PasswordFilePrincipalDatabase.class);
private File _passwordFile;
private Pattern _regexp = Pattern.compile(":");
- public PasswordFilePrincipalDatabase()
+ private Map<String, AuthenticationProviderInitialiser> _saslServers;
+
+ public MD5PasswordFilePrincipalDatabase()
{
+ _saslServers = new HashMap<String, AuthenticationProviderInitialiser>();
+
+ /**
+ * Create Authenticators for MD5 Password file.
+ */
+
+ // Accept MD5 incomming and use plain comparison with the file
+ PlainInitialiser cram = new PlainInitialiser();
+ cram.initialise(this);
+ // Accept Plain incomming and hash it for comparison to the file.
+ CRAMMD5Initialiser plain = new CRAMMD5Initialiser();
+ plain.initialise(this,CRAMMD5Initialiser.HashDirection.INCOMMING);
+
+ _saslServers.put(plain.getMechanismName(), cram);
+ _saslServers.put(cram.getMechanismName(), plain);
}
public void setPasswordFile(String passwordFile) throws FileNotFoundException
@@ -75,7 +91,7 @@ public class PasswordFilePrincipalDatabase implements PrincipalDatabase
}
public void setPassword(Principal principal, PasswordCallback callback) throws IOException,
- AccountNotFoundException
+ AccountNotFoundException
{
if (_passwordFile == null)
{
@@ -96,13 +112,20 @@ public class PasswordFilePrincipalDatabase implements PrincipalDatabase
}
}
+ public Map<String, AuthenticationProviderInitialiser> getMechanisms()
+ {
+ return _saslServers;
+ }
+
/**
- * Looks up the password for a specified user in the password file.
- * Note this code is <b>not</b> secure since it creates strings of passwords. It should be modified
- * to create only char arrays which get nulled out.
+ * Looks up the password for a specified user in the password file. Note this code is <b>not</b> secure since it
+ * creates strings of passwords. It should be modified to create only char arrays which get nulled out.
+ *
* @param name
+ *
* @return
- * @throws IOException
+ *
+ * @throws java.io.IOException
*/
private char[] lookupPassword(String name) throws IOException
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
new file mode 100644
index 0000000000..6770baaece
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
@@ -0,0 +1,163 @@
+/*
+ * 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.auth.database;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
+import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
+
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.AccountNotFoundException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.util.regex.Pattern;
+import java.util.Map;
+import java.util.HashMap;
+import java.security.Principal;
+
+/**
+ * Represents a user database where the account information is stored in a simple flat file.
+ *
+ * The file is expected to be in the form: username:password username1:password1 ... usernamen:passwordn
+ *
+ * where a carriage return separates each username/password pair. Passwords are assumed to be in plain text.
+ */
+public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase
+{
+ private static final Logger _logger = Logger.getLogger(PlainPasswordFilePrincipalDatabase.class);
+
+ private File _passwordFile;
+
+ private Pattern _regexp = Pattern.compile(":");
+
+ private Map<String, AuthenticationProviderInitialiser> _saslServers;
+
+ public PlainPasswordFilePrincipalDatabase()
+ {
+ _saslServers = new HashMap<String, AuthenticationProviderInitialiser>();
+
+ /**
+ * Create Authenticators for Plain Password file.
+ */
+
+ // Accept Plain incomming and compare it to the file.
+ PlainInitialiser plain = new PlainInitialiser();
+ plain.initialise(this);
+
+ // Accept MD5 incomming and Hash file value for comparison
+ CRAMMD5Initialiser cram = new CRAMMD5Initialiser();
+ cram.initialise(this);
+
+ _saslServers.put(plain.getMechanismName(), plain);
+ _saslServers.put(cram.getMechanismName(), cram);
+ }
+
+ public void setPasswordFile(String passwordFile) throws FileNotFoundException
+ {
+ File f = new File(passwordFile);
+ _logger.info("PlainPasswordFile using file " + f.getAbsolutePath());
+ _passwordFile = f;
+ if (!f.exists())
+ {
+ throw new FileNotFoundException("Cannot find password file " + f);
+ }
+ if (!f.canRead())
+ {
+ throw new FileNotFoundException("Cannot read password file " + f +
+ ". Check permissions.");
+ }
+ }
+
+ public void setPassword(Principal principal, PasswordCallback callback) throws IOException,
+ AccountNotFoundException
+ {
+ if (_passwordFile == null)
+ {
+ throw new AccountNotFoundException("Unable to locate principal since no password file was specified during initialisation");
+ }
+ if (principal == null)
+ {
+ throw new IllegalArgumentException("principal must not be null");
+ }
+ char[] pwd = lookupPassword(principal.getName());
+ if (pwd != null)
+ {
+ callback.setPassword(pwd);
+ }
+ else
+ {
+ throw new AccountNotFoundException("No account found for principal " + principal);
+ }
+ }
+
+ public Map<String, AuthenticationProviderInitialiser> getMechanisms()
+ {
+ return _saslServers;
+ }
+
+
+ /**
+ * Looks up the password for a specified user in the password file. Note this code is <b>not</b> secure since it
+ * creates strings of passwords. It should be modified to create only char arrays which get nulled out.
+ *
+ * @param name
+ *
+ * @return
+ *
+ * @throws java.io.IOException
+ */
+ private char[] lookupPassword(String name) throws IOException
+ {
+ BufferedReader reader = null;
+ try
+ {
+ reader = new BufferedReader(new FileReader(_passwordFile));
+ String line;
+
+ while ((line = reader.readLine()) != null)
+ {
+ String[] result = _regexp.split(line);
+ if (result == null || result.length < 2)
+ {
+ continue;
+ }
+
+ if (name.equals(result[0]))
+ {
+ return result[1].toCharArray();
+ }
+ }
+ return null;
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+ }
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java
new file mode 100644
index 0000000000..37d883769a
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java
@@ -0,0 +1,241 @@
+/*
+ * 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.auth.database;
+
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
+import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
+import org.apache.qpid.server.security.access.AccessManager;
+import org.apache.qpid.server.security.access.AccessResult;
+import org.apache.qpid.server.security.access.Accessable;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.log4j.Logger;
+
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.AccountNotFoundException;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+import java.io.BufferedReader;
+import java.io.FileReader;
+import java.util.regex.Pattern;
+import java.util.Map;
+import java.util.HashMap;
+import java.security.Principal;
+
+/**
+ * Represents a user database where the account information is stored in a simple flat file.
+ *
+ * The file is expected to be in the form: username:password username1:password1 ... usernamen:passwordn
+ *
+ * where a carriage return separates each username/password pair. Passwords are assumed to be in plain text.
+ */
+public class PlainPasswordVhostFilePrincipalDatabase implements PrincipalDatabase, AccessManager
+{
+ private static final Logger _logger = Logger.getLogger(PlainPasswordVhostFilePrincipalDatabase.class);
+
+ private File _passwordFile;
+
+ private Pattern _regexp = Pattern.compile(":");
+
+ private Map<String, AuthenticationProviderInitialiser> _saslServers;
+
+ public PlainPasswordVhostFilePrincipalDatabase()
+ {
+ _saslServers = new HashMap<String, AuthenticationProviderInitialiser>();
+
+ /**
+ * Create Authenticators for Plain Password file.
+ */
+
+ // Accept Plain incomming and compare it to the file.
+ PlainInitialiser plain = new PlainInitialiser();
+ plain.initialise(this);
+
+ // Accept MD5 incomming and Hash file value for comparison
+ CRAMMD5Initialiser cram = new CRAMMD5Initialiser();
+ cram.initialise(this);
+
+ _saslServers.put(plain.getMechanismName(), plain);
+ _saslServers.put(cram.getMechanismName(), cram);
+ }
+
+ public void setPasswordFile(String passwordFile) throws FileNotFoundException
+ {
+ File f = new File(passwordFile);
+ _logger.info("PlainPasswordFile using file " + f.getAbsolutePath());
+ _passwordFile = f;
+ if (!f.exists())
+ {
+ throw new FileNotFoundException("Cannot find password file " + f);
+ }
+ if (!f.canRead())
+ {
+ throw new FileNotFoundException("Cannot read password file " + f +
+ ". Check permissions.");
+ }
+ }
+
+ public void setPassword(Principal principal, PasswordCallback callback) throws IOException,
+ AccountNotFoundException
+ {
+ if (_passwordFile == null)
+ {
+ throw new AccountNotFoundException("Unable to locate principal since no password file was specified during initialisation");
+ }
+ if (principal == null)
+ {
+ throw new IllegalArgumentException("principal must not be null");
+ }
+ char[] pwd = lookupPassword(principal.getName());
+ if (pwd != null)
+ {
+ callback.setPassword(pwd);
+ }
+ else
+ {
+ throw new AccountNotFoundException("No account found for principal " + principal);
+ }
+ }
+
+ public Map<String, AuthenticationProviderInitialiser> getMechanisms()
+ {
+ return _saslServers;
+ }
+
+
+ /**
+ * Looks up the password for a specified user in the password file. Note this code is <b>not</b> secure since it
+ * creates strings of passwords. It should be modified to create only char arrays which get nulled out.
+ *
+ * @param name
+ *
+ * @return
+ *
+ * @throws java.io.IOException
+ */
+ private char[] lookupPassword(String name) throws IOException
+ {
+ BufferedReader reader = null;
+ try
+ {
+ reader = new BufferedReader(new FileReader(_passwordFile));
+ String line;
+
+ while ((line = reader.readLine()) != null)
+ {
+ String[] result = _regexp.split(line);
+ if (result == null || result.length < 2)
+ {
+ continue;
+ }
+
+ if (name.equals(result[0]))
+ {
+ return result[1].toCharArray();
+ }
+ }
+ return null;
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+ }
+ }
+
+ /**
+ * Looks up the virtual hosts for a specified user in the password file.
+ *
+ * @param user The user to lookup
+ *
+ * @return a list of virtualhosts
+ */
+ private String[] lookupVirtualHost(String user)
+ {
+ try
+ {
+ BufferedReader reader = null;
+ try
+ {
+ reader = new BufferedReader(new FileReader(_passwordFile));
+ String line;
+
+ while ((line = reader.readLine()) != null)
+ {
+ String[] result = _regexp.split(line);
+ if (result == null || result.length < 3)
+ {
+ continue;
+ }
+
+ if (user.equals(result[0]))
+ {
+ return result[2].split(",");
+ }
+ }
+ return null;
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+ }
+ }
+ catch (IOException ioe)
+ {
+ //ignore
+ }
+ return null;
+ }
+
+
+ public AccessResult isAuthorized(Accessable accessObject, String username)
+ {
+ if (accessObject instanceof VirtualHost)
+ {
+ String[] hosts = lookupVirtualHost(username);
+
+ if (hosts != null)
+ {
+ for (String host : hosts)
+ {
+ if (accessObject.getAccessableName().equals(host))
+ {
+ return new AccessResult(this, AccessResult.AccessStatus.GRANTED);
+ }
+ }
+ }
+ }
+
+ return new AccessResult(this, AccessResult.AccessStatus.REFUSED);
+ }
+
+ public String getName()
+ {
+ return "PlainPasswordVhostFile";
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/PrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
index e731ea271b..6c5a2a44ee 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/PrincipalDatabase.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
@@ -18,29 +18,33 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth;
+package org.apache.qpid.server.security.auth.database;
+
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
import java.io.IOException;
import java.security.Principal;
+import java.util.Map;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
-/**
- * Represents a "user database" which is really a way of storing principals (i.e. usernames) and
- * passwords.
- */
+/** Represents a "user database" which is really a way of storing principals (i.e. usernames) and passwords. */
public interface PrincipalDatabase
{
/**
- * Set the password for a given principal in the specified callback. This is used for certain
- * SASL providers. The user database implementation should look up the password in any way it
- * chooses and set it in the callback by calling its setPassword method.
+ * Set the password for a given principal in the specified callback. This is used for certain SASL providers. The
+ * user database implementation should look up the password in any way it chooses and set it in the callback by
+ * calling its setPassword method.
+ *
* @param principal the principal
- * @param callback the password callback that wants to receive the password
+ * @param callback the password callback that wants to receive the password
+ *
* @throws AccountNotFoundException if the account for specified principal could not be found
- * @throws IOException if there was an error looking up the principal
+ * @throws IOException if there was an error looking up the principal
*/
void setPassword(Principal principal, PasswordCallback callback)
throws IOException, AccountNotFoundException;
+
+ public Map<String, AuthenticationProviderInitialiser> getMechanisms();
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
new file mode 100644
index 0000000000..83f1201bd8
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
@@ -0,0 +1,30 @@
+/*
+ * 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.auth.database;
+
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+
+import java.util.Map;
+
+public interface PrincipalDatabaseManager
+{
+ public Map<String, PrincipalDatabase> getDatabases();
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
new file mode 100644
index 0000000000..9a58acd98c
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
@@ -0,0 +1,83 @@
+/*
+ * 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.auth.database;
+
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
+import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
+
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.AccountNotFoundException;
+import java.util.Properties;
+import java.util.Map;
+import java.util.HashMap;
+import java.security.Principal;
+import java.io.IOException;
+
+public class PropertiesPrincipalDatabase implements PrincipalDatabase
+{
+ private Properties _users;
+
+ private Map<String, AuthenticationProviderInitialiser> _saslServers;
+
+ public PropertiesPrincipalDatabase(Properties users)
+ {
+ _users = users;
+
+ _saslServers = new HashMap<String, AuthenticationProviderInitialiser>();
+
+ /**
+ * Create Authenticators for Properties Principal Database.
+ */
+
+ // Accept MD5 incomming and use plain comparison with the file
+ PlainInitialiser cram = new PlainInitialiser();
+ cram.initialise(this);
+ // Accept Plain incomming and hash it for comparison to the file.
+ CRAMMD5Initialiser plain = new CRAMMD5Initialiser();
+ plain.initialise(this, CRAMMD5Initialiser.HashDirection.INCOMMING);
+
+ _saslServers.put(plain.getMechanismName(), cram);
+ _saslServers.put(cram.getMechanismName(), plain);
+ }
+
+ public void setPassword(Principal principal, PasswordCallback callback) throws IOException, AccountNotFoundException
+ {
+ if (principal == null)
+ {
+ throw new IllegalArgumentException("principal must not be null");
+ }
+ char[] pwd = _users.getProperty(principal.getName()).toCharArray();
+ if (pwd != null)
+ {
+ callback.setPassword(pwd);
+ }
+ else
+ {
+ throw new AccountNotFoundException("No account found for principal " + principal);
+ }
+ }
+
+ public Map<String, AuthenticationProviderInitialiser> getMechanisms()
+ {
+ return _saslServers;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java
new file mode 100644
index 0000000000..89c84e8130
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java
@@ -0,0 +1,41 @@
+/*
+ * 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.auth.database;
+
+import java.util.Map;
+import java.util.Properties;
+import java.util.HashMap;
+
+public class PropertiesPrincipalDatabaseManager implements PrincipalDatabaseManager
+{
+
+ Map<String, PrincipalDatabase> _databases = new HashMap<String, PrincipalDatabase>();
+
+ public PropertiesPrincipalDatabaseManager(String name, Properties users)
+ {
+ _databases.put(name, new PropertiesPrincipalDatabase(users));
+ }
+
+ public Map<String, PrincipalDatabase> getDatabases()
+ {
+ return _databases;
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationManager.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
index 9f4addd7ee..bb94e0b7bf 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationManager.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
@@ -18,7 +18,10 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth;
+package org.apache.qpid.server.security.auth.manager;
+
+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;
@@ -30,4 +33,5 @@ public interface AuthenticationManager
SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException;
AuthenticationResult authenticate(SaslServer server, byte[] response);
+
}
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
new file mode 100644
index 0000000000..d0862fbb63
--- /dev/null
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -0,0 +1,246 @@
+/*
+ * 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.auth.manager;
+
+import org.apache.log4j.Logger;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.commons.configuration.SubsetConfiguration;
+import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.virtualhost.VirtualHost;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.JCAProvider;
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.SaslServerFactory;
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.Sasl;
+import java.util.Map;
+import java.util.HashMap;
+import java.util.TreeMap;
+import java.security.Security;
+
+public class PrincipalDatabaseAuthenticationManager implements AuthenticationManager
+{
+ private static final Logger _logger = Logger.getLogger(PrincipalDatabaseAuthenticationManager.class);
+
+ /** The list of mechanisms, in the order in which they are configured (i.e. preferred order) */
+ private String _mechanisms;
+
+ /** Maps from the mechanism to the callback handler to use for handling those requests */
+ private Map<String, CallbackHandler> _callbackHandlerMap = new HashMap<String, CallbackHandler>();
+
+ /**
+ * Maps from the mechanism to the properties used to initialise the server. See the method Sasl.createSaslServer for
+ * details of the use of these properties. This map is populated during initialisation of each provider.
+ */
+ private Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>();
+
+ private AuthenticationManager _default = null;
+
+ public PrincipalDatabaseAuthenticationManager(String name, Configuration hostConfig) throws Exception
+ {
+ _logger.info("Initialising " + (name == null ? " Default" : "'" + name + "'")
+ + " PrincipleDatabase 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
+
+ Map<String, Class<? extends SaslServerFactory>> providerMap = new TreeMap<String, Class<? extends SaslServerFactory>>();
+
+
+ if (name == null)
+ {
+ initialiseAuthenticationMechanisms(providerMap, ApplicationRegistry.getInstance().getDatabaseManager().getDatabases());
+ }
+ else
+ {
+ String databaseName = hostConfig.getString("security.authentication.name");
+
+ if (databaseName == null)
+ {
+
+ if (hostConfig instanceof SubsetConfiguration)
+ {
+ _logger.warn("No authentication specified for '" + ((SubsetConfiguration) hostConfig).getPrefix() + "'. Using Default authentication manager");
+ }
+ else
+ {
+ _logger.warn("No authentication specified. Using Default authentication manager");
+ }
+ _default = ApplicationRegistry.getInstance().getAuthenticationManager();
+ return;
+ }
+ else
+ {
+ PrincipalDatabase database = ApplicationRegistry.getInstance().getDatabaseManager().getDatabases().get(databaseName);
+
+ if (database == null)
+ {
+ throw new ConfigurationException("Requested database:" + databaseName + " was not found");
+ }
+
+ initialiseAuthenticationMechanisms(providerMap, database);
+ }
+ }
+
+ if (providerMap.size() > 0)
+ {
+ Security.addProvider(new JCAProvider(providerMap));
+ }
+ else
+ {
+ _logger.warn("No SASL providers availble.");
+ }
+
+ }
+
+
+ private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, Map<String, PrincipalDatabase> databases) throws Exception
+ {
+// Configuration config = ApplicationRegistry.getInstance().getConfiguration();
+// List<String> mechanisms = config.getList("security.sasl.mechanisms.mechanism.initialiser.class");
+//
+// // Maps from the mechanism to the properties used to initialise the server. See the method
+// // Sasl.createSaslServer for details of the use of these properties. This map is populated during initialisation
+// // of each provider.
+
+
+ if (databases.size() > 1)
+ {
+ _logger.warn("More than one principle database provided currently authentication mechanism will override each other.");
+ }
+
+ for (Map.Entry<String, PrincipalDatabase> entry : databases.entrySet())
+ {
+
+ // fixme As the database now provide the mechanisms they support, they will ...
+ // overwrite each other in the map. There should only be one database per vhost.
+ // But currently we must have authentication before vhost definition.
+ initialiseAuthenticationMechanisms(providerMap, entry.getValue());
+ }
+
+ }
+
+ private void initialiseAuthenticationMechanisms(Map<String, Class<? extends SaslServerFactory>> providerMap, PrincipalDatabase database) throws Exception
+ {
+ if (database == null || database.getMechanisms().size() == 0)
+ {
+ _logger.warn("");
+ return;
+ }
+
+ for (AuthenticationProviderInitialiser mechanism : database.getMechanisms().values())
+ {
+ initialiseAuthenticationMechanism(mechanism, providerMap);
+ }
+ }
+
+ private void initialiseAuthenticationMechanism(AuthenticationProviderInitialiser initialiser,
+ Map<String, Class<? extends SaslServerFactory>> providerMap)
+ throws Exception
+ {
+ String mechanism = initialiser.getMechanismName();
+ if (_mechanisms == null)
+ {
+ _mechanisms = mechanism;
+ }
+ else
+ {
+ // simple append should be fine since the number of mechanisms is small and this is a one time initialisation
+ _mechanisms = _mechanisms + " " + mechanism;
+ }
+ _callbackHandlerMap.put(mechanism, initialiser.getCallbackHandler());
+ _serverCreationProperties.put(mechanism, initialiser.getProperties());
+ Class<? extends SaslServerFactory> factory = initialiser.getServerFactoryClassForJCARegistration();
+ if (factory != null)
+ {
+ providerMap.put(mechanism, factory);
+ }
+ _logger.info("Initialised " + mechanism + " SASL provider successfully");
+ }
+
+ public String getMechanisms()
+ {
+ if (_default != null)
+ {
+ // Use the default AuthenticationManager if present
+ return _default.getMechanisms();
+ }
+ else
+ {
+ return _mechanisms;
+ }
+ }
+
+ public SaslServer createSaslServer(String mechanism, String localFQDN) throws SaslException
+ {
+ if (_default != null)
+ {
+ // Use the default AuthenticationManager if present
+ return _default.createSaslServer(mechanism, localFQDN);
+ }
+ else
+ {
+ return Sasl.createSaslServer(mechanism, "AMQP", localFQDN, _serverCreationProperties.get(mechanism),
+ _callbackHandlerMap.get(mechanism));
+ }
+
+ }
+
+ public AuthenticationResult authenticate(SaslServer server, byte[] response)
+ {
+ // Use the default AuthenticationManager if present
+ if (_default != null)
+ {
+ return _default.authenticate(server, response);
+ }
+
+
+ try
+ {
+ // Process response from the client
+ byte[] challenge = server.evaluateResponse(response != null ? response : new byte[0]);
+
+ if (server.isComplete())
+ {
+ return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.SUCCESS);
+ }
+ else
+ {
+ return new AuthenticationResult(challenge, AuthenticationResult.AuthenticationStatus.CONTINUE);
+ }
+ }
+ catch (SaslException e)
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
+ }
+ }
+
+ public AuthenticationResult isAuthorize(VirtualHost vhost, String username)
+ {
+ return new AuthenticationResult(AuthenticationResult.AuthenticationStatus.ERROR);
+ }
+}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainInitialiser.java
deleted file mode 100644
index 9791c13373..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainInitialiser.java
+++ /dev/null
@@ -1,38 +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.auth.plain;
-
-import javax.security.sasl.SaslServerFactory;
-
-import org.apache.qpid.server.security.auth.UsernamePasswordInitialiser;
-
-public class PlainInitialiser extends UsernamePasswordInitialiser
-{
- public String getMechanismName()
- {
- return "PLAIN";
- }
-
- public Class<? extends SaslServerFactory> getServerFactoryClassForJCARegistration()
- {
- return PlainSaslServerFactory.class;
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainSaslServer.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainSaslServer.java
deleted file mode 100644
index 094315dc1f..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainSaslServer.java
+++ /dev/null
@@ -1,149 +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.auth.plain;
-
-import java.io.IOException;
-
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.sasl.AuthorizeCallback;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
-public class PlainSaslServer implements SaslServer
-{
- public static final String MECHANISM = "PLAIN";
-
- private CallbackHandler _cbh;
-
- private String _authorizationId;
-
- private boolean _complete = false;
-
- public PlainSaslServer(CallbackHandler cbh)
- {
- _cbh = cbh;
- }
-
- public String getMechanismName()
- {
- return MECHANISM;
- }
-
- public byte[] evaluateResponse(byte[] response) throws SaslException
- {
- try
- {
- int authzidNullPosition = findNullPosition(response, 0);
- if (authzidNullPosition < 0)
- {
- throw new SaslException("Invalid PLAIN encoding, authzid null terminator not found");
- }
- int authcidNullPosition = findNullPosition(response, authzidNullPosition + 1);
- if (authcidNullPosition < 0)
- {
- throw new SaslException("Invalid PLAIN encoding, authcid null terminator not found");
- }
-
- // we do not currently support authcid in any meaningful way
- // String authcid = new String(response, 0, authzidNullPosition, "utf8");
- String authzid = new String(response, authzidNullPosition + 1, authcidNullPosition - 1, "utf8");
-
- // we do not care about the prompt but it throws if null
- NameCallback nameCb = new NameCallback("prompt", authzid);
- // we do not care about the prompt but it throws if null
- PasswordCallback passwordCb = new PasswordCallback("prompt", false);
- // TODO: should not get pwd as a String but as a char array...
- int passwordLen = response.length - authcidNullPosition - 1;
- String pwd = new String(response, authcidNullPosition + 1, passwordLen, "utf8");
- passwordCb.setPassword(pwd.toCharArray());
- AuthorizeCallback authzCb = new AuthorizeCallback(authzid, authzid);
- Callback[] callbacks = new Callback[]{nameCb, passwordCb, authzCb};
- _cbh.handle(callbacks);
- _complete = true;
- if (authzCb.isAuthorized())
- {
- _authorizationId = authzCb.getAuthenticationID();
- return null;
- }
- else
- {
- throw new SaslException("Authentication failed");
- }
- }
- catch (IOException e)
- {
- throw new SaslException("Error processing data: " + e, e);
- }
- catch (UnsupportedCallbackException e)
- {
- throw new SaslException("Unable to obtain data from callback handler: " + e, e);
- }
- }
-
- private int findNullPosition(byte[] response, int startPosition)
- {
- int position = startPosition;
- while (position < response.length)
- {
- if (response[position] == (byte) 0)
- {
- return position;
- }
- position++;
- }
- return -1;
- }
-
- public boolean isComplete()
- {
- return _complete;
- }
-
- public String getAuthorizationID()
- {
- return _authorizationId;
- }
-
- public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException
- {
- throw new SaslException("Unsupported operation");
- }
-
- public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException
- {
- throw new SaslException("Unsupported operation");
- }
-
- public Object getNegotiatedProperty(String propName)
- {
- return null;
- }
-
- public void dispose() throws SaslException
- {
- _cbh = null;
- }
-
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainSaslServerFactory.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainSaslServerFactory.java
deleted file mode 100644
index 3ea720dd8c..0000000000
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/PlainSaslServerFactory.java
+++ /dev/null
@@ -1,60 +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.auth.plain;
-
-import java.util.Map;
-
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-import javax.security.sasl.SaslServerFactory;
-
-public class PlainSaslServerFactory implements SaslServerFactory
-{
- public SaslServer createSaslServer(String mechanism, String protocol, String serverName, Map props,
- CallbackHandler cbh) throws SaslException
- {
- if (PlainSaslServer.MECHANISM.equals(mechanism))
- {
- return new PlainSaslServer(cbh);
- }
- else
- {
- return null;
- }
- }
-
- public String[] getMechanismNames(Map props)
- {
- if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
- props.containsKey(Sasl.POLICY_NODICTIONARY) ||
- props.containsKey(Sasl.POLICY_NOACTIVE))
- {
- // returned array must be non null according to interface documentation
- return new String[0];
- }
- else
- {
- return new String[]{PlainSaslServer.MECHANISM};
- }
- }
-}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationProviderInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java
index 19e562517e..89e545d6f5 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationProviderInitialiser.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth;
+package org.apache.qpid.server.security.auth.sasl;
import java.util.Map;
@@ -26,6 +26,7 @@ import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.SaslServerFactory;
import org.apache.commons.configuration.Configuration;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
public interface AuthenticationProviderInitialiser
{
@@ -41,11 +42,19 @@ public interface AuthenticationProviderInitialiser
* provider can have its own set of configuration options
* @param configuration the Apache Commons Configuration instance used to configure this provider
* @param principalDatabases the set of principal databases that are available
+ * @throws Exception needs refined Exception is too broad.
*/
void initialise(String baseConfigPath, Configuration configuration,
Map<String, PrincipalDatabase> principalDatabases) throws Exception;
/**
+ * Initialise the authentication provider.
+ * @param db The principal database to initialise with
+ */
+ void initialise(PrincipalDatabase db);
+
+
+ /**
* @return the callback handler that should be used to process authentication requests for this mechanism. This will
* be called after initialise and will be stored by the authentication manager. The callback handler <b>must</b> be
* fully threadsafe.
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/JCAProvider.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
index ac8eae024e..8ffcdc4e36 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/JCAProvider.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth;
+package org.apache.qpid.server.security.auth.sasl;
import java.security.Provider;
import java.security.Security;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePasswordInitialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
index d88c6df548..68095de3a0 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePasswordInitialiser.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth;
+package org.apache.qpid.server.security.auth.sasl;
import java.io.IOException;
import java.security.Principal;
@@ -33,9 +33,15 @@ import javax.security.auth.login.AccountNotFoundException;
import javax.security.sasl.AuthorizeCallback;
import org.apache.commons.configuration.Configuration;
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
public abstract class UsernamePasswordInitialiser implements AuthenticationProviderInitialiser
{
+ protected static final Logger _logger = Logger.getLogger(UsernamePasswordInitialiser.class);
+
private ServerCallbackHandler _callbackHandler;
private class ServerCallbackHandler implements CallbackHandler
@@ -54,7 +60,7 @@ public abstract class UsernamePasswordInitialiser implements AuthenticationProvi
{
if (callback instanceof NameCallback)
{
- username = new UsernamePrincipal(((NameCallback)callback).getDefaultName());
+ username = new UsernamePrincipal(((NameCallback) callback).getDefaultName());
}
else if (callback instanceof PasswordCallback)
{
@@ -71,7 +77,7 @@ public abstract class UsernamePasswordInitialiser implements AuthenticationProvi
}
else if (callback instanceof AuthorizeCallback)
{
- ((AuthorizeCallback)callback).setAuthorized(true);
+ ((AuthorizeCallback) callback).setAuthorized(true);
}
else
{
@@ -79,17 +85,22 @@ public abstract class UsernamePasswordInitialiser implements AuthenticationProvi
}
}
}
- }
+ }
public void initialise(String baseConfigPath, Configuration configuration,
Map<String, PrincipalDatabase> principalDatabases) throws Exception
{
String principalDatabaseName = configuration.getString(baseConfigPath + ".principal-database");
PrincipalDatabase db = principalDatabases.get(principalDatabaseName);
+
+ initialise(db);
+ }
+
+ public void initialise(PrincipalDatabase db)
+ {
if (db == null)
{
- throw new Exception("Principal database " + principalDatabaseName + " not found. Ensure the name matches " +
- "an entry in the configuration file");
+ throw new NullPointerException("Cannot initialise with a null Principal database.");
}
_callbackHandler = new ServerCallbackHandler(db);
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
index e068ba6fe4..f9aaabd15a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
@@ -18,7 +18,7 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth;
+package org.apache.qpid.server.security.auth.sasl;
import java.security.Principal;
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/CRAMMD5Initialiser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java
index 4e428bbf23..264832888d 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/CRAMMD5Initialiser.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java
@@ -18,12 +18,23 @@
* under the License.
*
*/
-package org.apache.qpid.server.security.auth;
+package org.apache.qpid.server.security.auth.sasl.crammd5;
+
+import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import javax.security.sasl.SaslServerFactory;
public class CRAMMD5Initialiser extends UsernamePasswordInitialiser
{
+ private HashDirection _hashDirection;
+
+ public enum HashDirection
+ {
+ INCOMMING, PASSWORD_FILE
+ }
+
+
public String getMechanismName()
{
return "CRAM-MD5";
@@ -33,6 +44,28 @@ public class CRAMMD5Initialiser extends UsernamePasswordInitialiser
{
// since the CRAM-MD5 provider is registered as part of the JDK, we do not
// return the factory class here since we do not need to register it ourselves.
- return null;
+ if (_hashDirection == HashDirection.PASSWORD_FILE)
+ {
+ return null;
+ }
+ else
+ {
+ //fixme we need a server that will correctly has the incomming plain text for comparison to file.
+ _logger.warn("we need a server that will correctly convert the incomming plain text for comparison to file.");
+ return null;
+ }
+ }
+
+ public void initialise(PrincipalDatabase passwordFile)
+ {
+ initialise(passwordFile, HashDirection.PASSWORD_FILE);
}
+
+ public void initialise(PrincipalDatabase passwordFile, HashDirection direction)
+ {
+ super.initialise(passwordFile);
+
+ _hashDirection = direction;
+ }
+
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java
index 217a524562..150b98b424 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java
@@ -23,14 +23,19 @@ package org.apache.qpid.server.util;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashMap;
+import java.util.Properties;
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.MapConfiguration;
import org.apache.qpid.server.management.ManagedObjectRegistry;
import org.apache.qpid.server.management.NoopManagedObjectRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.AuthenticationManager;
-import org.apache.qpid.server.security.auth.NullAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
+import org.apache.qpid.server.security.auth.database.PropertiesPrincipalDatabaseManager;
+import org.apache.qpid.server.security.access.AccessManager;
+import org.apache.qpid.server.security.access.AllowAll;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
@@ -42,6 +47,10 @@ public class NullApplicationRegistry extends ApplicationRegistry
private VirtualHostRegistry _virtualHostRegistry;
+ private AccessManager _accessManager;
+
+ private PrincipalDatabaseManager _databaseManager;
+
public NullApplicationRegistry()
{
@@ -50,14 +59,23 @@ public class NullApplicationRegistry extends ApplicationRegistry
public void initialise() throws Exception
{
- _configuration.addProperty("store.class","org.apache.qpid.server.store.MemoryMessageStore");
+ _configuration.addProperty("store.class", "org.apache.qpid.server.store.MemoryMessageStore");
+
+ Properties users = new Properties();
+
+ users.put("guest", "guest");
+
+ _databaseManager = new PropertiesPrincipalDatabaseManager("default", users);
+
+ _accessManager = new AllowAll();
+
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null);
_managedObjectRegistry = new NoopManagedObjectRegistry();
_virtualHostRegistry = new VirtualHostRegistry();
- VirtualHost dummyHost = new VirtualHost("test",getConfiguration());
+ VirtualHost dummyHost = new VirtualHost("test", getConfiguration());
_virtualHostRegistry.registerVirtualHost(dummyHost);
_virtualHostRegistry.setDefaultVirtualHostName("test");
- _authenticationManager = new NullAuthenticationManager();
_configuration.addProperty("heartbeat.delay", 10 * 60); // 10 minutes
@@ -74,6 +92,11 @@ public class NullApplicationRegistry extends ApplicationRegistry
return _managedObjectRegistry;
}
+ public PrincipalDatabaseManager getDatabaseManager()
+ {
+ return _databaseManager;
+ }
+
public AuthenticationManager getAuthenticationManager()
{
return _authenticationManager;
@@ -81,14 +104,19 @@ public class NullApplicationRegistry extends ApplicationRegistry
public Collection<String> getVirtualHostNames()
{
- String[] hosts = {"test"};
- return Arrays.asList( hosts );
+ String[] hosts = {"test"};
+ return Arrays.asList(hosts);
}
public VirtualHostRegistry getVirtualHostRegistry()
{
return _virtualHostRegistry;
}
+
+ public AccessManager getAccessManager()
+ {
+ return _accessManager;
+ }
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
index e09ce9326c..c24d1aa23a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
@@ -25,6 +25,11 @@ import javax.management.NotCompliantMBeanException;
import org.apache.commons.configuration.Configuration;
import org.apache.log4j.Logger;
import org.apache.qpid.server.AMQBrokerManagerMBean;
+import org.apache.qpid.server.security.access.AccessManager;
+import org.apache.qpid.server.security.access.AccessManagerImpl;
+import org.apache.qpid.server.security.access.Accessable;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
import org.apache.qpid.server.configuration.Configurator;
import org.apache.qpid.server.exchange.DefaultExchangeFactory;
import org.apache.qpid.server.exchange.DefaultExchangeRegistry;
@@ -37,7 +42,7 @@ import org.apache.qpid.server.queue.QueueRegistry;
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.store.MessageStore;
-public class VirtualHost
+public class VirtualHost implements Accessable
{
private static final Logger _logger = Logger.getLogger(VirtualHost.class);
@@ -50,84 +55,103 @@ public class VirtualHost
private ExchangeFactory _exchangeFactory;
- private MessageStore _messageStore;
+ private MessageStore _messageStore;
protected VirtualHostMBean _virtualHostMBean;
private AMQBrokerManagerMBean _brokerMBean;
+ private AuthenticationManager _authenticationManager;
- /**
- * Abstract MBean class. This has some of the methods implemented from
- * management intrerface for exchanges. Any implementaion of an
- * Exchange MBean should extend this class.
- */
- public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtualHost
- {
- public VirtualHostMBean() throws NotCompliantMBeanException
- {
- super(ManagedVirtualHost.class, "VirtualHost");
- }
+ private AccessManager _accessManager;
- public String getObjectInstanceName()
- {
- return _name.toString();
- }
+ public void setAccessableName(String name)
+ {
+ _logger.warn("Setting Accessable Name for VirualHost is not allowed. ("
+ + name + ") ignored remains :" + getAccessableName());
+ }
- public String getName()
- {
- return _name.toString();
- }
+ public String getAccessableName()
+ {
+ return _name;
+ }
- public VirtualHost getVirtualHost()
- {
- return VirtualHost.this;
- }
+ /**
+ * Abstract MBean class. This has some of the methods implemented from management intrerface for exchanges. Any
+ * implementaion of an Exchange MBean should extend this class.
+ */
+ public class VirtualHostMBean extends AMQManagedObject implements ManagedVirtualHost
+ {
+ public VirtualHostMBean() throws NotCompliantMBeanException
+ {
+ super(ManagedVirtualHost.class, "VirtualHost");
+ }
- } // End of MBean class
+ public String getObjectInstanceName()
+ {
+ return _name.toString();
+ }
+ public String getName()
+ {
+ return _name.toString();
+ }
- public VirtualHost(String name, MessageStore store) throws Exception
- {
- _name = name;
+ public VirtualHost getVirtualHost()
+ {
+ return VirtualHost.this;
+ }
- _virtualHostMBean = new VirtualHostMBean();
- // This isn't needed to be registered
- //_virtualHostMBean.register();
- _queueRegistry = new DefaultQueueRegistry(this);
- _exchangeFactory = new DefaultExchangeFactory(this);
- _exchangeRegistry = new DefaultExchangeRegistry(this);
-
- _messageStore = store;
-
- _exchangeRegistry.initialise();
+ } // End of MBean class
- _brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean);
- _brokerMBean.register();
+ public VirtualHost(String name, MessageStore store) throws Exception
+ {
+ this(name, null, store);
}
+
public VirtualHost(String name, Configuration hostConfig) throws Exception
{
+ this(name, hostConfig, null);
+ }
+
+ private VirtualHost(String name, Configuration hostConfig, MessageStore store) throws Exception
+ {
_name = name;
_virtualHostMBean = new VirtualHostMBean();
// This isn't needed to be registered
//_virtualHostMBean.register();
-
+
_queueRegistry = new DefaultQueueRegistry(this);
_exchangeFactory = new DefaultExchangeFactory(this);
_exchangeRegistry = new DefaultExchangeRegistry(this);
- initialiseMessageStore(hostConfig);
+ if (store != null)
+ {
+ _messageStore = store;
+ }
+ else
+ {
+ if (hostConfig == null)
+ {
+ throw new IllegalAccessException("HostConfig and MessageStore cannot be null");
+ }
+ initialiseMessageStore(hostConfig);
+ }
_exchangeRegistry.initialise();
+ _logger.warn("VirtualHost authentication Managers require spec change to be operational.");
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(name, hostConfig);
+
+ _accessManager = new AccessManagerImpl(name, hostConfig);
+
_brokerMBean = new AMQBrokerManagerMBean(_virtualHostMBean);
_brokerMBean.register();
-
}
private void initialiseMessageStore(Configuration config) throws Exception
@@ -140,15 +164,13 @@ public class VirtualHost
if (!(o instanceof MessageStore))
{
throw new ClassCastException("Message store class must implement " + MessageStore.class + ". Class " + clazz +
- " does not.");
+ " does not.");
}
_messageStore = (MessageStore) o;
_messageStore.configure(this, "store", config);
}
-
-
public <T> T getConfiguredObject(Class<T> instanceType, Configuration config)
{
T instance;
@@ -171,7 +193,7 @@ public class VirtualHost
{
return _name;
}
-
+
public QueueRegistry getQueueRegistry()
{
return _queueRegistry;
@@ -189,7 +211,7 @@ public class VirtualHost
public ApplicationRegistry getApplicationRegistry()
{
- throw new UnsupportedOperationException();
+ throw new UnsupportedOperationException();
}
public MessageStore getMessageStore()
@@ -197,9 +219,19 @@ public class VirtualHost
return _messageStore;
}
+ public AuthenticationManager getAuthenticationManager()
+ {
+ return _authenticationManager;
+ }
+
+ public AccessManager getAccessManager()
+ {
+ return _accessManager;
+ }
+
public void close() throws Exception
{
- if(_messageStore != null)
+ if (_messageStore != null)
{
_messageStore.close();
}
@@ -210,8 +242,6 @@ public class VirtualHost
return _brokerMBean;
}
-
-
public ManagedObject getManagedObject()
{
return _virtualHostMBean;
diff --git a/java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java b/java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java
index aba2d5d657..cb8adae18c 100644
--- a/java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java
+++ b/java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java
@@ -38,7 +38,7 @@ public class ChannelFlowTest implements MessageListener
ChannelFlowTest(String broker) throws Exception
{
- this(new AMQConnection(broker, "guest", "guest", randomize("Client"), "/test_path"));
+ this(new AMQConnection(broker, "guest", "guest", randomize("Client"), "/test"));
}
ChannelFlowTest(AMQConnection connection) throws Exception
diff --git a/java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java b/java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java
index 8d833f4d4c..4865a68dc4 100644
--- a/java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java
+++ b/java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java
@@ -48,7 +48,7 @@ public class LatencyTest implements MessageListener
LatencyTest(String broker, int count, int delay, int length) throws Exception
{
- this(new AMQConnection(broker, "guest", "guest", randomize("Client"), "/test_path"), count, delay, length);
+ this(new AMQConnection(broker, "guest", "guest", randomize("Client"), "/test"), count, delay, length);
}
LatencyTest(AMQConnection connection, int count, int delay, int length) throws Exception
diff --git a/java/client/src/test/java/org/apache/qpid/client/DispatcherTest.java b/java/client/src/test/java/org/apache/qpid/client/DispatcherTest.java
index cf26a54f1b..1d85ea47fd 100644
--- a/java/client/src/test/java/org/apache/qpid/client/DispatcherTest.java
+++ b/java/client/src/test/java/org/apache/qpid/client/DispatcherTest.java
@@ -82,7 +82,7 @@ public class DispatcherTest extends TestCase
Hashtable<String, String> env = new Hashtable<String, String>();
- env.put("connectionfactory.connection", "amqp://client:client@MLT_ID/test?brokerlist='vm://:1'");
+ env.put("connectionfactory.connection", "amqp://guest:guest@MLT_ID/test?brokerlist='vm://:1'");
env.put("queue.queue", "MessageListenerTest");
_context = factory.getInitialContext(env);
diff --git a/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java b/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java
index 6062528d43..a406f9f86e 100644
--- a/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java
+++ b/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java
@@ -74,7 +74,7 @@ public class MessageListenerMultiConsumerTest extends TestCase
Hashtable<String, String> env = new Hashtable<String, String>();
- env.put("connectionfactory.connection", "amqp://client:client@MLT_ID/test?brokerlist='vm://:1'");
+ env.put("connectionfactory.connection", "amqp://guest:guest@MLT_ID/test?brokerlist='vm://:1'");
env.put("queue.queue", "direct://amq.direct//MessageListenerTest");
_context = factory.getInitialContext(env);
diff --git a/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java b/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java
index dc01005247..5fb77af4db 100644
--- a/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java
+++ b/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java
@@ -73,7 +73,7 @@ public class MessageListenerTest extends TestCase implements MessageListener
Hashtable<String, String> env = new Hashtable<String, String>();
- env.put("connectionfactory.connection", "amqp://client:client@MLT_ID/test?brokerlist='vm://:1'");
+ env.put("connectionfactory.connection", "amqp://guest:guest@MLT_ID/test?brokerlist='vm://:1'");
env.put("queue.queue", "MessageListenerTest");
_context = factory.getInitialContext(env);
diff --git a/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java b/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java
index 08501c9554..10bf1a8d6d 100644
--- a/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java
+++ b/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java
@@ -82,7 +82,7 @@ public class ResetMessageListenerTest extends TestCase
Hashtable<String, String> env = new Hashtable<String, String>();
- env.put("connectionfactory.connection", "amqp://client:client@MLT_ID/test?brokerlist='vm://:1'");
+ env.put("connectionfactory.connection", "amqp://guest:guest@MLT_ID/test?brokerlist='vm://:1'");
env.put("queue.queue", "direct://amq.direct//MessageListenerTest");
_context = factory.getInitialContext(env);
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
index d9ce080e14..ab0d26b0e0 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
@@ -73,7 +73,7 @@ public class ConnectionTest extends TestCase
{
try
{
- AMQConnection conn = new AMQConnection("amqp://guest:guestd@clientid/test?brokerlist='"
+ AMQConnection conn = new AMQConnection("amqp://guest:guest@clientid/test?brokerlist='"
+ _broker
+ "?retries='1''&defaultQueueExchange='test.direct'"
+ "&defaultTopicExchange='test.topic'"
@@ -115,13 +115,12 @@ public class ConnectionTest extends TestCase
}
}
-
- // FIXME The inVM broker currently has no authentication .. Needs added QPID-70
- public void passwordFailureConnection() throws Exception
+ //fixme AMQAuthenticationException is not propogaged
+ public void PasswordFailureConnection() throws Exception
{
try
{
- new AMQConnection("amqp://guest:rubbishpassword@clientid/testpath?brokerlist='" + _broker + "?retries='1''");
+ new AMQConnection("amqp://guest:rubbishpassword@clientid/test?brokerlist='" + _broker + "?retries='1''");
fail("Connection should not be established password is wrong.");
}
catch (AMQException amqe)
diff --git a/java/client/src/test/java/org/apache/qpid/test/unit/close/CloseBeforeAckTest.java b/java/client/src/test/java/org/apache/qpid/test/unit/close/CloseBeforeAckTest.java
index 5cee306846..117696196e 100644
--- a/java/client/src/test/java/org/apache/qpid/test/unit/close/CloseBeforeAckTest.java
+++ b/java/client/src/test/java/org/apache/qpid/test/unit/close/CloseBeforeAckTest.java
@@ -41,10 +41,8 @@ import uk.co.thebadgerset.junit.concurrency.ThreadTestCoordinator;
* Running in AUTO_ACK mode, the close call ought to wait until the onMessage method completes, and the ack is sent
* before closing the connection.
*
- * <p><table id="crc"><caption>CRC Card</caption>
- * <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Check that closing a connection whilst handling a message, blocks till completion of the handler.
- * </table>
+ * <p><table id="crc"><caption>CRC Card</caption> <tr><th> Responsibilities <th> Collaborations <tr><td> Check that
+ * closing a connection whilst handling a message, blocks till completion of the handler. </table>
*/
public class CloseBeforeAckTest extends TestCase
{
@@ -53,6 +51,7 @@ public class CloseBeforeAckTest extends TestCase
Connection connection;
Session session;
public static final String TEST_QUEUE_NAME = "TestQueue";
+ private int TEST_COUNT = 25;
class TestThread1 extends TestRunnable implements MessageListener
{
@@ -65,34 +64,34 @@ public class CloseBeforeAckTest extends TestCase
public void onMessage(Message message)
{
// Give thread 2 permission to close the session.
- allow(new int[] { 1 });
+ allow(new int[]{1});
// Wait until thread 2 has closed the connection, or is blocked waiting for this to complete.
- waitFor(new int[] { 1 }, true);
+ waitFor(new int[]{1}, true);
}
}
TestThread1 testThread1 = new TestThread1();
TestRunnable testThread2 =
- new TestRunnable()
- {
- public void runWithExceptions() throws Exception
+ new TestRunnable()
{
- // Send a message to be picked up by thread 1.
- session.createProducer(null).send(session.createQueue(TEST_QUEUE_NAME),
- session.createTextMessage("Hi there thread 1!"));
+ public void runWithExceptions() throws Exception
+ {
+ // Send a message to be picked up by thread 1.
+ session.createProducer(null).send(session.createQueue(TEST_QUEUE_NAME),
+ session.createTextMessage("Hi there thread 1!"));
- // Wait for thread 1 to pick up the message and give permission to continue.
- waitFor(new int[] { 0 }, false);
+ // Wait for thread 1 to pick up the message and give permission to continue.
+ waitFor(new int[]{0}, false);
- // Close the connection.
- session.close();
+ // Close the connection.
+ session.close();
- // Allow thread 1 to continue to completion, if it is erronously still waiting.
- allow(new int[] { 1 });
- }
- };
+ // Allow thread 1 to continue to completion, if it is erronously still waiting.
+ allow(new int[]{1});
+ }
+ };
public void testCloseBeforeAutoAck_QPID_397() throws Exception
{
@@ -123,9 +122,9 @@ public class CloseBeforeAckTest extends TestCase
Assert.assertTrue(errorMessage, "".equals(errorMessage));
}
- public void testCloseBeforeAutoAckManyTimes() throws Exception
+ public void closeBeforeAutoAckManyTimes() throws Exception
{
- for (int i = 0; i < 500; i++)
+ for (int i = 0; i < TEST_COUNT; i++)
{
testCloseBeforeAutoAck_QPID_397();
}
diff --git a/java/client/src/test/java/org/apache/qpid/testutil/Config.java b/java/client/src/test/java/org/apache/qpid/testutil/Config.java
index e5b4834622..8109d20a33 100644
--- a/java/client/src/test/java/org/apache/qpid/testutil/Config.java
+++ b/java/client/src/test/java/org/apache/qpid/testutil/Config.java
@@ -136,7 +136,7 @@ public class Config
public Connection getConnection() throws Exception
{
System.out.println("Connecting to " + host + " on " + port + "...");
- return new AMQConnection(host, port, "guest", "guest", "Client" + System.currentTimeMillis(), "/test_path");
+ return new AMQConnection(host, port, "guest", "guest", "Client" + System.currentTimeMillis(), "/test");
}
public boolean setOptions(String[] argv)
diff --git a/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java b/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java
index 508d88f941..8795adbc55 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java
@@ -177,6 +177,16 @@ public class MockProtocolSession implements AMQProtocolSession
return ProtocolOutputConverterRegistry.getConverter(this);
}
+ public void setAuthorizedID(String authorizedID)
+ {
+ //To change body of implemented methods use File | Settings | File Templates.
+ }
+
+ public String getAuthorizedID()
+ {
+ return null; //To change body of implemented methods use File | Settings | File Templates.
+ }
+
public byte getProtocolMajorVersion()
{
return 8; //To change body of implemented methods use File | Settings | File Templates.
diff --git a/java/systests/src/main/java/org/apache/qpid/server/util/TestApplicationRegistry.java b/java/systests/src/main/java/org/apache/qpid/server/util/TestApplicationRegistry.java
index 849285e6d6..bd7ed60d1d 100644
--- a/java/systests/src/main/java/org/apache/qpid/server/util/TestApplicationRegistry.java
+++ b/java/systests/src/main/java/org/apache/qpid/server/util/TestApplicationRegistry.java
@@ -20,18 +20,18 @@
*/
package org.apache.qpid.server.util;
-import org.apache.qpid.server.exchange.DefaultExchangeFactory;
-import org.apache.qpid.server.exchange.DefaultExchangeRegistry;
import org.apache.qpid.server.exchange.ExchangeFactory;
import org.apache.qpid.server.exchange.ExchangeRegistry;
import org.apache.qpid.server.management.ManagedObjectRegistry;
-import org.apache.qpid.server.management.NoopManagedObjectRegistry;
-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.auth.AuthenticationManager;
-import org.apache.qpid.server.security.auth.NullAuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.PrincipalDatabaseAuthenticationManager;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
+import org.apache.qpid.server.security.auth.database.PropertiesPrincipalDatabaseManager;
+import org.apache.qpid.server.security.access.AccessManager;
+import org.apache.qpid.server.security.access.AllowAll;
import org.apache.qpid.server.store.MessageStore;
import org.apache.qpid.server.store.TestableMemoryMessageStore;
import org.apache.qpid.server.virtualhost.VirtualHost;
@@ -41,6 +41,7 @@ import org.apache.commons.configuration.MapConfiguration;
import java.util.HashMap;
import java.util.Collection;
+import java.util.Properties;
public class TestApplicationRegistry extends ApplicationRegistry
{
@@ -52,6 +53,10 @@ public class TestApplicationRegistry extends ApplicationRegistry
private ManagedObjectRegistry _managedObjectRegistry;
+ private AccessManager _accessManager;
+
+ private PrincipalDatabaseManager _databaseManager;
+
private AuthenticationManager _authenticationManager;
private MessageStore _messageStore;
@@ -64,13 +69,23 @@ public class TestApplicationRegistry extends ApplicationRegistry
public void initialise() throws Exception
{
+ Properties users = new Properties();
+
+ users.put("guest", "guest");
+
+ _databaseManager = new PropertiesPrincipalDatabaseManager("default", users);
+
+ _accessManager = new AllowAll();
+
+ _authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null);
+
IApplicationRegistry appRegistry = ApplicationRegistry.getInstance();
_managedObjectRegistry = appRegistry.getManagedObjectRegistry();
_vHost = appRegistry.getVirtualHostRegistry().getVirtualHost("test");
_queueRegistry = _vHost.getQueueRegistry();
_exchangeFactory = _vHost.getExchangeFactory();
_exchangeRegistry = _vHost.getExchangeRegistry();
- _authenticationManager = new NullAuthenticationManager();
+
_messageStore = new TestableMemoryMessageStore();
_configuration.addProperty("heartbeat.delay", 10 * 60); // 10 minutes
@@ -101,6 +116,11 @@ public class TestApplicationRegistry extends ApplicationRegistry
return _managedObjectRegistry;
}
+ public PrincipalDatabaseManager getDatabaseManager()
+ {
+ return _databaseManager;
+ }
+
public AuthenticationManager getAuthenticationManager()
{
return _authenticationManager;
@@ -116,6 +136,11 @@ public class TestApplicationRegistry extends ApplicationRegistry
return null; //To change body of implemented methods use File | Settings | File Templates.
}
+ public AccessManager getAccessManager()
+ {
+ return _accessManager;
+ }
+
public MessageStore getMessageStore()
{
return _messageStore;
diff --git a/java/systests/src/main/java/org/apache/qpid/test/VMTestCase.java b/java/systests/src/main/java/org/apache/qpid/test/VMTestCase.java
index bbac06382d..31fd77691d 100644
--- a/java/systests/src/main/java/org/apache/qpid/test/VMTestCase.java
+++ b/java/systests/src/main/java/org/apache/qpid/test/VMTestCase.java
@@ -84,7 +84,7 @@ public class VMTestCase extends TestCase
_brokerlist = "vm://:1";
}
- env.put("connectionfactory.connection", "amqp://client:client@" +
+ env.put("connectionfactory.connection", "amqp://guest:guest@" +
_clientID + _virtualhost + "?brokerlist='" + _brokerlist + "'");
for (Map.Entry<String, String> c : _connections.entrySet())