Author: ritchiem
Date: Fri Jun  6 09:03:48 2008
New Revision: 664001

URL: http://svn.apache.org/viewvc?rev=664001&view=rev
Log:
QPID-1058 : Addition of a CRAM-MD5-HEX as discussed on the JIRA. An additional 
test is provided to ensure that the handle method correctly wraps a given 
Database password in hex.

Added:
    
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
   (contents, props changed)
      - copied, changed from r663950, 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java
    
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java
   (contents, props changed)
      - copied, changed from r663950, 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java
    
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java
   (contents, props changed)
      - copied, changed from r663950, 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java
    
incubator/qpid/branches/M2.x/java/broker/src/test/java/org/apache/qpid/server/securiity/
    
incubator/qpid/branches/M2.x/java/broker/src/test/java/org/apache/qpid/server/securiity/auth/
    
incubator/qpid/branches/M2.x/java/broker/src/test/java/org/apache/qpid/server/securiity/auth/sasl/
    
incubator/qpid/branches/M2.x/java/broker/src/test/java/org/apache/qpid/server/securiity/auth/sasl/CRAMMD5HexInitialiserTest.java
   (with props)
Modified:
    
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java

Modified: 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java?rev=664001&r1=664000&r2=664001&view=diff
==============================================================================
--- 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
 (original)
+++ 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
 Fri Jun  6 09:03:48 2008
@@ -24,6 +24,7 @@
 import 
org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
 import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
 import 
org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser;
+import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexInitialiser;
 import 
org.apache.qpid.server.security.access.management.AMQUserManagementMBean;
 import org.apache.commons.codec.binary.Base64;
 import org.apache.commons.codec.EncoderException;
@@ -81,6 +82,11 @@
         cram.initialise(this);
         _saslServers.put(cram.getMechanismName(), cram);
 
+        //Add the Hex initialiser
+        CRAMMD5HexInitialiser cramHex = new CRAMMD5HexInitialiser();
+        cramHex.initialise(this);
+        _saslServers.put(cramHex.getMechanismName(), cramHex);
+
         //fixme The PDs should setup a PD Mangement MBean
 //        try
 //        {
@@ -284,7 +290,6 @@
         return true;
     }
 
-
     public Map<String, AuthenticationProviderInitialiser> getMechanisms()
     {
         return _saslServers;
@@ -325,7 +330,6 @@
         }
     }
 
-
     private void loadPasswordFile() throws IOException
     {
         try
@@ -553,7 +557,6 @@
             _encodedPassword = null;
         }
 
-
         byte[] getEncodePassword() throws EncoderException, 
