Author: ritchiem
Date: Wed Apr 11 06:31:18 2007
New Revision: 527487

URL: http://svn.apache.org/viewvc?view=rev&rev=527487
Log:
QPID-446  AMQUserManagementMBean Initial implementation of user management in 
authentication file.
UserManagement - Added annotations for MBeanOperations
PrincipalDatabase - Added new methods to update,create,delete Principal.
 - Implemented method on all PrincipalDatabase implementations, most return 
false to say not complete except 
Base64MD5PasswordFilePrincipalDatabase - which now stores in memory the 
password file and flushes any changes to disk.

Modified:
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
    
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java

Modified: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java?view=diff&rev=527487&r1=527486&r2=527487
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java
 (original)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java
 Wed Apr 11 06:31:18 2007
@@ -24,15 +24,33 @@
 import org.apache.qpid.server.management.AMQManagedObject;
 import org.apache.qpid.server.management.MBeanOperationParameter;
 import org.apache.qpid.server.management.MBeanOperation;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import org.apache.log4j.Logger;
 
 import javax.management.JMException;
 import javax.management.openmbean.TabularData;
+import javax.security.auth.login.AccountNotFoundException;
+import java.io.File;
+import java.io.FileInputStream;
+import java.io.IOException;
+import java.util.Properties;
+import java.util.Map;
+import java.util.HashMap;
+import java.security.Principal;
 
 /** MBean class for AMQUserManagementMBean. It implements all the management 
features exposed for managing users. */
 @MBeanDescription("User Management Interface")
 public class AMQUserManagementMBean extends AMQManagedObject implements 
UserManagement
 {
 
+    private static final Logger _logger = 
Logger.getLogger(AMQUserManagementMBean.class);
+
+    private PrincipalDatabase _principalDatabase;
+    private File _accessFile;
+
+    Map<String, Principal> _users = new HashMap<String, Principal>();
+
     public AMQUserManagementMBean() throws JMException
     {
         super(UserManagement.class, UserManagement.TYPE);
@@ -43,29 +61,142 @@
         return UserManagement.TYPE;
     }
 
-    public boolean setPassword(@MBeanOperationParameter(name = "username", 
description = "Username")String username, @MBeanOperationParameter(name = 
"password", description = "Password")String password)
+    public boolean setPassword(@MBeanOperationParameter(name = "username", 
description = "Username")String username,
+                               @MBeanOperationParameter(name = "password", 
description = "Password")String password)
     {
-        return true;
-    }
-
-    public boolean setRights(@MBeanOperationParameter(name = "username", 
description = "Username")String username, @MBeanOperationParameter(name = 
"read", description = "Administration read")boolean read, 
@MBeanOperationParameter(name = "write", description = "Administration 
write")boolean write, @MBeanOperationParameter(name = "admin", description = 
"Administration rights")boolean admin)
+        try
+        {
+            return _principalDatabase.updatePassword(new 
UsernamePrincipal(username), password);
+        }
+        catch (AccountNotFoundException e)
+        {
+            _logger.warn("Attempt to set password of non-existant user'" + 
username + "'");
+            return false;
+        }
+    }
+
+    public boolean setRights(@MBeanOperationParameter(name = "username", 
description = "Username")String username,
+                             @MBeanOperationParameter(name = "read", 
description = "Administration read")boolean read,
+                             @MBeanOperationParameter(name = "write", 
description = "Administration write")boolean write,
+                             @MBeanOperationParameter(name = "admin", 
description = "Administration rights")boolean admin)
     {
         return true;
     }
 
