Author: ritchiem
Date: Thu Apr  5 02:29:22 2007
New Revision: 525777

URL: http://svn.apache.org/viewvc?view=rev&rev=525777
Log:
Addition of CRAM-MD5-HASHED authentication. Same as CRAM-MD5 but the client 
uses the hash of the password rather than the original password. This allows 
the broker to store the hash not the original password.

Added initial tool for generation passwords.

Broker:
Renamed MD5PasswordFilePrincipalDatabase.java to 
Base64MD5PasswordFilePrincipalDatabase.java as that more accurately represents 
the file contents. 
PlainPasswordVhostFilePrincipalDatabase.java - import tidy up
PrincipalDatabaseAuthenticationManager.java - Changed to add our SASL providers 
at the start of the SASL list.
CRAMMD5Hashed* - New SASL mechanism that delegates to CRAM-MD5 but understands 
that the password to use is the hash of the users password.
JCAProvider - Removed the addProvider() line as this is done after the 
construction in PrincipalDatabaseAuthenticationManager.
PlainSaslServerFactory - White Space
Passwd.java - New util stub for managing passwords ala htpasswd.

Client
Added CRAM-MD5-HASHED to CallbackHandlerRegistry 
Added ClientFactory for CRAMMD5Hashed that returns the first CRAM-MD5 
SaslClient.
DynamicSaslRegistrar.java - Tidied imports added new JCAProviders at the start 
of the Sasl lists.
DynamicSaslRegistrar.properties - Added CRAM-MD5-HASHED handler.
JCAProvider.java - as with broker stopped JCAProvider.java adding itself as the 
DynamicSaslRegistrar.java does this on the client.
UsernameHashedPasswordCallbackHandler.java - New callback handler that is used 
by CRAM-MD5-HASHED. It hashes the client's password and uses that in the 
CRAM-MD5 algorithm.

Added:
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java
   (with props)
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
   (with props)
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java
   (with props)
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java
   (with props)
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java
   (with props)
    
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
   (with props)
    
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/
    
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/CRAMMD5HashedSaslClientFactory.java
   (with props)
Removed:
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/MD5PasswordFilePrincipalDatabase.java
Modified:
    
incubator/qpid/branches/M2/java/broker/distribution/src/main/assembly/broker-bin.xml
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
    
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
    
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties
    
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
    
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
    
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java

Modified: 
incubator/qpid/branches/M2/java/broker/distribution/src/main/assembly/broker-bin.xml
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/distribution/src/main/assembly/broker-bin.xml?view=diff&rev=525777&r1=525776&r2=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/distribution/src/main/assembly/broker-bin.xml
 (original)
+++ 
incubator/qpid/branches/M2/java/broker/distribution/src/main/assembly/broker-bin.xml
 Thu Apr  5 02:29:22 2007
@@ -108,6 +108,12 @@
       <fileMode>473</fileMode>
     </file>
     <file>
+      <source>../bin/passwd</source>
+      <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
+      <destName>passwd</destName>
+      <fileMode>473</fileMode>
+    </file>
+    <file>
       <source>../bin/qpid-server</source>
       <outputDirectory>qpid-${qpid.version}/bin</outputDirectory>
       <destName>qpid-server</destName>

Added: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java?view=auto&rev=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java
 (added)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java
 Thu Apr  5 02:29:22 2007
