You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by ri...@apache.org on 2007/03/16 15:46:44 UTC

svn commit: r518988 [1/2] - in /incubator/qpid/trunk/qpid/java: broker/etc/ broker/src/main/java/org/apache/qpid/server/handler/ broker/src/main/java/org/apache/qpid/server/protocol/ broker/src/main/java/org/apache/qpid/server/registry/ broker/src/main...

Author: ritchiem
Date: Fri Mar 16 07:46:42 2007
New Revision: 518988

URL: http://svn.apache.org/viewvc?view=rev&rev=518988
Log:
QPID-70 InVM Authentication QPID-419 Access Control QPID-423 Authentication per virtualhost
Restructured auth package.
Enabled InVM Authentication
Initial changes to allow authenticators per virtualhost.
Initial access control classes.
Initial work to allow access control testing through inVM broker.


Added:
    incubator/qpid/trunk/qpid/java/broker/etc/md5passwd
    incubator/qpid/trunk/qpid/java/broker/etc/passwdVhost
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java   (with props)
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java   (with props)
Removed:
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationManager.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationProviderInitialiser.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/CRAMMD5Initialiser.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/JCAProvider.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/NullAuthenticationManager.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/PasswordFilePrincipalDatabase.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/PrincipalDatabase.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/SASLAuthenticationManager.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePasswordInitialiser.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/UsernamePrincipal.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/amqplain/
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/plain/
Modified:
    incubator/qpid/trunk/qpid/java/broker/etc/config.xml
    incubator/qpid/trunk/qpid/java/broker/etc/virtualhosts.xml
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/util/NullApplicationRegistry.java
    incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
    incubator/qpid/trunk/qpid/java/client/src/old_test/java/org/apache/qpid/flow/ChannelFlowTest.java
    incubator/qpid/trunk/qpid/java/client/src/old_test/java/org/apache/qpid/latency/LatencyTest.java
    incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/client/DispatcherTest.java
    incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerMultiConsumerTest.java
    incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/client/MessageListenerTest.java
    incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/client/ResetMessageListenerTest.java
    incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java
    incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/test/unit/close/CloseBeforeAckTest.java
    incubator/qpid/trunk/qpid/java/client/src/test/java/org/apache/qpid/testutil/Config.java
    incubator/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/server/queue/MockProtocolSession.java
    incubator/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/server/util/TestApplicationRegistry.java
    incubator/qpid/trunk/qpid/java/systests/src/main/java/org/apache/qpid/test/VMTestCase.java

Modified: incubator/qpid/trunk/qpid/java/broker/etc/config.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/etc/config.xml?view=diff&rev=518988&r1=518987&r2=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/etc/config.xml (original)
+++ incubator/qpid/trunk/qpid/java/broker/etc/config.xml Fri Mar 16 07:46:42 2007
@@ -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>

Added: incubator/qpid/trunk/qpid/java/broker/etc/md5passwd
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/etc/md5passwd?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/etc/md5passwd (added)
+++ incubator/qpid/trunk/qpid/java/broker/etc/md5passwd Fri Mar 16 07:46:42 2007
@@ -0,0 +1 @@
+guest:qfgyy4ewnVMBg

Added: incubator/qpid/trunk/qpid/java/broker/etc/passwdVhost
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/etc/passwdVhost?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/etc/passwdVhost (added)
+++ incubator/qpid/trunk/qpid/java/broker/etc/passwdVhost Fri Mar 16 07:46:42 2007
@@ -0,0 +1 @@
+guest:guest:localhost,test

Modified: incubator/qpid/trunk/qpid/java/broker/etc/virtualhosts.xml
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/etc/virtualhosts.xml?view=diff&rev=518988&r1=518987&r2=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/etc/virtualhosts.xml (original)
+++ incubator/qpid/trunk/qpid/java/broker/etc/virtualhosts.xml Fri Mar 16 07:46:42 2007
@@ -23,7 +23,7 @@
     <default>test</default>
     <virtualhost>
         <name>localhost</name>
-        <localhost>
+        <localhost>            
             <exchanges>
                 <exchange>
                     <type>direct</type>

Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java?view=diff&rev=518988&r1=518987&r2=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionOpenMethodHandler.java Fri Mar 16 07:46:42 2007
@@ -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.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 @@
 
         //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 @@
 
         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 @@
             // 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);
         }

Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java?view=diff&rev=518988&r1=518987&r2=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionSecureOkMethodHandler.java Fri Mar 16 07:46:42 2007
@@ -35,7 +35,7 @@
 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 @@
         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 @@
                     ConnectionStartOkMethodHandler.getConfiguredFrameSize(),	// frameMax
                     HeartbeatConfig.getInstance().getDelay());	// heartbeat
                 session.writeFrame(tune);
