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