@@ -0,0 +1,81 @@
+/*
+ *  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;
+
+import org.apache.commons.codec.binary.Base64;
+
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+import java.security.DigestException;
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintStream;
+
+public class Passwd
+{
+    public static void main(String args[]) throws NoSuchAlgorithmException, 
DigestException, IOException
+    {
+        if (args.length != 2)
+        {
+            System.out.println("Passwd <username> <password>");
+            System.exit(0);
+        }
+
+        byte[] data = args[1].getBytes("utf-8");
+
+        MessageDigest md = MessageDigest.getInstance("MD5");
+
+        for (byte b : data)
+        {
+            md.update(b);
+        }
+
+        byte[] digest = md.digest();
+
+        Base64 b64 = new Base64();
+
+        byte[] encoded = b64.encode(digest);
+
+        output(args[0], encoded);
+    }
+
+    private static void output(String user, byte[] encoded) throws IOException
+    {
+
+//        File passwdFile = new File("qpid.passwd");
+
+        PrintStream ps = new PrintStream(System.out);
+
+        user += ":";
+        ps.write(user.getBytes("utf-8"));
+
+        for (byte b : encoded)
+        {
+            ps.write(b);
+        }
+
+        ps.println();
+
+        ps.flush();
+        ps.close();
+    }
+}

Propchange: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/Passwd.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
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=auto&rev=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
 (added)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
 Thu Apr  5 02:29:22 2007
@@ -0,0 +1,212 @@
+/*
+ *  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.sasl.AuthenticationProviderInitialiser;
+import 
org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser;
+import org.apache.commons.codec.binary.Base64;
+
+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 Base64MD5PasswordFilePrincipalDatabase implements 
PrincipalDatabase
+{
+    private static final Logger _logger = 
Logger.getLogger(Base64MD5PasswordFilePrincipalDatabase.class);
+
+    private File _passwordFile;
+
+    private Pattern _regexp = Pattern.compile(":");
+
+    private Map<String, AuthenticationProviderInitialiser> _saslServers;
+
+    public Base64MD5PasswordFilePrincipalDatabase()
+    {
+        _saslServers = new HashMap<String, 
AuthenticationProviderInitialiser>();
+
+        /**
+         *  Create Authenticators for MD5 Password file.
+         */
+
+        // Accept Plain incomming and hash it for comparison to the file.
+        CRAMMD5HashedInitialiser cram = new CRAMMD5HashedInitialiser();
+        cram.initialise(this);
+        _saslServers.put(cram.getMechanismName(), cram);
+    }
+
+    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 boolean verifyPassword(Principal principal, char[] password) throws 
AccountNotFoundException
+    {
+        try
+        {
+            char[] pwd = lookupPassword(principal.getName());
+            return compareCharArray(pwd, password);
+        }
+        catch (IOException e)
+        {
+            return false;
+        }
+    }
+
+    public Map<String, AuthenticationProviderInitialiser> getMechanisms()
+    {
+        return _saslServers;
+    }
+
+    private boolean compareCharArray(char[] a, char[] b)
+    {
+        boolean equal = false;
+        if (a.length == b.length)
+        {
+            equal = true;
+            int index = 0;
+            while (equal && index < a.length)
+            {
+                equal = a[index] == b[index];
+                index++;
+            }
+        }
+        return equal;
+    }
+
+
+    /**
+     * 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;
+        byte[] passwd = 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]))
+                {
+
+
+                    char[] raw = result[1].toCharArray();
+
+                    byte[] encoded = new byte[result[1].length() + 1];
+
+                    int index = 0;
+                    for (char c : raw)
+                    {
+                        index++;
+                        encoded[index] = (byte) c;
+                    }
+
+                    Base64 b64 = new Base64();
+                    byte[] decoded = b64.decode(encoded);
+
+
+                    char[] hashedPassword = new char[decoded.length + 1];
+
+                    index = 0;
+                    for (byte c : decoded)
+                    {
+                        index++;
+                        hashedPassword[index] = (char) c;
+                    }
+
+                    return hashedPassword;
+                }
+            }
+            return null;
+        }
+        finally
+        {
+            if (reader != null)
+            {
+                reader.close();
+            }
+        }
+    }
+}

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

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

Modified: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java?view=diff&rev=525777&r1=525776&r2=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java
 (original)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java
 Thu Apr  5 02:29:22 2007
@@ -20,27 +20,15 @@
  */
 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.

Modified: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java?view=diff&rev=525777&r1=525776&r2=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
 (original)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
 Thu Apr  5 02:29:22 2007
@@ -108,11 +108,15 @@
 
         if (providerMap.size() > 0)
         {
-            Security.addProvider(new JCAProvider(providerMap));
+            // Ensure we are used before the defaults
+            if (Security.insertProviderAt(new JCAProvider(providerMap), 1) == 
-1)
+            {
+                _logger.warn("Unable to set order of providers.");
+            }
         }
         else
         {
-            _logger.warn("No SASL providers availble.");
+            _logger.warn("No additional SASL providers registered.");
         }
 
     }
