You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by rg...@apache.org on 2007/04/19 18:24:45 UTC
svn commit: r530474 [3/8] - in /incubator/qpid/trunk/qpid: ./
java/broker/bin/ java/broker/distribution/src/main/assembly/
java/broker/etc/ java/broker/lib/
java/broker/src/main/java/org/apache/qpid/server/
java/broker/src/main/java/org/apache/qpid/ser...
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ApplicationRegistry.java Thu Apr 19 09:24:30 2007
@@ -153,7 +153,7 @@
{
_logger.error("Error configuring application: " + e, e);
//throw new AMQBrokerCreationException(instanceID, "Unable to create Application Registry instance " + instanceID);
- throw new RuntimeException("Unable to create Application Registry");
+ throw new RuntimeException("Unable to create Application Registry", e);
}
}
else
@@ -168,6 +168,12 @@
{
virtualHost.close();
}
+
+ // close the rmi registry(if any) started for management
+ if (getInstance().getManagedObjectRegistry() != null)
+ {
+ getInstance().getManagedObjectRegistry().close();
+ }
}
public Configuration getConfiguration()
@@ -187,7 +193,7 @@
catch (Exception e)
{
_logger.error("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor");
- throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor");
+ throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor", e);
}
Configurator.configure(instance);
_configuredObjects.put(instanceType, instance);
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/registry/ConfigurationFileApplicationRegistry.java Thu Apr 19 09:24:30 2007
@@ -42,6 +42,7 @@
import org.apache.qpid.server.security.access.AccessManagerImpl;
import org.apache.qpid.server.virtualhost.VirtualHost;
import org.apache.qpid.server.virtualhost.VirtualHostRegistry;
+import org.apache.qpid.AMQException;
public class ConfigurationFileApplicationRegistry extends ApplicationRegistry
{
@@ -103,6 +104,7 @@
public void initialise() throws Exception
{
initialiseManagedObjectRegistry();
+
_virtualHostRegistry = new VirtualHostRegistry();
_accessManager = new AccessManagerImpl("default", _configuration);
@@ -111,7 +113,12 @@
_authenticationManager = new PrincipalDatabaseAuthenticationManager(null, null);
+ _databaseManager.initialiseManagement(_configuration);
+
+ _managedObjectRegistry.start();
+
initialiseVirtualHosts();
+
}
private void initialiseVirtualHosts() throws Exception
@@ -123,7 +130,7 @@
}
}
- private void initialiseManagedObjectRegistry()
+ private void initialiseManagedObjectRegistry() throws AMQException
{
ManagementConfiguration config = getConfiguredObject(ManagementConfiguration.class);
if (config.enabled)
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManager.java Thu Apr 19 09:24:30 2007
@@ -20,8 +20,13 @@
*/
package org.apache.qpid.server.security.access;
+import java.security.Principal;
+
public interface AccessManager
{
+ AccessResult isAuthorized(Accessable accessObject, Principal username, AccessRights.Rights rights);
+
+ @Deprecated
AccessResult isAuthorized(Accessable accessObject, String username);
String getName();
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AccessManagerImpl.java Thu Apr 19 09:24:30 2007
@@ -23,13 +23,13 @@
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.server.registry.ApplicationRegistry;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.configuration.PropertyUtils;
-import org.apache.qpid.configuration.PropertyException;
import org.apache.log4j.Logger;
import java.util.List;
import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
+import java.security.Principal;
public class AccessManagerImpl implements AccessManager
{
@@ -39,8 +39,13 @@
public AccessManagerImpl(String name, Configuration hostConfig) throws ConfigurationException
{
- String accessClass = hostConfig.getString("security.access.class");
+ if (hostConfig == null)
+ {
+ _logger.warn("No Configuration specified. Using default access controls for VirtualHost:'" + name + "'");
+ return;
+ }
+ String accessClass = hostConfig.getString("security.access.class");
if (accessClass == null)
{
_logger.warn("No access control specified. Using default access controls for VirtualHost:'" + name + "'");
@@ -111,21 +116,35 @@
}
catch (Exception e)
{
- throw new ConfigurationException(e.getCause());
+ ConfigurationException ce = new ConfigurationException(e.getMessage(), e.getCause());
+ ce.initCause(e);
+ throw ce;
}
}
}
-
public AccessResult isAuthorized(Accessable accessObject, String username)
{
+ return isAuthorized(accessObject, new UsernamePrincipal(username), AccessRights.Rights.READ);
+ }
+
+ public AccessResult isAuthorized(Accessable accessObject, Principal user, AccessRights.Rights rights)
+ {
if (_accessManager == null)
{
- return ApplicationRegistry.getInstance().getAccessManager().isAuthorized(accessObject, username);
+ if (ApplicationRegistry.getInstance().getAccessManager() == this)
+ {
+ _logger.warn("No Default access manager specified DENYING ALL ACCESS");
+ return new AccessResult(this, AccessResult.AccessStatus.REFUSED);
+ }
+ else
+ {
+ return ApplicationRegistry.getInstance().getAccessManager().isAuthorized(accessObject, user, rights);
+ }
}
else
{
- return _accessManager.isAuthorized(accessObject, username);
+ return _accessManager.isAuthorized(accessObject, user, rights);
}
}
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/AllowAll.java Thu Apr 19 09:24:30 2007
@@ -20,8 +20,15 @@
*/
package org.apache.qpid.server.security.access;
+import java.security.Principal;
+
public class AllowAll implements AccessManager
{
+
+ public AccessResult isAuthorized(Accessable accessObject, Principal username, AccessRights.Rights rights)
+ {
+ return new AccessResult(this, AccessResult.AccessStatus.GRANTED);
+ }
public AccessResult isAuthorized(Accessable accessObject, String username)
{
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/DenyAll.java Thu Apr 19 09:24:30 2007
@@ -20,8 +20,15 @@
*/
package org.apache.qpid.server.security.access;
+import java.security.Principal;
+
public class DenyAll implements AccessManager
{
+ public AccessResult isAuthorized(Accessable accessObject, Principal username, AccessRights.Rights rights)
+ {
+ return new AccessResult(this, AccessResult.AccessStatus.REFUSED);
+ }
+
public AccessResult isAuthorized(Accessable accessObject, String username)
{
return new AccessResult(this, AccessResult.AccessStatus.REFUSED);
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/PrincipalDatabaseAccessManager.java Thu Apr 19 09:24:30 2007
@@ -22,8 +22,11 @@
import org.apache.qpid.server.registry.ApplicationRegistry;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.log4j.Logger;
+import java.security.Principal;
+
public class PrincipalDatabaseAccessManager implements AccessManager
{
private static final Logger _logger = Logger.getLogger(PrincipalDatabaseAccessManager.class);
@@ -58,15 +61,21 @@
}
}
+
public AccessResult isAuthorized(Accessable accessObject, String username)
{
+ return isAuthorized(accessObject, new UsernamePrincipal(username), AccessRights.Rights.READ);
+ }
+
+ public AccessResult isAuthorized(Accessable accessObject, Principal username, AccessRights.Rights rights)
+ {
AccessResult result;
if (_database == null)
{
if (_default != null)
{
- result = _default.isAuthorized(accessObject, username);
+ result = _default.isAuthorized(accessObject, username, rights);
}
else
{
@@ -75,7 +84,15 @@
}
else
{
- result = ((AccessManager) _database).isAuthorized(accessObject, username);
+ if (!(_database instanceof AccessManager))
+ {
+ _logger.warn("Specified PrincipalDatabase is not an AccessManager so using default AccessManager");
+ result = _default.isAuthorized(accessObject, username, rights);
+ }
+ else
+ {
+ result = ((AccessManager) _database).isAuthorized(accessObject, username, rights);
+ }
}
result.addAuthorizer(this);
Copied: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java (from r526122, 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/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java?view=diff&rev=530474&p1=incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java&r1=526122&p2=incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java&r2=530474
==============================================================================
--- incubator/qpid/branches/M2/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java Thu Apr 19 09:24:30 2007
@@ -22,8 +22,11 @@
import org.apache.log4j.Logger;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser;
+import org.apache.qpid.server.security.access.AMQUserManagementMBean;
import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.codec.EncoderException;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
@@ -32,10 +35,17 @@
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
+import java.io.UnsupportedEncodingException;
+import java.io.PrintStream;
import java.util.regex.Pattern;
import java.util.Map;
import java.util.HashMap;
+import java.util.List;
+import java.util.LinkedList;
+import java.util.concurrent.locks.ReentrantLock;
import java.security.Principal;
+import java.security.NoSuchAlgorithmException;
+import java.security.MessageDigest;
/**
* Represents a user database where the account information is stored in a simple flat file.
@@ -54,6 +64,11 @@
private Map<String, AuthenticationProviderInitialiser> _saslServers;
+ AMQUserManagementMBean _mbean;
+ private static final String DEFAULT_ENCODING = "utf-8";
+ private Map<String, User> _users = new HashMap<String, User>();
+ private ReentrantLock _userUpdate = new ReentrantLock();
+
public Base64MD5PasswordFilePrincipalDatabase()
{
_saslServers = new HashMap<String, AuthenticationProviderInitialiser>();
@@ -66,9 +81,20 @@
CRAMMD5HashedInitialiser cram = new CRAMMD5HashedInitialiser();
cram.initialise(this);
_saslServers.put(cram.getMechanismName(), cram);
+
+ //fixme The PDs should setup a PD Mangement MBean
+// try
+// {
+// _mbean = new AMQUserManagementMBean();
+// _mbean.setPrincipalDatabase(this);
+// }
+// catch (JMException e)
+// {
+// _logger.warn("User management disabled as unable to create MBean:" + e);
+// }
}
- public void setPasswordFile(String passwordFile) throws FileNotFoundException
+ public void setPasswordFile(String passwordFile) throws IOException
{
File f = new File(passwordFile);
_logger.info("PasswordFilePrincipalDatabase using file " + f.getAbsolutePath());
@@ -82,10 +108,19 @@
throw new FileNotFoundException("Cannot read password file " + f +
". Check permissions.");
}
+
+ loadPasswordFile();
}
- public void setPassword(Principal principal, PasswordCallback callback) throws IOException,
- AccountNotFoundException
+ /**
+ * SASL Callback Mechanism - sets the Password in the PasswordCallback based on the value in the PasswordFile
+ *
+ * @param principal The Principal to set the password for
+ * @param callback The PasswordCallback to call setPassword on
+ *
+ * @throws AccountNotFoundException If the Principal cannont be found in this Database
+ */
+ public void setPassword(Principal principal, PasswordCallback callback) throws AccountNotFoundException
{
if (_passwordFile == null)
{
@@ -95,7 +130,9 @@
{
throw new IllegalArgumentException("principal must not be null");
}
+
char[] pwd = lookupPassword(principal.getName());
+
if (pwd != null)
{
callback.setPassword(pwd);
@@ -106,107 +143,484 @@
}
}
- public boolean verifyPassword(Principal principal, char[] password) throws AccountNotFoundException
+ /**
+ * Used to verify that the presented Password is correct. Currently only used by Management Console
+ *
+ * @param principal The principal to authenticate
+ * @param password The password to check
+ *
+ * @return true if password is correct
+ *
+ * @throws AccountNotFoundException if the principal cannot be found
+ */
+ public boolean verifyPassword(String principal, String password) throws AccountNotFoundException
{
try
{
- char[] pwd = lookupPassword(principal.getName());
- return compareCharArray(pwd, password);
+ char[] pwd = lookupPassword(principal);
+ byte[] passwordBytes = password.getBytes(DEFAULT_ENCODING);
+
+ int index = 0;
+ boolean verified = true;
+
+ while (verified & index < passwordBytes.length)
+ {
+ verified = (pwd[index] == (char) passwordBytes[index]);
+ index++;
+ }
+ return verified;
}
- catch (IOException e)
+ catch (UnsupportedEncodingException e)
{
return false;
}
}
- public Map<String, AuthenticationProviderInitialiser> getMechanisms()
+ public boolean updatePassword(Principal principal, String password) throws AccountNotFoundException
{
- return _saslServers;
+ User user = _users.get(principal.getName());
+
+ if (user == null)
+ {
+ throw new AccountNotFoundException(principal.getName());
+ }
+
+ try
+ {
+
+ char[] passwd = convertPassword(password);
+
+ try
+ {
+ _userUpdate.lock();
+ user.setPassword(passwd);
+
+ try
+ {
+ savePasswordFile();
+ }
+ catch (IOException e)
+ {
+ _logger.error("Unable to save password file, password change for user'"
+ + principal + "' will revert at restart");
+ return false;
+ }
+ return true;
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ return false;
+ }
}
- private boolean compareCharArray(char[] a, char[] b)
+ private char[] convertPassword(String password) throws UnsupportedEncodingException
{
- boolean equal = false;
- if (a.length == b.length)
+ byte[] passwdBytes = password.getBytes(DEFAULT_ENCODING);
+
+ char[] passwd = new char[passwdBytes.length];
+
+ int index = 0;
+
+ for (byte b : passwdBytes)
{
- equal = true;
- int index = 0;
- while (equal && index < a.length)
+ passwd[index++] = (char) b;
+ }
+
+ return passwd;
+ }
+
+ public boolean createPrincipal(Principal principal, String password)
+ {
+ if (_users.get(principal.getName()) != null)
+ {
+ return false;
+ }
+
+ User user;
+ try
+ {
+ user = new User(principal.getName(), convertPassword(password));
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ _logger.warn("Unable to encode password:" + e);
+ return false;
+ }
+
+ try
+ {
+ _userUpdate.lock();
+ _users.put(user.getName(), user);
+
+ try
{
- equal = a[index] == b[index];
- index++;
+ savePasswordFile();
+ return true;
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
+
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
}
}
- return equal;
}
+ public boolean deletePrincipal(Principal principal) throws AccountNotFoundException
+ {
+ User user = _users.get(principal.getName());
+
+ if (user == null)
+ {
+ throw new AccountNotFoundException(principal.getName());
+ }
+
+ try
+ {
+ _userUpdate.lock();
+ user.delete();
+
+ try
+ {
+ savePasswordFile();
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Unable to remove user '" + user.getName() + "' from password file.");
+ return false;
+ }
+
+ _users.remove(user.getName());
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
+
+ return true;
+ }
+
+
+ public Map<String, AuthenticationProviderInitialiser> getMechanisms()
+ {
+ return _saslServers;
+ }
+
+ public List<Principal> getUsers()
+ {
+ return new LinkedList<Principal>(_users.values());
+ }
+
+ public Principal getUser(String username)
+ {
+ if (_users.containsKey(username))
+ {
+ return new UsernamePrincipal(username);
+ }
+ return null;
+ }
/**
* 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
+ * @param name The principal name to lookup
*
- * @throws java.io.IOException
+ * @return a char[] for use in SASL.
*/
- private char[] lookupPassword(String name) throws IOException
+ private char[] lookupPassword(String name)
+ {
+ User user = _users.get(name);
+ if (user == null)
+ {
+ return null;
+ }
+ else
+ {
+ return user.getPassword();
+ }
+ }
+
+
+ private void loadPasswordFile() throws IOException
{
- BufferedReader reader = null;
- byte[] passwd = null;
try
{
- reader = new BufferedReader(new FileReader(_passwordFile));
- String line;
+ _userUpdate.lock();
+ _users.clear();
- while ((line = reader.readLine()) != null)
+ BufferedReader reader = null;
+ try
{
- String[] result = _regexp.split(line);
- if (result == null || result.length < 2)
- {
- continue;
- }
+ reader = new BufferedReader(new FileReader(_passwordFile));
+ String line;
- if (name.equals(result[0]))
+ while ((line = reader.readLine()) != null)
{
+ String[] result = _regexp.split(line);
+ if (result == null || result.length < 2 || result[0].startsWith("#"))
+ {
+ continue;
+ }
+ User user = new User(result);
+ _logger.info("Created user:" + user);
+ _users.put(user.getName(), user);
+ }
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+ }
+ }
+ finally
+ {
+ if (_userUpdate.isHeldByCurrentThread())
+ {
+ _userUpdate.unlock();
+ }
+ }
+ }
- char[] raw = result[1].toCharArray();
+ private void savePasswordFile() throws IOException
+ {
+ try
+ {
+ _userUpdate.lock();
- byte[] encoded = new byte[result[1].length() + 1];
+ BufferedReader reader = null;
+ PrintStream writer = null;
+ File tmp = new File(_passwordFile.getAbsolutePath() + ".tmp");
+ if (tmp.exists())
+ {
+ tmp.delete();
+ }
+ try
+ {
+ writer = new PrintStream(tmp);
+ reader = new BufferedReader(new FileReader(_passwordFile));
+ String line;
- int index = 0;
- for (char c : raw)
+ while ((line = reader.readLine()) != null)
+ {
+ String[] result = _regexp.split(line);
+ if (result == null || result.length < 2 || result[0].startsWith("#"))
{
- index++;
- encoded[index] = (byte) c;
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ continue;
}
- Base64 b64 = new Base64();
- byte[] decoded = b64.decode(encoded);
-
+ User user = _users.get(result[0]);
- char[] hashedPassword = new char[decoded.length + 1];
+ if (user == null)
+ {
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ writer.println();
+ }
+ else if (!user.isDeleted())
+ {
+ if (!user.isModified())
+ {
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ writer.println();
+ }
+ else
+ {
+ try
+ {
+ byte[] encodedPassword = user.getEncodePassword();
+
+ writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING));
+ writer.write(encodedPassword);
+ writer.println();
+
+ user.saved();
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Unable to encode new password reverting to old password.");
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ writer.println();
+ }
+ }
+ }
+ }
- index = 0;
- for (byte c : decoded)
+ for (User user : _users.values())
+ {
+ if (user.isModified())
{
- index++;
- hashedPassword[index] = (char) c;
+ byte[] encodedPassword;
+ try
+ {
+ encodedPassword = user.getEncodePassword();
+ writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING));
+ writer.write(encodedPassword);
+ writer.println();
+ user.saved();
+ }
+ catch (Exception e)
+ {
+ _logger.warn("Unable to get Encoded password for user'" + user.getName() + "' password not saved");
+ }
}
+ }
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+
+ if (writer != null)
+ {
+ writer.close();
+ }
- return hashedPassword;
+ // Swap temp file to main password file.
+ File old = new File(_passwordFile.getAbsoluteFile() + ".old");
+ if (old.exists())
+ {
+ old.delete();
}
+ _passwordFile.renameTo(old);
+ tmp.renameTo(_passwordFile);
+ tmp.delete();
}
- return null;
}
finally
{
- if (reader != null)
+ if (_userUpdate.isHeldByCurrentThread())
{
- reader.close();
+ _userUpdate.unlock();
}
}
+ }
+
+ private class User implements Principal
+ {
+ String _name;
+ char[] _password;
+ byte[] _encodedPassword = null;
+ private boolean _modified = false;
+ private boolean _deleted = false;
+
+ User(String[] data) throws UnsupportedEncodingException
+ {
+ if (data.length != 2)
+ {
+ throw new IllegalArgumentException("User Data should be lenght 2, username, password");
+ }
+
+ _name = data[0];
+
+ byte[] encoded_password = data[1].getBytes(DEFAULT_ENCODING);
+
+ Base64 b64 = new Base64();
+ byte[] decoded = b64.decode(encoded_password);
+
+ _encodedPassword = encoded_password;
+
+ _password = new char[decoded.length];
+
+ int index = 0;
+ for (byte c : decoded)
+ {
+ _password[index++] = (char) c;
+ }
+ }
+
+ public User(String name, char[] password)
+ {
+ _name = name;
+ setPassword(password);
+ }
+
+ public String getName()
+ {
+ return _name;
+ }
+
+ public String toString()
+ {
+ if (_logger.isDebugEnabled())
+ {
+ return getName() + ((_encodedPassword == null) ? "" : ":" + new String(_encodedPassword));
+ }
+ else
+ {
+ return _name;
+ }
+ }
+
+ char[] getPassword()
+ {
+ return _password;
+ }
+
+ void setPassword(char[] password)
+ {
+ _password = password;
+ _modified = true;
+ _encodedPassword = null;
+ }
+
+
+ byte[] getEncodePassword() throws EncoderException, UnsupportedEncodingException, NoSuchAlgorithmException
+ {
+ if (_encodedPassword == null)
+ {
+ encodePassword();
+ }
+ return _encodedPassword;
+ }
+
+ private void encodePassword() throws EncoderException, UnsupportedEncodingException, NoSuchAlgorithmException
+ {
+ Base64 b64 = new Base64();
+ _encodedPassword = b64.encode(new String(_password).getBytes(DEFAULT_ENCODING));
+ }
+
+ public boolean isModified()
+ {
+ return _modified;
+ }
+
+ public boolean isDeleted()
+ {
+ return _deleted;
+ }
+
+ public void delete()
+ {
+ _deleted = true;
+ }
+
+ public void saved()
+ {
+ _modified = false;
+ }
+
}
}
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/ConfigurationFilePrincipalDatabaseManager.java Thu Apr 19 09:24:30 2007
@@ -1,38 +1,46 @@
/*
- * 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
+ * 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
*
- * 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.
+ * 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 java.io.FileNotFoundException;
+import java.io.IOException;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
+
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.configuration.PropertyUtils;
+import org.apache.qpid.configuration.PropertyException;
import org.apache.qpid.server.registry.ApplicationRegistry;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.configuration.PropertyUtils;
-import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabaseManager;
+import org.apache.qpid.server.security.access.AMQUserManagementMBean;
+import org.apache.qpid.AMQException;
-import java.util.Map;
-import java.util.List;
-import java.util.HashMap;
-import java.lang.reflect.Method;
-import java.io.FileNotFoundException;
+import javax.management.JMException;
public class ConfigurationFilePrincipalDatabaseManager implements PrincipalDatabaseManager
{
@@ -80,18 +88,21 @@
initialisePrincipalDatabase((PrincipalDatabase) o, config, i);
String name = databaseNames.get(i);
- if (name == null || name.length() == 0)
+ if ((name == null) || (name.length() == 0))
{
throw new Exception("Principal database names must have length greater than or equal to one character");
}
+
PrincipalDatabase pd = databases.get(name);
if (pd != null)
{
throw new Exception("Duplicate principal database name not provided");
}
+
_logger.info("Initialised principal database '" + name + "' successfully");
databases.put(name, (PrincipalDatabase) o);
}
+
return databases;
}
@@ -104,14 +115,16 @@
for (int i = 0; i < argumentNames.size(); i++)
{
String argName = argumentNames.get(i);
- if (argName == null || argName.length() == 0)
+ if ((argName == null) || (argName.length() == 0))
{
throw new ConfigurationException("Argument names must have length >= 1 character");
}
+
if (Character.isLowerCase(argName.charAt(0)))
{
argName = Character.toUpperCase(argName.charAt(0)) + argName.substring(1);
}
+
String methodName = "set" + argName;
Method method = null;
try
@@ -125,9 +138,10 @@
if (method == null)
{
- throw new ConfigurationException("No method " + methodName + " found in class " + principalDatabase.getClass() +
- " hence unable to configure principal database. The method must be public and " +
- "have a single String argument with a void return type");
+ throw new ConfigurationException("No method " + methodName + " found in class "
+ + principalDatabase.getClass()
+ + " hence unable to configure principal database. The method must be public and "
+ + "have a single String argument with a void return type");
}
try
@@ -136,7 +150,14 @@
}
catch (Exception ite)
{
- throw new ConfigurationException(ite.getCause());
+ if (ite instanceof ConfigurationException)
+ {
+ throw(ConfigurationException) ite;
+ }
+ else
+ {
+ throw new ConfigurationException(ite.getMessage(), ite);
+ }
}
}
}
@@ -144,5 +165,72 @@
public Map<String, PrincipalDatabase> getDatabases()
{
return _databases;
+ }
+
+ public void initialiseManagement(Configuration config) throws ConfigurationException
+ {
+ try
+ {
+ AMQUserManagementMBean _mbean = new AMQUserManagementMBean();
+
+ String baseSecurity = "security.jmx";
+ List<String> principalDBs = config.getList(baseSecurity + ".principal-database");
+
+ if (principalDBs.size() == 0)
+ {
+ throw new ConfigurationException("No principal-database specified for jmx security(" + baseSecurity + ".principal-database)");
+ }
+
+ String databaseName = principalDBs.get(0);
+
+ PrincipalDatabase database = getDatabases().get(databaseName);
+
+ if (database == null)
+ {
+ throw new ConfigurationException("Principal-database '" + databaseName + "' not found");
+ }
+
+ _mbean.setPrincipalDatabase(database);
+
+ List<String> jmxaccesslist = config.getList(baseSecurity + ".access");
+
+ if (jmxaccesslist.size() == 0)
+ {
+ throw new ConfigurationException("No access control files specified for jmx security(" + baseSecurity + ".access)");
+ }
+
+ String jmxaccesssFile = null;
+
+ try
+ {
+ jmxaccesssFile = PropertyUtils.replaceProperties(jmxaccesslist.get(0));
+ }
+ catch (PropertyException e)
+ {
+ throw new ConfigurationException("Unable to parse access control filename '" + jmxaccesssFile + "'");
+ }
+
+ try
+ {
+ _mbean.setAccessFile(jmxaccesssFile);
+ }
+ catch (IOException e)
+ {
+ _logger.warn("Unable to load access file:" + jmxaccesssFile);
+ }
+
+ try
+ {
+ _mbean.register();
+ }
+ catch (AMQException e)
+ {
+ _logger.warn("Unable to register user management MBean");
+ }
+ }
+ catch (JMException e)
+ {
+ _logger.warn("User management disabled as unable to create MBean:" + e);
+ }
}
}
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java Thu Apr 19 09:24:30 2007
@@ -21,8 +21,8 @@
package org.apache.qpid.server.security.auth.database;
import org.apache.log4j.Logger;
-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.UsernamePrincipal;
import org.apache.qpid.server.security.auth.sasl.amqplain.AmqPlainInitialiser;
import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
@@ -34,9 +34,11 @@
import java.io.IOException;
import java.io.BufferedReader;
import java.io.FileReader;
+import java.io.UnsupportedEncodingException;
import java.util.regex.Pattern;
import java.util.Map;
import java.util.HashMap;
+import java.util.List;
import java.security.Principal;
/**
@@ -119,21 +121,103 @@
}
}
+ public boolean verifyPassword(String principal, String password) throws AccountNotFoundException
+ {
+ try
+ {
+ char[] pwd = lookupPassword(principal);
+
+ return compareCharArray(pwd, convertPassword(password));
+ }
+ catch (IOException e)
+ {
+ return false;
+ }
+ }
+
+ private char[] convertPassword(String password) throws UnsupportedEncodingException
+ {
+ byte[] passwdBytes = password.getBytes("utf-8");
+
+ char[] passwd = new char[passwdBytes.length];
+
+ int index = 0;
+
+ for (byte b : passwdBytes)
+ {
+ passwd[index++] = (char) b;
+ }
+
+ return passwd;
+ }
+
+ public boolean updatePassword(Principal principal, String password) throws AccountNotFoundException
+ {
+ return false; // updates denied
+ }
+
+ public boolean createPrincipal(Principal principal, String password)
+ {
+ return false; // updates denied
+ }
+
+ public boolean deletePrincipal(Principal principal) throws AccountNotFoundException
+ {
+ return false; // updates denied
+ }
+
public Map<String, AuthenticationProviderInitialiser> getMechanisms()
{
return _saslServers;
}
+ public List<Principal> getUsers()
+ {
+ return null; //todo
+ }
+
+ public Principal getUser(String username)
+ {
+ try
+ {
+ if (lookupPassword(username) != null)
+ {
+ return new UsernamePrincipal(username);
+ }
+ }
+ catch (IOException e)
+ {
+ //fall through to null return
+ }
+ return null;
+ }
+
+ 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
+ * @param name the name of the principal to lookup
*
- * @return
+ * @return char[] of the password
*
- * @throws java.io.IOException
+ * @throws java.io.IOException whilst accessing the file
*/
private char[] lookupPassword(String name) throws IOException
{
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordVhostFilePrincipalDatabase.java Thu Apr 19 09:24:30 2007
@@ -20,26 +20,17 @@
*/
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.security.access.AccessRights;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
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;
/**
@@ -103,9 +94,15 @@
public AccessResult isAuthorized(Accessable accessObject, String username)
{
+ return isAuthorized(accessObject, new UsernamePrincipal(username), AccessRights.Rights.READ);
+ }
+
+ public AccessResult isAuthorized(Accessable accessObject, Principal user, AccessRights.Rights rights)
+ {
+
if (accessObject instanceof VirtualHost)
{
- String[] hosts = lookupVirtualHost(username);
+ String[] hosts = lookupVirtualHost(user.getName());
if (hosts != null)
{
@@ -126,4 +123,5 @@
{
return "PlainPasswordVhostFile";
}
+
}
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java Thu Apr 19 09:24:30 2007
@@ -23,8 +23,10 @@
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
import java.security.Principal;
import java.util.Map;
+import java.util.List;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
@@ -46,5 +48,53 @@
void setPassword(Principal principal, PasswordCallback callback)
throws IOException, AccountNotFoundException;
+ /**
+ * Used to verify that the presented Password is correct. Currently only used by Management Console
+ * @param principal The principal to authenticate
+ * @param password The password to check
+ * @return true if password is correct
+ * @throws AccountNotFoundException if the principal cannot be found
+ */
+ boolean verifyPassword(String principal, String password)
+ throws AccountNotFoundException;
+
+ /**
+ * Update(Change) the password for the given principal
+ * @param principal Who's password is to be changed
+ * @param password The new password to use
+ * @return True if change was successful
+ * @throws AccountNotFoundException If the given principal doesn't exist in the Database
+ */
+ boolean updatePassword(Principal principal, String password)
+ throws AccountNotFoundException;
+
+ /**
+ * Create a new principal in the database
+ * @param principal The principal to create
+ * @param password The password to set for the principal
+ * @return True on a successful creation
+ */
+ boolean createPrincipal(Principal principal, String password);
+
+ /**
+ * Delete a principal
+ * @param principal The principal to delete
+ * @return True on a successful creation
+ * @throws AccountNotFoundException If the given principal doesn't exist in the Database
+ */
+ boolean deletePrincipal(Principal principal)
+ throws AccountNotFoundException;
+
+ /**
+ * Get the principal from the database with the given username
+ * @param username of the principal to lookup
+ * @return The Principal object for the given username or null if not found.
+ */
+ Principal getUser(String username);
+
+
public Map<String, AuthenticationProviderInitialiser> getMechanisms();
+
+
+ List<Principal> getUsers();
}
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabaseManager.java Thu Apr 19 09:24:30 2007
@@ -21,10 +21,14 @@
package org.apache.qpid.server.security.auth.database;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
import java.util.Map;
public interface PrincipalDatabaseManager
{
public Map<String, PrincipalDatabase> getDatabases();
+
+ public void initialiseManagement(Configuration config) throws ConfigurationException;
}
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java Thu Apr 19 09:24:30 2007
@@ -21,6 +21,7 @@
package org.apache.qpid.server.security.auth.database;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
@@ -29,8 +30,10 @@
import java.util.Properties;
import java.util.Map;
import java.util.HashMap;
+import java.util.List;
import java.security.Principal;
import java.io.IOException;
+import java.io.UnsupportedEncodingException;
public class PropertiesPrincipalDatabase implements PrincipalDatabase
{
@@ -76,8 +79,87 @@
}
}
+ public boolean verifyPassword(String principal, String password) throws AccountNotFoundException
+ {
+ char[] pwd = _users.getProperty(principal).toCharArray();
+
+ try
+ {
+ return compareCharArray(pwd, convertPassword(password));
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ return false;
+ }
+ }
+
+ public boolean updatePassword(Principal principal, String password) throws AccountNotFoundException
+ {
+ return false; // updates denied
+ }
+
+ public boolean createPrincipal(Principal principal, String password)
+ {
+ return false; // updates denied
+ }
+
+ public boolean deletePrincipal(Principal principal) throws AccountNotFoundException
+ {
+ return false; // updates denied
+ }
+
+ 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;
+ }
+
+ private char[] convertPassword(String password) throws UnsupportedEncodingException
+ {
+ byte[] passwdBytes = password.getBytes("utf-8");
+
+ char[] passwd = new char[passwdBytes.length];
+
+ int index = 0;
+
+ for (byte b : passwdBytes)
+ {
+ passwd[index++] = (char) b;
+ }
+
+ return passwd;
+ }
+
+
public Map<String, AuthenticationProviderInitialiser> getMechanisms()
{
return _saslServers;
+ }
+
+ public List<Principal> getUsers()
+ {
+ return null; //todo
+ }
+
+ public Principal getUser(String username)
+ {
+ if (_users.getProperty(username) != null)
+ {
+ return new UsernamePrincipal(username);
+ }
+ else
+ {
+ return null;
+ }
}
}
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabaseManager.java Thu Apr 19 09:24:30 2007
@@ -20,6 +20,8 @@
*/
package org.apache.qpid.server.security.auth.database;
+import org.apache.commons.configuration.Configuration;
+
import java.util.Map;
import java.util.Properties;
import java.util.HashMap;
@@ -37,5 +39,10 @@
public Map<String, PrincipalDatabase> getDatabases()
{
return _databases;
+ }
+
+ public void initialiseManagement(Configuration config)
+ {
+ //todo
}
}
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java Thu Apr 19 09:24:30 2007
@@ -71,7 +71,7 @@
Map<String, Class<? extends SaslServerFactory>> providerMap = new TreeMap<String, Class<? extends SaslServerFactory>>();
- if (name == null)
+ if (name == null || hostConfig == null)
{
initialiseAuthenticationMechanisms(providerMap, ApplicationRegistry.getInstance().getDatabaseManager().getDatabases());
}
@@ -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/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java Thu Apr 19 09:24:30 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)
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java Thu Apr 19 09:24:30 2007
@@ -7,9 +7,9 @@
* 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
@@ -33,14 +33,16 @@
import javax.security.sasl.AuthorizeCallback;
import org.apache.commons.configuration.Configuration;
+
import org.apache.log4j.Logger;
+
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.UsernamePrincipal;
public abstract class UsernamePasswordInitialiser implements AuthenticationProviderInitialiser
{
- protected static final Logger _logger = Logger.getLogger(UsernamePasswordInitialiser.class);
+ protected static final Logger _logger = Logger.getLogger(UsernamePasswordInitialiser.class);
private ServerCallbackHandler _callbackHandler;
@@ -72,7 +74,9 @@
{
// very annoyingly the callback handler does not throw anything more appropriate than
// IOException
- throw new IOException("Error looking up user " + e);
+ IOException ioe = new IOException("Error looking up user " + e);
+ ioe.initCause(e);
+ throw ioe;
}
}
else if (callback instanceof AuthorizeCallback)
@@ -88,7 +92,7 @@
}
public void initialise(String baseConfigPath, Configuration configuration,
- Map<String, PrincipalDatabase> principalDatabases) throws Exception
+ Map<String, PrincipalDatabase> principalDatabases) throws Exception
{
String principalDatabaseName = configuration.getString(baseConfigPath + ".principal-database");
PrincipalDatabase db = principalDatabases.get(principalDatabaseName);
@@ -102,6 +106,7 @@
{
throw new NullPointerException("Cannot initialise with a null Principal database.");
}
+
_callbackHandler = new ServerCallbackHandler(db);
}
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java Thu Apr 19 09:24:30 2007
@@ -22,10 +22,7 @@
import java.security.Principal;
-/**
- * A principal that is just a wrapper for a simple username.
- *
- */
+/** A principal that is just a wrapper for a simple username. */
public class UsernamePrincipal implements Principal
{
private String _name;
@@ -36,6 +33,11 @@
}
public String getName()
+ {
+ return _name;
+ }
+
+ public String toString()
{
return _name;
}
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java Thu Apr 19 09:24:30 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/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/CleanupMessageOperation.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/CleanupMessageOperation.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/CleanupMessageOperation.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/CleanupMessageOperation.java Thu Apr 19 09:24:30 2007
@@ -56,18 +56,7 @@
public void commit(StoreContext context)
{
- //The routers reference can now be released. This is done
- //here to ensure that it happens after the queues that
- //enqueue it have incremented their counts (which as a
- //memory only operation is done in the commit phase).
- try
- {
- _msg.decrementReference(context);
- }
- catch (AMQException e)
- {
- _log.error("On commiting transaction, failed to cleanup unused message: " + e, e);
- }
+
try
{
_msg.checkDeliveredToConsumer();
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/LocalTransactionalContext.java Thu Apr 19 09:24:30 2007
@@ -89,6 +89,12 @@
public void rollback() throws AMQException
{
_txnBuffer.rollback(_storeContext);
+ // Hack to deal with uncommitted non-transactional writes
+ if(_messageStore.inTran(_storeContext))
+ {
+ _messageStore.abortTran(_storeContext);
+ _inTran = false;
+ }
_postCommitDeliveryList.clear();
}
@@ -103,6 +109,7 @@
// message.incrementReference();
_postCommitDeliveryList.add(new DeliveryDetails(message, queue, deliverFirst));
_messageDelivered = true;
+ _txnBuffer.enlist(new CleanupMessageOperation(message, _returnMessages));
/*_txnBuffer.enlist(new DeliverMessageOperation(message, queue));
if (_log.isDebugEnabled())
{
@@ -111,7 +118,7 @@
}
message.incrementReference();
_messageDelivered = true;
- _txnBuffer.enlist(new CleanupMessageOperation(message, _returnMessages));
+
*/
}
@@ -195,6 +202,7 @@
{
_txnBuffer.enlist(new StoreMessageOperation(_messageStore));
}
+ //fixme fail commit here ... QPID-440
try
{
_txnBuffer.commit(_storeContext);
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TxnBuffer.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TxnBuffer.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TxnBuffer.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/txn/TxnBuffer.java Thu Apr 19 09:24:30 2007
@@ -41,7 +41,7 @@
{
if (_log.isDebugEnabled())
{
- _log.debug("Committing " + _ops.size() + " ops to commit.:" + _ops.toArray());
+ _log.debug("Committing " + _ops.size() + " ops to commit.:" + _ops);
}
if (prepare(context))
Modified: incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/main/java/org/apache/qpid/server/virtualhost/VirtualHost.java Thu Apr 19 09:24:30 2007
@@ -181,7 +181,7 @@
catch (Exception e)
{
_logger.error("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor");
- throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor");
+ throw new IllegalArgumentException("Unable to instantiate configuration class " + instanceType + " - ensure it has a public default constructor", e);
}
Configurator.configure(instance);
Modified: incubator/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java (original)
+++ incubator/qpid/trunk/qpid/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java Thu Apr 19 09:24:30 2007
@@ -106,6 +106,8 @@
/**
* Tests if Queue Depth alert is thrown when queue depth reaches the threshold value
*
+ * Based on FT402 subbmitted by client
+ *
* @throws Exception
*/
public void testQueueDepthAlertNoSubscriber() throws Exception
Modified: incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java (original)
+++ incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageDispatcher.java Thu Apr 19 09:24:30 2007
@@ -1,4 +1,5 @@
/*
+ *
* 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
@@ -6,33 +7,35 @@
* 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.example.publisher;
-import org.apache.log4j.Logger;
-
import java.io.File;
+import javax.jms.JMSException;
+
+import org.apache.log4j.Logger;
+
import org.apache.qpid.example.shared.FileUtils;
import org.apache.qpid.example.shared.Statics;
-import javax.jms.JMSException;
-
/**
* Class that sends message files to the Publisher to distribute
* using files as input
* Must set properties for host in properties file or uses in vm broker
*/
-public class FileMessageDispatcher {
+public class FileMessageDispatcher
+{
protected static final Logger _logger = Logger.getLogger(FileMessageDispatcher.class);
@@ -48,30 +51,30 @@
public static void main(String[] args)
{
- //Check command line args ok - must provide a path or file for us to dispatch
+ // Check command line args ok - must provide a path or file for us to dispatch
if (args.length == 0)
{
- System.err.println("Usage: FileMessageDispatcher <filesToDispatch>" + "");
+ System.out.println("Usage: FileMessageDispatcher <filesToDispatch>" + "");
}
else
{
try
{
- //publish message(s) from file(s) to configured queue
+ // publish message(s) from file(s) to configured queue
publish(args[0]);
- //Move payload file(s) to archive location as no error
+ // Move payload file(s) to archive location as no error
FileUtils.moveFileToNewDir(args[0], System.getProperties().getProperty(Statics.ARCHIVE_PATH));
}
- catch(Exception e)
+ catch (Exception e)
{
- //log error and exit
+ // log error and exit
_logger.error("Error trying to dispatch message: " + e);
System.exit(1);
}
finally
{
- //clean up before exiting
+ // clean up before exiting
if (getPublisher() != null)
{
getPublisher().cleanup();
@@ -98,10 +101,10 @@
File tempFile = new File(path);
if (tempFile.isDirectory())
{
- //while more files in dir publish them
+ // while more files in dir publish them
File[] files = tempFile.listFiles();
- if (files == null || files.length == 0)
+ if ((files == null) || (files.length == 0))
{
_logger.info("FileMessageDispatcher - No files to publish in input directory: " + tempFile);
}
@@ -109,10 +112,10 @@
{
for (File file : files)
{
- //Create message factory passing in payload path
+ // Create message factory passing in payload path
FileMessageFactory factory = new FileMessageFactory(getPublisher().getSession(), file.toString());
- //Send the message generated from the payload using the _publisher
+ // Send the message generated from the payload using the _publisher
getPublisher().sendMessage(factory.createEventMessage());
}
@@ -120,11 +123,11 @@
}
else
{
- //handle a single file
- //Create message factory passing in payload path
- FileMessageFactory factory = new FileMessageFactory(getPublisher().getSession(),tempFile.toString());
+ // handle a single file
+ // Create message factory passing in payload path
+ FileMessageFactory factory = new FileMessageFactory(getPublisher().getSession(), tempFile.toString());
- //Send the message generated from the payload using the _publisher
+ // Send the message generated from the payload using the _publisher
getPublisher().sendMessage(factory.createEventMessage());
}
}
@@ -145,15 +148,15 @@
*/
private static Publisher getPublisher()
{
- if (_publisher != null)
- {
- return _publisher;
- }
+ if (_publisher != null)
+ {
+ return _publisher;
+ }
- //Create a _publisher
- _publisher = new Publisher();
+ // Create a _publisher
+ _publisher = new Publisher();
- return _publisher;
+ return _publisher;
}
}
Modified: incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java (original)
+++ incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/publisher/FileMessageFactory.java Thu Apr 19 09:24:30 2007
@@ -47,7 +47,9 @@
}
catch (IOException e)
{
- throw new MessageFactoryException(e.toString());
+ MessageFactoryException mfe = new MessageFactoryException(e.toString());
+ mfe.initCause(e);
+ throw mfe;
}
}
Modified: incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/shared/InitialContextHelper.java
URL: http://svn.apache.org/viewvc/incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/shared/InitialContextHelper.java?view=diff&rev=530474&r1=530473&r2=530474
==============================================================================
--- incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/shared/InitialContextHelper.java (original)
+++ incubator/qpid/trunk/qpid/java/client/example/src/main/java/org/apache/qpid/example/shared/InitialContextHelper.java Thu Apr 19 09:24:30 2007
@@ -59,11 +59,11 @@
}
catch (IOException e)
{
- throw new ContextException(e.toString());
+ throw new ContextException(e.toString(), e);
}
catch (NamingException n)
{
- throw new ContextException(n.toString());
+ throw new ContextException(n.toString(), n);
}
}