UnsupportedEncodingException, NoSuchAlgorithmException
         {
             if (_encodedPassword == null)

Copied: 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
 (from r663950, 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java)
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java?p2=incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java&p1=incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java&r1=663950&r2=664001&rev=664001&view=diff
==============================================================================
--- 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java
 (original)
+++ 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
 Fri Jun  6 09:03:48 2008
@@ -20,31 +20,120 @@
  */
 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 org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
+import 
org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
 
 import javax.security.sasl.SaslServerFactory;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.AccountNotFoundException;
 import java.util.Map;
+import java.util.List;
+import java.security.Principal;
+import java.io.IOException;
 
-public class CRAMMD5HashedInitialiser extends UsernamePasswordInitialiser
+public class CRAMMD5HexInitialiser extends UsernamePasswordInitialiser
 {
     public String getMechanismName()
     {
-        return CRAMMD5HashedSaslServer.MECHANISM;
+        return CRAMMD5HexSaslServer.MECHANISM;
     }
 
     public Class<? extends SaslServerFactory> 
getServerFactoryClassForJCARegistration()
     {
-        return CRAMMD5HashedServerFactory.class;
+        return CRAMMD5HexServerFactory.class;
     }
 
-    public void initialise(PrincipalDatabase passwordFile)
+    public Map<String, ?> getProperties()
     {
-        super.initialise(passwordFile);
+        return null;
     }
 
-    public Map<String, ?> getProperties()
+    public void initialise(PrincipalDatabase db)
     {
-        return null;
+        super.initialise(new HexifyPrincipalDatabase(db));
+
+    }
+
+    private class HexifyPrincipalDatabase implements PrincipalDatabase
+    {
+        private PrincipalDatabase _realPricipalDatabase;
+
+        HexifyPrincipalDatabase(PrincipalDatabase db)
+        {
+            _realPricipalDatabase = db;
+        }
+
+        private char[] toHex(char[] password)
+        {
+            StringBuilder sb = new StringBuilder();
+            for (char c : password)
+            {
+                //toHexString does not prepend 0 so we have to
+                if (((byte) c > -1) && (byte) c < 10)
+                {
+                    sb.append(0);
+                }
+
+                sb.append(Integer.toHexString(c & 0xFF));
+            }
+
+            //Extract the hex string as char[]
+            char[] hex = new char[sb.length()];
+
+            sb.getChars(0, sb.length(), hex, 0);
+
+            return hex;
+        }
+
+        public void setPassword(Principal principal, PasswordCallback 
callback) throws IOException, AccountNotFoundException
+        {
+            //Let the read DB set the password
+            _realPricipalDatabase.setPassword(principal, callback);
+
+            //Retrieve the setpassword
+            char[] plainPassword = callback.getPassword();
+
+            char[] hexPassword = toHex(plainPassword);
+
+            callback.setPassword(hexPassword);
+        }
+
+        // Simply delegate to the real PrincipalDB
+        public boolean verifyPassword(String principal, char[] password) 
throws AccountNotFoundException
+        {
+            return _realPricipalDatabase.verifyPassword(principal, password);
+        }
+
+        public boolean updatePassword(Principal principal, char[] password) 
throws AccountNotFoundException
+        {
+            return _realPricipalDatabase.updatePassword(principal, password);
+        }
+
+        public boolean createPrincipal(Principal principal, char[] password)
+        {
+            return _realPricipalDatabase.createPrincipal(principal, password);
+        }
+
+        public boolean deletePrincipal(Principal principal) throws 
AccountNotFoundException
+        {
+            return _realPricipalDatabase.deletePrincipal(principal);
+        }
+
+        public Principal getUser(String username)
+        {
+            return _realPricipalDatabase.getUser(username);
+        }
+
+        public Map<String, AuthenticationProviderInitialiser> getMechanisms()
+        {
+            return _realPricipalDatabase.getMechanisms();
+        }
+
+        public List<Principal> getUsers()
+        {
+            return _realPricipalDatabase.getUsers();
+        }
     }
+
 }

Propchange: 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Copied: 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java
 (from r663950, 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java)
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java?p2=incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java&p1=incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java&r1=663950&r2=664001&rev=664001&view=diff
==============================================================================
--- 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java
 (original)
+++ 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java
 Fri Jun  6 09:03:48 2008
@@ -28,13 +28,13 @@
 import java.util.Enumeration;
 import java.util.Map;
 
-public class CRAMMD5HashedSaslServer implements SaslServer
+public class CRAMMD5HexSaslServer implements SaslServer
 {
-    public static final String MECHANISM = "CRAM-MD5-HASHED";
+    public static final String MECHANISM = "CRAM-MD5-HEX";
 
     private SaslServer _realServer;
 
-    public CRAMMD5HashedSaslServer(String mechanism, String protocol, String 
serverName, Map<String, ?> props,
+    public CRAMMD5HexSaslServer(String mechanism, String protocol, String 
serverName, Map<String, ?> props,
                                    CallbackHandler cbh) throws SaslException
     {
         Enumeration factories = Sasl.getSaslServerFactories();
@@ -43,7 +43,7 @@
         {
             SaslServerFactory factory = (SaslServerFactory) 
factories.nextElement();
 
-            if (factory instanceof CRAMMD5HashedServerFactory)
+            if (factory instanceof CRAMMD5HexServerFactory)
             {
                 continue;
             }

Propchange: 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Copied: 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java
 (from r663950, 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java)
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java?p2=incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java&p1=incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java&r1=663950&r2=664001&rev=664001&view=diff
==============================================================================
--- 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java
 (original)
+++ 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java
 Fri Jun  6 09:03:48 2008
@@ -28,14 +28,14 @@
 import javax.security.sasl.SaslServer;
 import javax.security.sasl.SaslServerFactory;
 
-public class CRAMMD5HashedServerFactory implements SaslServerFactory
+public class CRAMMD5HexServerFactory implements SaslServerFactory
 {
     public SaslServer createSaslServer(String mechanism, String protocol, 
String serverName, Map<String, ?> props,
                                        CallbackHandler cbh) throws 
SaslException
     {
-        if (mechanism.equals(CRAMMD5HashedSaslServer.MECHANISM))
+        if (mechanism.equals(CRAMMD5HexSaslServer.MECHANISM))
         {
-            return new CRAMMD5HashedSaslServer(mechanism, protocol, 
serverName, props, cbh);
+            return new CRAMMD5HexSaslServer(mechanism, protocol, serverName, 
props, cbh);
         }
         else
         {
@@ -56,6 +56,6 @@
             }
         }
 
-        return new String[]{CRAMMD5HashedSaslServer.MECHANISM};
+        return new String[]{CRAMMD5HexSaslServer.MECHANISM};
     }
 }

Propchange: 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/qpid/branches/M2.x/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
incubator/qpid/branches/M2.x/java/broker/src/test/java/org/apache/qpid/server/securiity/auth/sasl/CRAMMD5HexInitialiserTest.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2.x/java/broker/src/test/java/org/apache/qpid/server/securiity/auth/sasl/CRAMMD5HexInitialiserTest.java?rev=664001&view=auto
==============================================================================
--- 
incubator/qpid/branches/M2.x/java/broker/src/test/java/org/apache/qpid/server/securiity/auth/sasl/CRAMMD5HexInitialiserTest.java
 (added)
+++ 
incubator/qpid/branches/M2.x/java/broker/src/test/java/org/apache/qpid/server/securiity/auth/sasl/CRAMMD5HexInitialiserTest.java
 Fri Jun  6 09:03:48 2008
@@ -0,0 +1,143 @@
+/*
+ *
+ * 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.securiity.auth.sasl;
+
+import junit.framework.TestCase;
+import 
org.apache.qpid.server.security.auth.database.PropertiesPrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexInitialiser;
+
+import javax.security.auth.callback.Callback;
+import javax.security.auth.callback.NameCallback;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.callback.UnsupportedCallbackException;
+import java.io.IOException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.util.Properties;
+
+/**
+ * These tests ensure that the Hex wrapping that the initialiser performs does 
actually operate when the handle method is called.
+ */
+public class CRAMMD5HexInitialiserTest extends TestCase
+{
+
+    public void testHex()
+    {
+
+        //Create User details for testing
+        String user = "testUser";
+        String password = "testPassword";
+
+        perform(user, password);
+    }
+
+    public void testHashedHex()
+    {
+
+        //Create User details for testing
+        String user = "testUser";
+        String password = "testPassword";
+
+        //Create a hashed password that we then attempt to put through the 
call back mechanism.
+        try
+        {
+            password = new 
String(MessageDigest.getInstance("MD5").digest(password.getBytes()));
+        }
+        catch (NoSuchAlgorithmException e)
+        {
+            fail(e.getMessage());
+        }
+
+        perform(user, password);
+    }
+
+    public void perform(String user, String password)
+    {
+        CRAMMD5HexInitialiser initialiser = new CRAMMD5HexInitialiser();
+
+        //Use properties to create a PrincipalDatabase
+        Properties users = new Properties();
+        users.put(user, password);
+
+        PropertiesPrincipalDatabase db = new 
PropertiesPrincipalDatabase(users);
+
+        initialiser.initialise(db);
+
+        //setup the callbacks
+        PasswordCallback passwordCallback = new PasswordCallback("password:", 
false);
+        NameCallback usernameCallback = new NameCallback("user:", user);
+
+        Callback[] callbacks = new Callback[]{usernameCallback, 
passwordCallback};
+
+        //Check the
+        try
+        {
+            assertNull("The password was not null before the handle call.", 
passwordCallback.getPassword());
+            initialiser.getCallbackHandler().handle(callbacks);
+        }
+        catch (IOException e)
+        {
+            fail(e.getMessage());
+        }
+        catch (UnsupportedCallbackException e)
+        {
+            fail(e.getMessage());
+        }
+
+        //Hex the password we initialised with and compare it with the 
passwordCallback
+        assertArrayEquals(toHex(password.toCharArray()), 
passwordCallback.getPassword());
+
+    }
+
+    private void assertArrayEquals(char[] expected, char[] actual)
+    {        
+        assertEquals("Arrays are not the same length", expected.length, 
actual.length);
+
+        for (int index = 0; index < expected.length; index++)
+        {
+            assertEquals("Characters are not equal", expected[index], 
actual[index]);
+        }
+    }
+
+    private char[] toHex(char[] password)
+    {
+        StringBuilder sb = new StringBuilder();
+        for (char c : password)
+        {
+            //toHexString does not prepend 0 so we have to
+            if (((byte) c > -1) && (byte) c < 10)
+            {
+                sb.append(0);
+            }
+
+            sb.append(Integer.toHexString(c & 0xFF));
+        }
+
+        //Extract the hex string as char[]
+        char[] hex = new char[sb.length()];
+
+        sb.getChars(0, sb.length(), hex, 0);
+
+        return hex;
+    }
+    
+
+}

Propchange: 
incubator/qpid/branches/M2.x/java/broker/src/test/java/org/apache/qpid/server/securiity/auth/sasl/CRAMMD5HexInitialiserTest.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/qpid/branches/M2.x/java/broker/src/test/java/org/apache/qpid/server/securiity/auth/sasl/CRAMMD5HexInitialiserTest.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date


Reply via email to