-    public boolean createUser(@MBeanOperationParameter(name = "username", 
description = "Username")String username, @MBeanOperationParameter(name = 
"password", description = "Password")String password, 
@MBeanOperationParameter(name = "read", description = "Administration 
read")boolean read, @MBeanOperationParameter(name = "write", description = 
"Administration write")boolean write, @MBeanOperationParameter(name = "admin", 
description = "Administration rights")boolean admin)
-    {
-        return true;
+    public boolean createUser(@MBeanOperationParameter(name = "username", 
description = "Username")String username,
+                              @MBeanOperationParameter(name = "password", 
description = "Password")String password,
+                              @MBeanOperationParameter(name = "read", 
description = "Administration read")boolean read,
+                              @MBeanOperationParameter(name = "write", 
description = "Administration write")boolean write,
+                              @MBeanOperationParameter(name = "admin", 
description = "Administration rights")boolean admin)
+    {
+        try
+        {
+            if (_principalDatabase.createPrincipal(new 
UsernamePrincipal(username), password))
+            {
+                _users.remove(username);
+                return true;
+            }
+        }
+        catch (AccountNotFoundException e)
+        {
+            _logger.warn("Attempt to delete user (" + username + ") that 
doesn't exist");
+        }
+
+        return false;
     }
 
     public boolean deleteUser(@MBeanOperationParameter(name = "username", 
description = "Username")String username)
     {
-        return true;
+
+        try
+        {
+            if (_principalDatabase.deletePrincipal(new 
UsernamePrincipal(username)))
+            {
+                _users.remove(username);
+                return true;
+            }
+        }
+        catch (AccountNotFoundException e)
+        {
+            _logger.warn("Attempt to delete user (" + username + ") that 
doesn't exist");
+        }
+
+        return false;
+    }
+
+    public boolean reloadData()
+    {
+        try
+        {
+            loadAccessFile();
+
+            // Reload successful
+            return true;
+        }
+        catch (IOException e)
+        {
+            _logger.info("Reload failed due to:" + e);
+            // Reload unsuccessful
+            return false;
+        }
     }
 
     @MBeanOperation(name = "viewUsers", description = "All users with access 
rights to the system.")
     public TabularData viewUsers()
     {
         return null;
+    }
+
+    /*** Broker Methods **/
+
+    /**
+     * setPrincipalDatabase
+     *
+     * @param database
+     *
+     * @throws java.io.IOException If the file cannot be read
+     */
+    public void setPrincipalDatabase(PrincipalDatabase database)
+    {
+        _principalDatabase = database;
+    }
+
+    /**
+     * setAccessFile
+     *
+     * @param accessFile the file to use for updating.
+     *
+     * @throws java.io.IOException If the file cannot be read
+     */
+    public void setAccessFile(File accessFile) throws IOException
+    {
+        _accessFile = accessFile;
+
+        if (_accessFile != null)
+        {
+            loadAccessFile();
+        }
+        else
+        {
+            _logger.warn("Access rights file specified is null. Access rights 
not changed.");
+        }
+    }
+
+    private void loadAccessFile() throws IOException
+    {
+        Properties accessRights = new Properties();
+        accessRights.load(new FileInputStream(_accessFile));
+        processAccessRights(accessRights);
+
+    }
+
+    /**
+     * user=read user=write user=readwrite user=admin
+     *
+     * @param accessRights The properties list of access rights to process
+     */
+    private void processAccessRights(Properties accessRights)
+    {
+        //To change body of created methods use File | Settings | File 
Templates.
     }
 }

Modified: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java?view=diff&rev=527487&r1=527486&r2=527487
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java
 (original)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java
 Wed Apr 11 06:31:18 2007
@@ -35,8 +35,6 @@
     String TYPE = "UserManagement";
 
     //********** Operations *****************//
-
-
     /**
      * set password for user
      *
@@ -45,6 +43,7 @@
      *
      * @return The result of the operation
      */
+    @MBeanOperation(name = "setPassword", description = "Set password for 
user.")              
     boolean setPassword(@MBeanOperationParameter(name = "username", 
description = "Username")String username,
                         @MBeanOperationParameter(name = "password", 
description = "Password")String password);
 
@@ -58,6 +57,7 @@
      *
      * @return The result of the operation
      */
+    @MBeanOperation(name = "setRights", description = "Set access rights for 
user.")
     boolean setRights(@MBeanOperationParameter(name = "username", description 
= "Username")String username,
                       @MBeanOperationParameter(name = "read", description = 
"Administration read")boolean read,
                       @MBeanOperationParameter(name = "write", description = 
"Administration write")boolean write,
@@ -74,6 +74,7 @@
      *
      * @return The result of the operation
      */
+    @MBeanOperation(name = "createUser", description = "Create new user from 
system.")
     boolean createUser(@MBeanOperationParameter(name = "username", description 
= "Username")String username,
                        @MBeanOperationParameter(name = "password", description 
= "Password")String password,
                        @MBeanOperationParameter(name = "read", description = 
"Administration read")boolean read,
@@ -87,7 +88,17 @@
      *
      * @return The result of the operation
      */
+    @MBeanOperation(name = "deleteUser", description = "Delete user from 
system.")
     boolean deleteUser(@MBeanOperationParameter(name = "username", description 
= "Username")String username);
+
+
+    /**
+     * Reload the date from disk
+     *
+     * @return The result of the operation
+     */
+    @MBeanOperation(name = "reloadData", description = "Reload the 
authentication file from disk.")
+    boolean reloadData();
 
     /**
      * View users returns all the users that are currently available to the 
system.

Modified: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java?view=diff&rev=527487&r1=527486&r2=527487
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
 (original)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
 Wed Apr 11 06:31:18 2007
@@ -23,19 +23,29 @@
 import org.apache.log4j.Logger;
 import 
org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
 import 
org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser;
+import org.apache.qpid.server.security.access.AMQUserManagementMBean;
+import org.apache.qpid.server.security.Passwd;
 import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.EncoderException;
 
 import javax.security.auth.callback.PasswordCallback;
 import javax.security.auth.login.AccountNotFoundException;
+import javax.management.JMException;
 import java.io.File;
 import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.BufferedReader;
 import java.io.FileReader;
+import java.io.UnsupportedEncodingException;
+import java.io.BufferedWriter;
+import java.io.FileWriter;
+import java.io.PrintStream;
 import java.util.regex.Pattern;
 import java.util.Map;
 import java.util.HashMap;
+import java.util.List;
 import java.security.Principal;
+import java.security.NoSuchAlgorithmException;
 
 /**
  * Represents a user database where the account information is stored in a 
simple flat file.
@@ -54,6 +64,10 @@
 
     private Map<String, AuthenticationProviderInitialiser> _saslServers;
 
+    AMQUserManagementMBean _mbean;
+    private static final String DEFAULT_ENCODING = "utf-8";
+    private Map<String, User> _users = new HashMap<String, User>();
+
     public Base64MD5PasswordFilePrincipalDatabase()
     {
         _saslServers = new HashMap<String, 
AuthenticationProviderInitialiser>();
@@ -66,9 +80,19 @@
         CRAMMD5HashedInitialiser cram = new CRAMMD5HashedInitialiser();
         cram.initialise(this);
         _saslServers.put(cram.getMechanismName(), cram);
+
+        try
+        {
+            _mbean = new AMQUserManagementMBean();
+            _mbean.setPrincipalDatabase(this);
+        }
+        catch (JMException e)
+        {
+            _logger.warn("User management disabled as unable to create MBean:" 
+ e);
+        }
     }
 
-    public void setPasswordFile(String passwordFile) throws 
FileNotFoundException
+    public void setPasswordFile(String passwordFile) throws IOException
     {
         File f = new File(passwordFile);
         _logger.info("PasswordFilePrincipalDatabase using file " + 
f.getAbsolutePath());
@@ -82,10 +106,11 @@
             throw new FileNotFoundException("Cannot read password file " + f +
                                             ". Check permissions.");
         }
+
+        loadPasswordFile();
     }
 
-    public void setPassword(Principal principal, PasswordCallback callback) 
throws IOException,
-                                                                               
    AccountNotFoundException
+    public void setPassword(Principal principal, PasswordCallback callback) 
throws AccountNotFoundException
     {
         if (_passwordFile == null)
         {
@@ -95,7 +120,9 @@
         {
             throw new IllegalArgumentException("principal must not be null");
         }
+
         char[] pwd = lookupPassword(principal.getName());
+
         if (pwd != null)
         {
             callback.setPassword(pwd);
@@ -106,55 +133,169 @@
         }
     }
 
-    public boolean verifyPassword(Principal principal, char[] password) throws 
AccountNotFoundException
+    public boolean verifyPassword(Principal principal, String password) throws 
AccountNotFoundException
     {
         try
         {
             char[] pwd = lookupPassword(principal.getName());
-            return compareCharArray(pwd, password);
+            byte[] passwordBytes = password.getBytes(DEFAULT_ENCODING);
+
+            int index = 0;
+            boolean verified = true;
+
+            while (verified & index < passwordBytes.length)
+            {
+                verified = (pwd[index] == (char) passwordBytes[index]);
+                index++;
+            }
+            return verified;
         }
-        catch (IOException e)
+        catch (UnsupportedEncodingException e)
         {
             return false;
         }
     }
 
-    public Map<String, AuthenticationProviderInitialiser> getMechanisms()
+    public boolean updatePassword(Principal principal, String password) throws 
AccountNotFoundException
     {
-        return _saslServers;
-    }
+        User user = _users.get(principal.getName());
 
-    private boolean compareCharArray(char[] a, char[] b)
-    {
-        boolean equal = false;
-        if (a.length == b.length)
+        if (user == null)
         {
-            equal = true;
-            int index = 0;
-            while (equal && index < a.length)
+            throw new AccountNotFoundException(principal.getName());
+        }
+
+        try
+        {
+
+            char[] passwd = convertPassword(password);
+
+            user.setPassword(passwd);
+
+            try
             {
-                equal = a[index] == b[index];
-                index++;
+                savePasswordFile();
             }
+            catch (IOException e)
+            {
+                _logger.error("Unable to save password file, password change 
for user'"
+                              + principal + "' will revert at restart");
+                return false;
+            }
+            return true;
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            return false;
         }
-        return equal;
     }
 
+    private char[] convertPassword(String password) throws 
UnsupportedEncodingException
+    {
+        byte[] passwdBytes = password.getBytes(DEFAULT_ENCODING);
+
+        char[] passwd = new char[passwdBytes.length];
+
+        int index = 0;
+
+        for (byte b : passwdBytes)
+        {
+            passwd[index] = (char) b;
+        }
+
+        return passwd;
+    }
+
+    public boolean createPrincipal(Principal principal, String password) 
throws AccountNotFoundException
+    {
+        if (_users.get(principal.getName()) != null)
+        {
+            return false;
+        }
+
+        User user = null;
+        try
+        {
+            user = new User(principal.getName(), convertPassword(password));
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            _logger.warn("Unable to encode password:" + e);
+            return false;
+        }
+
+        _users.put(user.getName(), user);
+
+        try
+        {
+            savePasswordFile();
+            return true;
+        }
+        catch (IOException e)
+        {
+            return false;
+        }
+
+    }
+
+    public boolean deletePrincipal(Principal principal) throws 
AccountNotFoundException
+    {
+        User user = _users.get(principal.getName());
+
+        if (user == null)
+        {
+            throw new AccountNotFoundException(principal.getName());
+        }
+
+        user.delete();
+
+        try
+        {
+            savePasswordFile();
+        }
+        catch (IOException e)
+        {
+            _logger.warn("Unable to remove user '" + user.getName() + "' from 
password file.");
+            return false;
+        }
+
+        _users.remove(user.getName());
+
+        return true;
+    }
+
+    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
+     * @param name The principal name to lookup
      *
-     * @return
-     *
-     * @throws java.io.IOException
+     * @return a char[] for use in SASL.
      */
-    private char[] lookupPassword(String name) throws IOException
+    private char[] lookupPassword(String name)
     {
+        User user = _users.get(name);
+        if (user == null)
+        {
+            return null;
+        }
+        else
+        {
+            return user.getPassword();
+        }
+    }
+
+
+    private void loadPasswordFile() throws IOException
+    {
+        _users.clear();
+
         BufferedReader reader = null;
-        byte[] passwd = null;
         try
         {
             reader = new BufferedReader(new FileReader(_passwordFile));
@@ -163,43 +304,75 @@
             while ((line = reader.readLine()) != null)
             {
                 String[] result = _regexp.split(line);
-                if (result == null || result.length < 2)
+                if (result == null || result.length < 2 || 
result[0].startsWith("#"))
                 {
                     continue;
                 }
 
-                if (name.equals(result[0]))
-                {
+                User user = new User(result);
+                _users.put(user.getName(), user);
+            }
+        }
+        finally
+        {
+            if (reader != null)
+            {
+                reader.close();
+            }
+        }
+    }
 
+    private void savePasswordFile() throws IOException
+    {
+        BufferedReader reader = null;
+        PrintStream writer = null;
+        File tmp = new File(_passwordFile.getAbsolutePath() + ".tmp");
+        try
+        {
+            writer = new PrintStream(tmp);
+            reader = new BufferedReader(new FileReader(_passwordFile));
+            String line;
 
-                    char[] raw = result[1].toCharArray();
+            while ((line = reader.readLine()) != null)
+            {
+                String[] result = _regexp.split(line);
+                if (result == null || result.length < 2 || 
result[0].startsWith("#"))
+                {
+                    writer.write(line.getBytes(DEFAULT_ENCODING));
+                    continue;
+                }
 
-                    byte[] encoded = new byte[result[1].length() + 1];
+                User user = _users.get(result[0]);
 
-                    int index = 0;
-                    for (char c : raw)
+                if (user == null)
+                {
+                    writer.write(line.getBytes(DEFAULT_ENCODING));
+                }
+                else if (!user.isDeleted())
+                {
+                    if (!user.isModified())
                     {
-                        index++;
-                        encoded[index] = (byte) c;
+                        writer.write(line.getBytes(DEFAULT_ENCODING));
                     }
-
-                    Base64 b64 = new Base64();
-                    byte[] decoded = b64.decode(encoded);
-
-
-                    char[] hashedPassword = new char[decoded.length + 1];
-
-                    index = 0;
-                    for (byte c : decoded)
+                    else
                     {
-                        index++;
-                        hashedPassword[index] = (char) c;
+                        try
+                        {
+                            byte[] encodedPassword = user.getEncodePassword();
+
+                            writer.write((user.getName() + 
":").getBytes(DEFAULT_ENCODING));
+                            writer.write(encodedPassword);
+                        }
+                        catch (EncoderException e)
+                        {
+                            _logger.warn("Unable to encode new password 
reverting to old password.");
+                            writer.write(line.getBytes(DEFAULT_ENCODING));
+                        }
                     }
-
-                    return hashedPassword;
                 }
+
+
             }
-            return null;
         }
         finally
         {
@@ -207,6 +380,102 @@
             {
                 reader.close();
             }
+
+            if (writer != null)
+            {
+                writer.close();
+            }
+
+            // Swap temp file to main password file.
+            tmp.renameTo(_passwordFile);
+        }
+    }
+
+    private class User
+    {
+        String _name;
+        char[] _password;
+        byte[] _encodedPassword = null;
+        private boolean _modified = false;
+        private boolean _deleted = false;
+
+        User(String[] data) throws UnsupportedEncodingException
+        {
+            if (data.length != 2)
+            {
+                throw new IllegalArgumentException("User Data should be lenght 
2, username, password");
+            }
+
+            _name = data[0];
+
+            byte[] encoded_password = data[1].getBytes(DEFAULT_ENCODING);
+
+            Base64 b64 = new Base64();
+            byte[] decoded = b64.decode(encoded_password);
+
+            _encodedPassword = encoded_password;
+
+            _password = new char[decoded.length];
+
+            int index = 0;
+            for (byte c : decoded)
+            {
+                _password[index++] = (char) c;
+            }
+        }
+
+        public User(String name, char[] password)
+        {
+            _name = name;
+            setPassword(password);
+        }
+
+        String getName()
+        {
+            return _name;
+        }
+
+        char[] getPassword()
+        {
+            return _password;
+        }
+
+        void setPassword(char[] password)
+        {
+            _password = password;
+            _modified = true;
+            _encodedPassword = null;
+        }
+
+
+        byte[] getEncodePassword() throws EncoderException, 
UnsupportedEncodingException
+        {
+            if (_encodedPassword == null)
+            {
+                encodePassword();
+            }
+            return _encodedPassword;
+        }
+
+        private void encodePassword() throws EncoderException, 
UnsupportedEncodingException
+        {
+            Base64 b64 = new Base64();
+            _encodedPassword = b64.encode(new 
String(_password).getBytes(DEFAULT_ENCODING));
+        }
+
+        public boolean isModified()
+        {
+            return _modified;
+        }
+
+        public boolean isDeleted()
+        {
+            return _deleted;
+        }
+
+        public void delete()
+        {
+            _deleted = true;
         }
     }
 }

Modified: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java?view=diff&rev=527487&r1=527486&r2=527487
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
 (original)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
 Wed Apr 11 06:31:18 2007
@@ -34,6 +34,7 @@
 import java.io.IOException;
 import java.io.BufferedReader;
 import java.io.FileReader;
+import java.io.UnsupportedEncodingException;
 import java.util.regex.Pattern;
 import java.util.Map;
 import java.util.HashMap;
@@ -119,17 +120,49 @@
         }
     }
 
-    public boolean verifyPassword(Principal principal, char[] password) throws 
AccountNotFoundException
+    public boolean verifyPassword(Principal principal, String password) throws 
AccountNotFoundException
     {
         try
         {
             char[] pwd = lookupPassword(principal.getName());
-            return compareCharArray(pwd, password);
+
+            return compareCharArray(pwd, convertPassword(password));
         }
         catch (IOException e)
         {
             return false;
         }
+    }
+
+    private char[] convertPassword(String password) throws 
UnsupportedEncodingException
+    {
+        byte[] passwdBytes = password.getBytes("utf-8");
+
+        char[] passwd = new char[passwdBytes.length];
+
+        int index = 0;
+
+        for (byte b : passwdBytes)
+        {
+            passwd[index] = (char) b;
+        }
+
+        return passwd;
+    }
+
+    public boolean updatePassword(Principal principal, String password) throws 
AccountNotFoundException
+    {
+        return false; // updates denied
+    }
+
+    public boolean createPrincipal(Principal principal, String password) 
throws AccountNotFoundException
+    {
+        return false; // updates denied
+    }
+
+    public boolean deletePrincipal(Principal principal) throws 
AccountNotFoundException
+    {
+        return false; // updates denied
     }
 
     public Map<String, AuthenticationProviderInitialiser> getMechanisms()

Modified: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java?view=diff&rev=527487&r1=527486&r2=527487
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
 (original)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
 Wed Apr 11 06:31:18 2007
@@ -23,6 +23,7 @@
 import 
org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
 
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 import java.security.Principal;
 import java.util.Map;
 
@@ -46,7 +47,7 @@
     void setPassword(Principal principal, PasswordCallback callback)
             throws IOException, AccountNotFoundException;
 
-       /**
+    /**
      * Set the password for a given principal in the specified callback. This 
is used for certain SASL providers. The
      * user database implementation should look up the password in any way it 
chooses and set it in the callback by
      * calling its setPassword method.
@@ -54,10 +55,20 @@
      * @param principal the principal
      * @param password  the password to be verified
      *
-     * @throws AccountNotFoundException if the account for specified principal 
could not be found
      * @return true if the account is verified.
+     *
+     * @throws AccountNotFoundException if the account for specified principal 
could not be found
      */
-    boolean verifyPassword(Principal principal, char[] password)
+    boolean verifyPassword(Principal principal, String password)
+            throws AccountNotFoundException;
+
+    boolean updatePassword(Principal principal, String password)
+            throws AccountNotFoundException;
+
+    boolean createPrincipal(Principal principal, String password)
+            throws AccountNotFoundException;
+
+    boolean deletePrincipal(Principal principal)
             throws AccountNotFoundException;
 
     public Map<String, AuthenticationProviderInitialiser> getMechanisms();

Modified: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java?view=diff&rev=527487&r1=527486&r2=527487
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
 (original)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
 Wed Apr 11 06:31:18 2007
@@ -31,6 +31,7 @@
 import java.util.HashMap;
 import java.security.Principal;
 import java.io.IOException;
+import java.io.UnsupportedEncodingException;
 
 public class PropertiesPrincipalDatabase implements PrincipalDatabase
 {
@@ -76,11 +77,33 @@
         }
     }
 
-    public boolean verifyPassword(Principal principal, char[] password) throws 
AccountNotFoundException
+    public boolean verifyPassword(Principal principal, String password) throws 
AccountNotFoundException
     {
         char[] pwd = _users.getProperty(principal.getName()).toCharArray();
 
-        return compareCharArray(pwd, password);
+        try
+        {
+            return compareCharArray(pwd, convertPassword(password));
+        }
+        catch (UnsupportedEncodingException e)
+        {
+            return false;
+        }
+    }
+
+    public boolean updatePassword(Principal principal, String password) throws 
AccountNotFoundException
+    {
+        return false; // updates denied
+    }
+
+    public boolean createPrincipal(Principal principal, String password) 
throws AccountNotFoundException
+    {
+        return false; // updates denied
+    }
+
+    public boolean deletePrincipal(Principal principal) throws 
AccountNotFoundException
+    {
+        return false; // updates denied
     }
 
     private boolean compareCharArray(char[] a, char[] b)
@@ -98,6 +121,23 @@
         }
         return equal;
     }
+
+    private char[] convertPassword(String password) throws 
UnsupportedEncodingException
+    {
+        byte[] passwdBytes = password.getBytes("utf-8");
+
+        char[] passwd = new char[passwdBytes.length];
+
+        int index = 0;
+
+        for (byte b : passwdBytes)
+        {
+            passwd[index] = (char) b;
+        }
+
+        return passwd;
+    }
+
 
     public Map<String, AuthenticationProviderInitialiser> getMechanisms()
     {

Modified: 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java?view=diff&rev=527487&r1=527486&r2=527487
==============================================================================
--- 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
 (original)
+++ 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
 Wed Apr 11 06:31:18 2007
@@ -91,13 +91,12 @@
 
         byte[] digest = md.digest();
 
-        char[] hash = new char[digest.length + 1];
+        char[] hash = new char[digest.length ];
 
         int index = 0;
         for (byte b : digest)
-        {
-            index++;
-            hash[index] = (char) b;
+        {            
+            hash[index++] = (char) b;
         }
 
         return hash;


Reply via email to