@@ -148,21 +152,20 @@
     {
         if (database == null || database.getMechanisms().size() == 0)
         {
-            _logger.warn("");
+            _logger.warn("No Database or no mechanisms to initialise 
authentication");
             return;
         }
 
-        for (AuthenticationProviderInitialiser mechanism : 
database.getMechanisms().values())
+        for (Map.Entry<String, AuthenticationProviderInitialiser> mechanism : 
database.getMechanisms().entrySet())
         {
-            initialiseAuthenticationMechanism(mechanism, providerMap);
+            initialiseAuthenticationMechanism(mechanism.getKey(), 
mechanism.getValue(), providerMap);
         }
     }
 
-    private void 
initialiseAuthenticationMechanism(AuthenticationProviderInitialiser initialiser,
+    private void initialiseAuthenticationMechanism(String mechanism, 
AuthenticationProviderInitialiser initialiser,
                                                    Map<String, Class<? extends 
SaslServerFactory>> providerMap)
             throws Exception
     {
-        String mechanism = initialiser.getMechanismName();
         if (_mechanisms == null)
         {
             _mechanisms = mechanism;

Modified: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java?view=diff&rev=525777&r1=525776&r2=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
 (original)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
 Thu Apr  5 02:29:22 2007
@@ -33,7 +33,7 @@
         super("AMQSASLProvider", 1.0, "A JCA provider that registers all " +
               "AMQ SASL providers that want to be registered");
         register(providerMap);
-        Security.addProvider(this);
+        //Security.addProvider(this);
     }
 
     private void register(Map<String, Class<? extends SaslServerFactory>> 
providerMap)

Added: 
incubator/qpid/branches/M2/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/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java?view=auto&rev=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java
 (added)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java
 Thu Apr  5 02:29:22 2007
@@ -0,0 +1,50 @@
+/*
+ *
+ * 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.sasl.crammd5;
+
+import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+
+import javax.security.sasl.SaslServerFactory;
+import java.util.Map;
+
+public class CRAMMD5HashedInitialiser extends UsernamePasswordInitialiser
+{
+    public String getMechanismName()
+    {
+        return CRAMMD5HashedSaslServer.MECHANISM;
+    }
+
+    public Class<? extends SaslServerFactory> 
getServerFactoryClassForJCARegistration()
+    {
+        return CRAMMD5HashedServerFactory.class;
+    }
+
+    public void initialise(PrincipalDatabase passwordFile)
+    {
+        super.initialise(passwordFile);
+    }
+
+    public Map<String, ?> getProperties()
+    {
+        return null;
+    }
+}

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

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

Added: 
incubator/qpid/branches/M2/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/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java?view=auto&rev=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java
 (added)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java
 Thu Apr  5 02:29:22 2007
@@ -0,0 +1,105 @@
+/*
+ *  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.sasl.crammd5;
+
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslServerFactory;
+import javax.security.auth.callback.CallbackHandler;
+import java.util.Enumeration;
+import java.util.Map;
+
+public class CRAMMD5HashedSaslServer implements SaslServer
+{
+    public static final String MECHANISM = "CRAM-MD5-HASHED";
+
+    private SaslServer _realServer;
+
+    public CRAMMD5HashedSaslServer(String mechanism, String protocol, String 
serverName, Map<String, ?> props,
+                                   CallbackHandler cbh) throws SaslException
+    {
+        Enumeration factories = Sasl.getSaslServerFactories();
+
+        while (factories.hasMoreElements())
+        {
+            SaslServerFactory factory = (SaslServerFactory) 
factories.nextElement();
+
+            if (factory instanceof CRAMMD5HashedServerFactory)
+            {
+                continue;
+            }
+            
+            String[] mechs = factory.getMechanismNames(props);
+
+            for (String mech : mechs)
+            {
+                if (mech.equals("CRAM-MD5"))
+                {
+                    _realServer = factory.createSaslServer("CRAM-MD5", 
protocol, serverName, props, cbh);
+                    return;
+                }
+            }
+        }
+
+        throw new RuntimeException("No default SaslServer found for 
mechanism:" + "CRAM-MD5");
+    }
+
+    public String getMechanismName()
+    {
+        return MECHANISM;
+    }
+
+    public byte[] evaluateResponse(byte[] response) throws SaslException
+    {
+        return _realServer.evaluateResponse(response);
+    }
+
+    public boolean isComplete()
+    {
+        return _realServer.isComplete();
+    }
+
+    public String getAuthorizationID()
+    {
+        return _realServer.getAuthorizationID();
+    }
+
+    public byte[] unwrap(byte[] incoming, int offset, int len) throws 
SaslException
+    {
+        return _realServer.unwrap(incoming, offset, len);
+    }
+
+    public byte[] wrap(byte[] outgoing, int offset, int len) throws 
SaslException
+    {
+        return _realServer.wrap(outgoing, offset, len);
+    }
+
+    public Object getNegotiatedProperty(String propName)
+    {
+        return _realServer.getNegotiatedProperty(propName);
+    }
+
+    public void dispose() throws SaslException
+    {
+        _realServer.dispose();
+    }
+}

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

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

Added: 
incubator/qpid/branches/M2/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/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java?view=auto&rev=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java
 (added)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java
 Thu Apr  5 02:29:22 2007
@@ -0,0 +1,61 @@
+/*
+ *
+ * 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.sasl.crammd5;
+
+import java.util.Map;
+
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslServerFactory;
+
+public class CRAMMD5HashedServerFactory implements SaslServerFactory
+{
+    public SaslServer createSaslServer(String mechanism, String protocol, 
String serverName, Map<String, ?> props,
+                                       CallbackHandler cbh) throws 
SaslException
+    {
+        if (mechanism.equals(CRAMMD5HashedSaslServer.MECHANISM))
+        {
+            return new CRAMMD5HashedSaslServer(mechanism, protocol, 
serverName, props, cbh);
+        }
+        else
+        {
+            return null;
+        }
+    }
+
+    public String[] getMechanismNames(Map props)
+    {
+        if (props != null)
+        {
+            if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
+                props.containsKey(Sasl.POLICY_NODICTIONARY) ||
+                props.containsKey(Sasl.POLICY_NOACTIVE))
+            {
+                // returned array must be non null according to interface 
documentation
+                return new String[0];
+            }
+        }
+
+        return new String[]{CRAMMD5HashedSaslServer.MECHANISM};
+    }
+}

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

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

Modified: 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java?view=diff&rev=525777&r1=525776&r2=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
 (original)
+++ 
incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
 Thu Apr  5 02:29:22 2007
@@ -29,7 +29,7 @@
 import javax.security.sasl.SaslServerFactory;
 
 public class PlainSaslServerFactory implements SaslServerFactory
-{    
+{
     public SaslServer createSaslServer(String mechanism, String protocol, 
String serverName, Map props,
                                        CallbackHandler cbh) throws 
SaslException
     {

Modified: 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties?view=diff&rev=525777&r1=525776&r2=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties
 (original)
+++ 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/CallbackHandlerRegistry.properties
 Thu Apr  5 02:29:22 2007
@@ -16,5 +16,6 @@
 # specific language governing permissions and limitations
 # under the License.
 #
+CallbackHandler.CRAM-MD5-HASHED=org.apache.qpid.client.security.UsernameHashedPasswordCallbackHandler
 
CallbackHandler.CRAM-MD5=org.apache.qpid.client.security.UsernamePasswordCallbackHandler
 
CallbackHandler.PLAIN=org.apache.qpid.client.security.UsernamePasswordCallbackHandler

Modified: 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java?view=diff&rev=525777&r1=525776&r2=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
 (original)
+++ 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.java
 Thu Apr  5 02:29:22 2007
@@ -20,10 +20,6 @@
  */
 package org.apache.qpid.client.security;
 
-import java.io.BufferedInputStream;
-import java.io.File;
-import java.io.FileInputStream;
-import java.io.FileNotFoundException;
 import java.io.IOException;
 import java.io.InputStream;
 import java.security.Security;
@@ -34,6 +30,7 @@
 
 import javax.security.sasl.SaslClientFactory;
 
+
 import org.apache.log4j.Logger;
 
 import org.apache.qpid.util.FileUtils;
@@ -50,14 +47,11 @@
  * mechanism=fully.qualified.class.name
  * </pre>
  *
- * <p/>Where mechanism is an IANA-registered mechanism name and the fully 
qualified class name refers to a
- * class that implements javax.security.sasl.SaslClientFactory and provides 
the specified mechanism.
+ * <p/>Where mechanism is an IANA-registered mechanism name and the fully 
qualified class name refers to a class that
+ * implements javax.security.sasl.SaslClientFactory and provides the specified 
mechanism.
  *
- * <p><table id="crc"><caption>CRC Card</caption>
- * <tr><th> Responsibilities <th> Collaborations
- * <tr><td> Parse SASL mechanism properties.
- * <tr><td> Create and register security provider for SASL mechanisms.
- * </table>
+ * <p><table id="crc"><caption>CRC Card</caption> <tr><th> Responsibilities 
<th> Collaborations <tr><td> Parse SASL
+ * mechanism properties. <tr><td> Create and register security provider for 
SASL mechanisms. </table>
  */
 public class DynamicSaslRegistrar
 {
@@ -69,10 +63,7 @@
     /** The default name of the SASL properties file resource. */
     public static final String DEFAULT_RESOURCE_NAME = 
"org/apache/qpid/client/security/DynamicSaslRegistrar.properties";
 
-    /**
-     * Reads the properties file, and creates a dynamic security provider to 
register the SASL implementations
-     * with.
-     */
+    /** Reads the properties file, and creates a dynamic security provider to 
register the SASL implementations with. */
     public static void registerSaslProviders()
     {
         _logger.debug("public static void registerSaslProviders(): called");
@@ -80,8 +71,8 @@
         // Open the SASL properties file, using the default name is one is not 
specified.
         String filename = System.getProperty(FILE_PROPERTY);
         InputStream is =
-            FileUtils.openFileOrDefaultResource(filename, 
DEFAULT_RESOURCE_NAME,
-                                                
DynamicSaslRegistrar.class.getClassLoader());
+                FileUtils.openFileOrDefaultResource(filename, 
DEFAULT_RESOURCE_NAME,
+                                                    
DynamicSaslRegistrar.class.getClassLoader());
 
         try
         {
@@ -94,7 +85,7 @@
 
             if (factories.size() > 0)
             {
-                Security.addProvider(new JCAProvider(factories));
+                Security.insertProviderAt(new JCAProvider(factories), 0);
                 _logger.debug("Dynamic SASL provider added as a security 
provider");
             }
         }
@@ -170,15 +161,15 @@
      * @return A map from SASL mechanism names to implementing client factory 
classes.
      *
      * @todo Why tree map here? Do really want mechanisms in alphabetical 
order? Seems more likely that the declared
-     *       order of the mechanisms is intended to be preserved, so that they 
are registered in the declared order
-     *       of preference. Consider LinkedHashMap instead.
+     * order of the mechanisms is intended to be preserved, so that they are 
registered in the declared order of
+     * preference. Consider LinkedHashMap instead.
      */
     private static Map<String, Class<? extends SaslClientFactory>> 
parseProperties(Properties props)
     {
         Enumeration e = props.propertyNames();
 
         TreeMap<String, Class<? extends SaslClientFactory>> 
factoriesToRegister =
-            new TreeMap<String, Class<? extends SaslClientFactory>>();
+                new TreeMap<String, Class<? extends SaslClientFactory>>();
 
         while (e.hasMoreElements())
         {

Modified: 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties?view=diff&rev=525777&r1=525776&r2=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
 (original)
+++ 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/DynamicSaslRegistrar.properties
 Thu Apr  5 02:29:22 2007
@@ -17,3 +17,4 @@
 # under the License.
 #
 AMQPLAIN=org.apache.qpid.client.security.amqplain.AmqPlainSaslClientFactory
+CRAM-MD5-HASHED=org.apache.qpid.client.security.crammd5hashed.CRAMMD5HashedSaslClientFactory

Modified: 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java?view=diff&rev=525777&r1=525776&r2=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
 (original)
+++ 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/JCAProvider.java
 Thu Apr  5 02:29:22 2007
@@ -52,7 +52,7 @@
         super("AMQSASLProvider", 1.0, "A JCA provider that registers all "
               + "AMQ SASL providers that want to be registered");
         register(providerMap);
-        Security.addProvider(this);
+//        Security.addProvider(this);
     }
 
     /**

Added: 
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=auto&rev=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
 (added)
+++ 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
 Thu Apr  5 02:29:22 2007
@@ -0,0 +1,103 @@
+/*
+ *
+ * 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.client.security;
+
+import java.io.IOException;
+import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
+import java.security.NoSuchAlgorithmException;
+
+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 javax.security.sasl.RealmCallback;
+
+import org.apache.qpid.client.protocol.AMQProtocolSession;
+import org.apache.log4j.Logger;
+import com.sun.crypto.provider.HmacMD5;
+
+public class UsernameHashedPasswordCallbackHandler implements 
AMQCallbackHandler
+{
+    private static final Logger _logger = 
Logger.getLogger(UsernameHashedPasswordCallbackHandler.class);
+
+
+    private AMQProtocolSession _protocolSession;
+
+    public void initialise(AMQProtocolSession protocolSession)
+    {
+        _protocolSession = protocolSession;
+    }
+
+    public void handle(Callback[] callbacks) throws IOException, 
UnsupportedCallbackException
+    {
+        for (int i = 0; i < callbacks.length; i++)
+        {
+            Callback cb = callbacks[i];
+            if (cb instanceof NameCallback)
+            {
+                ((NameCallback) cb).setName(_protocolSession.getUsername());
+            }
+            else if (cb instanceof PasswordCallback)
+            {
+
+                try
+                {
+                    ((PasswordCallback) 
cb).setPassword(getHash(_protocolSession.getPassword()));
+                }
+                catch (Exception e)
+                {
+                    throw new UnsupportedCallbackException(cb);
+                }
+            }
+            else
+            {
+                throw new UnsupportedCallbackException(cb);
+            }
+        }
+    }
+
+    private char[] getHash(String text) throws NoSuchAlgorithmException, 
UnsupportedEncodingException
+    {
+
+        byte[] data = text.getBytes("utf-8");
+
+        MessageDigest md = MessageDigest.getInstance("MD5");
+
+        for (byte b : data)
+        {
+            md.update(b);
+        }
+
+        byte[] digest = md.digest();
+
+        char[] hash = new char[digest.length + 1];
+
+        int index = 0;
+        for (byte b : digest)
+        {
+            index++;
+            hash[index] = (char) b;
+        }
+
+        return hash;
+    }
+}

Propchange: 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/UsernameHashedPasswordCallbackHandler.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date

Added: 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/CRAMMD5HashedSaslClientFactory.java
URL: 
http://svn.apache.org/viewvc/incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/CRAMMD5HashedSaslClientFactory.java?view=auto&rev=525777
==============================================================================
--- 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/CRAMMD5HashedSaslClientFactory.java
 (added)
+++ 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/CRAMMD5HashedSaslClientFactory.java
 Thu Apr  5 02:29:22 2007
@@ -0,0 +1,72 @@
+/*
+ *  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.client.security.crammd5hashed;
+
+import org.apache.qpid.client.security.amqplain.AmqPlainSaslClient;
+
+import javax.security.sasl.SaslClientFactory;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.Sasl;
+import javax.security.auth.callback.CallbackHandler;
+import java.util.Map;
+import java.security.Security;
+
+public class CRAMMD5HashedSaslClientFactory implements SaslClientFactory
+{
+    /** The name of this mechanism */
+    public static final String MECHANISM = "CRAM-MD5-HASHED";
+
+
+    public SaslClient createSaslClient(String[] mechanisms, String 
authorizationId, String protocol, String serverName, Map<String, ?> props, 
CallbackHandler cbh) throws SaslException
+    {
+        for (int i = 0; i < mechanisms.length; i++)
+        {
+            if (mechanisms[i].equals(MECHANISM))
+            {
+                if (cbh == null)
+                {
+                    throw new SaslException("CallbackHandler must not be 
null");
+                }
+
+                String[] mechs = {"CRAM-MD5"};
+                return Sasl.createSaslClient(mechs, authorizationId, protocol, 
serverName, props, cbh);
+            }
+        }
+        return null;
+    }
+
+    public String[] getMechanismNames(Map props)
+    {
+        if (props != null)
+        {
+            if (props.containsKey(Sasl.POLICY_NOPLAINTEXT) ||
+                props.containsKey(Sasl.POLICY_NODICTIONARY) ||
+                props.containsKey(Sasl.POLICY_NOACTIVE))
+            {
+                // returned array must be non null according to interface 
documentation
+                return new String[0];
+            }
+        }
+
+        return new String[]{MECHANISM};
+    }
+}

Propchange: 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/CRAMMD5HashedSaslClientFactory.java
------------------------------------------------------------------------------
    svn:eol-style = native

Propchange: 
incubator/qpid/branches/M2/java/client/src/main/java/org/apache/qpid/client/security/crammd5hashed/CRAMMD5HashedSaslClientFactory.java
------------------------------------------------------------------------------
    svn:keywords = Rev Date


Reply via email to