+                session.setAuthorizedID(ss.getAuthorizationID());                
                 disposeSaslServer(session);
                 break;
             case CONTINUE:

Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java?view=diff&rev=518988&r1=518987&r2=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/handler/ConnectionStartOkMethodHandler.java Fri Mar 16 07:46:42 2007
@@ -31,10 +31,11 @@
 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 @@
         _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 @@
                     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 @@
                     // 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);
             }
         }

Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java?view=diff&rev=518988&r1=518987&r2=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQMinaProtocolSession.java Fri Mar 16 07:46:42 2007
@@ -106,6 +106,7 @@
     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 @@
         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 @@
 
     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 @@
         return _protocolOutputConverter;
     }
 
+    public void setAuthorizedID(String authorizedID)
+    {
+        _authorizedID = authorizedID;
+    }
+
+    public String getAuthorizedID()
+    {
+        return _authorizedID;
+    }
 
 }

Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java?view=diff&rev=518988&r1=518987&r2=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/protocol/AMQProtocolSession.java Fri Mar 16 07:46:42 2007
@@ -165,4 +165,9 @@
 
     public ProtocolOutputConverter getProtocolOutputConverter();
 
+    void setAuthorizedID(String authorizedID);
+
+    /** @return a username string that was used to authorized this session */    
+    String getAuthorizedID();
+
 }

Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java?view=diff&rev=518988&r1=518987&r2=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java Fri Mar 16 07:46:42 2007
@@ -34,8 +34,12 @@
 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 @@
 
     private AuthenticationManager _authenticationManager;
 
+    private AccessManager _accessManager;
+
+    private PrincipalDatabaseManager _databaseManager;
+
     private VirtualHostRegistry _virtualHostRegistry;
 
 
@@ -59,26 +67,33 @@
 
     // 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 @@
     {
         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 @@
         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 Collection<String> getVirtualHostNames()
     {
-        return  getConfiguration().getList("virtualhosts.virtualhost.name");
+        return getConfiguration().getList("virtualhosts.virtualhost.name");
     }
 }

Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java?view=diff&rev=518988&r1=518987&r2=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/IApplicationRegistry.java Fri Mar 16 07:46:42 2007
@@ -24,7 +24,9 @@
 
 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 @@
 
     ManagedObjectRegistry getManagedObjectRegistry();
 
+    PrincipalDatabaseManager getDatabaseManager();
+
     AuthenticationManager getAuthenticationManager();
 
     Collection<String> getVirtualHostNames();
 
     VirtualHostRegistry getVirtualHostRegistry();
+
+    AccessManager getAccessManager();
 }

Added: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java (added)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java Fri Mar 16 07:46:42 2007
@@ -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();
+
+}

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java (added)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java Fri Mar 16 07:46:42 2007
@@ -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";
+    }
+}

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java (added)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java Fri Mar 16 07:46:42 2007
@@ -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());
+    }
+
+
+}

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessResult.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java (added)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java Fri Mar 16 07:46:42 2007
@@ -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();    
+}

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/Accessable.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java (added)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java Fri Mar 16 07:46:42 2007
@@ -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";
+    }
+}

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java (added)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java Fri Mar 16 07:46:42 2007
@@ -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";
+    }
+}

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java (added)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java Fri Mar 16 07:46:42 2007
@@ -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";
+    }
+
+}

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java (added)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java Fri Mar 16 07:46:42 2007
@@ -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;
+    }
+}

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java (added)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java Fri Mar 16 07:46:42 2007
@@ -0,0 +1,161 @@
+/*
+ *  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 MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
+{
+    private static final Logger _logger = Logger.getLogger(MD5PasswordFilePrincipalDatabase.class);
+
+    private File _passwordFile;
+
+    private Pattern _regexp = Pattern.compile(":");
+
+    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
+    {
+        File f = new File(passwordFile);
+        _logger.info("PasswordFilePrincipalDatabase 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();
+            }
+        }
+    }
+}

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java (added)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java Fri Mar 16 07:46:42 2007
@@ -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();
+            }
+        }
+    }
+}

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java?view=auto&rev=518988
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java (added)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java Fri Mar 16 07:46:42 2007
@@ -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";
+    }
+}