summaryrefslogtreecommitdiff
path: root/java/broker/src/main
diff options
context:
space:
mode:
authorRobert Gemmell <robbie@apache.org>2009-02-27 20:14:07 +0000
committerRobert Gemmell <robbie@apache.org>2009-02-27 20:14:07 +0000
commit2ef0ad78f223d70b651a8409db462f3e64e074d8 (patch)
tree88db350f1e8bf29bd86d070d4dd738901985e4af /java/broker/src/main
parent7c79adf16acfeb31cd2b90699c456698237a2e82 (diff)
downloadqpid-python-2ef0ad78f223d70b651a8409db462f3e64e074d8.tar.gz
QPID-1536: modify the B64MD5 PD to take plain text input and perform the required hashing itself in order to present a consistent interface for user management. Alter management console to use mbean versioning to detect this and send plaintext to v2+ user management mbeans. Update RMIPasswordAuthenticator to make use of the new PD input consistency
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@748680 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'java/broker/src/main')
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java49
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java43
-rw-r--r--java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java81
3 files changed, 93 insertions, 80 deletions
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
index 69ad9014db..3c211746e3 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
@@ -152,8 +152,39 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
public boolean verifyPassword(String principal, char[] password) throws AccountNotFoundException
{
char[] pwd = lookupPassword(principal);
+
+ if (pwd == null)
+ {
+ throw new AccountNotFoundException("Unable to lookup the specfied users password");
+ }
+
+ byte[] byteArray = new byte[password.length];
+ int index = 0;
+ for (char c : password)
+ {
+ byteArray[index++] = (byte) c;
+ }
+
+ byte[] MD5byteArray;
+ try
+ {
+ MD5byteArray = HashedUser.getMD5(byteArray);
+ }
+ catch (Exception e1)
+ {
+ _logger.warn("Unable to hash password for user '" + principal + "' for comparison");
+ return false;
+ }
+
+ char[] hashedPassword = new char[MD5byteArray.length];
- return compareCharArray(pwd, password);
+ index = 0;
+ for (byte c : MD5byteArray)
+ {
+ hashedPassword[index++] = (char) c;
+ }
+
+ return compareCharArray(pwd, hashedPassword);
}
private boolean compareCharArray(char[] a, char[] b)
@@ -193,7 +224,7 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
{
_userUpdate.lock();
char[] orig = user.getPassword();
- user.setPassword(password);
+ user.setPassword(password,false);
try
{
@@ -204,7 +235,7 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
_logger.error("Unable to save password file, password change for user'"
+ principal + "' will revert at restart");
//revert the password change
- user.setPassword(orig);
+ user.setPassword(orig,true);
return false;
}
return true;
@@ -230,7 +261,17 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
return false;
}
- HashedUser user = new HashedUser(principal.getName(), password);
+ HashedUser user;
+ try
+ {
+ user = new HashedUser(principal.getName(), password);
+ }
+ catch (Exception e1)
+ {
+ _logger.warn("Unable to create new user '" + principal.getName() + "'");
+ return false;
+ }
+
try
{
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java
index 4d92e3fb4c..3690e7f92a 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java
@@ -25,6 +25,7 @@ import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import java.io.UnsupportedEncodingException;
+import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
import java.security.Principal;
@@ -63,10 +64,22 @@ public class HashedUser implements Principal
}
}
- public HashedUser(String name, char[] password)
+ public HashedUser(String name, char[] password) throws UnsupportedEncodingException, NoSuchAlgorithmException
{
_name = name;
- setPassword(password);
+ setPassword(password,false);
+ }
+
+ public static byte[] getMD5(byte[] data) throws NoSuchAlgorithmException, UnsupportedEncodingException
+ {
+ MessageDigest md = MessageDigest.getInstance("MD5");
+
+ for (byte b : data)
+ {
+ md.update(b);
+ }
+
+ return md.digest();
}
public String getName()
@@ -84,9 +97,31 @@ public class HashedUser implements Principal
return _password;
}
- void setPassword(char[] password)
+ void setPassword(char[] password, boolean alreadyHashed) throws UnsupportedEncodingException, NoSuchAlgorithmException
{
- _password = password;
+ if(alreadyHashed){
+ _password = password;
+ }
+ else
+ {
+ byte[] byteArray = new byte[password.length];
+ int index = 0;
+ for (char c : password)
+ {
+ byteArray[index++] = (byte) c;
+ }
+
+ byte[] MD5byteArray = getMD5(byteArray);
+
+ _password = new char[MD5byteArray.length];
+
+ index = 0;
+ for (byte c : MD5byteArray)
+ {
+ _password[index++] = (char) c;
+ }
+ }
+
_modified = true;
_encodedPassword = null;
}
diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
index 378b17e733..77040e896c 100644
--- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
+++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
@@ -20,23 +20,14 @@
*/
package org.apache.qpid.server.security.auth.rmi;
-import java.io.IOException;
-import java.io.UnsupportedEncodingException;
-import java.security.MessageDigest;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
import java.util.Collections;
import javax.management.remote.JMXAuthenticator;
import javax.management.remote.JMXPrincipal;
import javax.security.auth.Subject;
-import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
-import org.apache.qpid.server.security.auth.database.Base64MD5PasswordFilePrincipalDatabase;
-import org.apache.qpid.server.security.auth.database.PlainPasswordFilePrincipalDatabase;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
public class RMIPasswordAuthenticator implements JMXAuthenticator
{
@@ -48,7 +39,6 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
static final String CREDENTIALS_REQUIRED = "User details are required. " +
"Please ensure you are using an up to date management console to connect.";
- public static final String DEFAULT_ENCODING = "utf-8";
private PrincipalDatabase _db = null;
public RMIPasswordAuthenticator()
@@ -91,56 +81,26 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
throw new SecurityException(SHOULD_BE_NON_NULL);
}
+ // Verify that a PD has been set.
+ if (_db == null)
+ {
+ throw new SecurityException(UNABLE_TO_LOOKUP);
+ }
+
boolean authenticated = false;
// Perform authentication
try
{
- PasswordCallback pwCallback = new PasswordCallback("prompt",false);
- UsernamePrincipal uname = new UsernamePrincipal(username);
-
- if (_db instanceof Base64MD5PasswordFilePrincipalDatabase)
- {
- //retrieve the stored password for the given user
- _db.setPassword(uname, pwCallback);
-
- //compare the MD5Hash of the given password with the stored value
- if (Arrays.equals(getMD5Hash(password), pwCallback.getPassword()))
- {
- authenticated = true;
- }
- }
- else if (_db instanceof PlainPasswordFilePrincipalDatabase)
- {
- //retrieve the users stored password and compare with given value
- _db.setPassword(uname, pwCallback);
-
- if (password.equals(new String(pwCallback.getPassword())))
- {
- authenticated = true;
- }
- }
- else
- {
- throw new SecurityException(UNABLE_TO_LOOKUP);
+ if (_db.verifyPassword(username, password.toCharArray()))
+ {
+ authenticated = true;
}
}
catch (AccountNotFoundException e)
{
throw new SecurityException(INVALID_CREDENTIALS);
}
- catch (UnsupportedEncodingException e)
- {
- throw new SecurityException(UNABLE_TO_LOOKUP);
- }
- catch (NoSuchAlgorithmException e)
- {
- throw new SecurityException(UNABLE_TO_LOOKUP);
- }
- catch (IOException e)
- {
- throw new SecurityException(UNABLE_TO_LOOKUP);
- }
if (authenticated)
{
@@ -155,28 +115,5 @@ public class RMIPasswordAuthenticator implements JMXAuthenticator
throw new SecurityException(INVALID_CREDENTIALS);
}
}
-
- public static char[] getMD5Hash(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException
- {
- byte[] data = text.getBytes(DEFAULT_ENCODING);
- MessageDigest md = MessageDigest.getInstance("MD5");
-
- for (byte b : data)
- {
- md.update(b);
- }
-
- byte[] digest = md.digest();
-
- char[] hash = new char[digest.length ];
-
- int index = 0;
- for (byte b : digest)
- {
- hash[index++] = (char) b;
- }
-
- return hash;
- }
} \ No newline at end of file