diff options
Diffstat (limited to 'java')
12 files changed, 197 insertions, 158 deletions
diff --git a/java/broker/etc/log4j.xml b/java/broker/etc/log4j.xml index b442227607..2fb7b80c96 100644 --- a/java/broker/etc/log4j.xml +++ b/java/broker/etc/log4j.xml @@ -64,6 +64,10 @@ </layout> </appender> + <category name="Qpid.Broker"> + <priority value="info"/> + </category> + <!--<category name="org.apache.qpid.server.store"> <priority value="debug"/> </category--> diff --git a/java/broker/src/main/java/org/apache/qpid/server/Main.java b/java/broker/src/main/java/org/apache/qpid/server/Main.java index 14aa919356..1e5f56fe3a 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/Main.java +++ b/java/broker/src/main/java/org/apache/qpid/server/Main.java @@ -48,6 +48,7 @@ import org.apache.mina.transport.socket.nio.SocketAcceptorConfig; import org.apache.mina.transport.socket.nio.SocketSessionConfig; import org.apache.qpid.AMQException; +import org.apache.qpid.common.QpidProperties; import org.apache.qpid.framing.ProtocolVersion; import org.apache.qpid.pool.ReadWriteThreadModel; import org.apache.qpid.server.configuration.VirtualHostConfiguration; @@ -66,6 +67,7 @@ import org.apache.qpid.url.URLSyntaxException; public class Main { private static final Logger _logger = Logger.getLogger(Main.class); + public static final Logger _brokerLogger = Logger.getLogger("Qpid.Broker"); private static final String DEFAULT_CONFIG_FILE = "etc/config.xml"; @@ -118,25 +120,25 @@ public class Main Option help = new Option("h", "help", false, "print this message"); Option version = new Option("v", "version", false, "print the version information and exit"); Option configFile = - OptionBuilder.withArgName("file").hasArg().withDescription("use given configuration file").withLongOpt("config") - .create("c"); + OptionBuilder.withArgName("file").hasArg().withDescription("use given configuration file").withLongOpt("config") + .create("c"); Option port = - OptionBuilder.withArgName("port").hasArg() - .withDescription("listen on the specified port. Overrides any value in the config file") - .withLongOpt("port").create("p"); + OptionBuilder.withArgName("port").hasArg() + .withDescription("listen on the specified port. Overrides any value in the config file") + .withLongOpt("port").create("p"); Option bind = - OptionBuilder.withArgName("bind").hasArg() - .withDescription("bind to the specified address. Overrides any value in the config file") - .withLongOpt("bind").create("b"); + OptionBuilder.withArgName("bind").hasArg() + .withDescription("bind to the specified address. Overrides any value in the config file") + .withLongOpt("bind").create("b"); Option logconfig = - OptionBuilder.withArgName("logconfig").hasArg() - .withDescription("use the specified log4j xml configuration file. By " - + "default looks for a file named " + DEFAULT_LOG_CONFIG_FILENAME - + " in the same directory as the configuration file").withLongOpt("logconfig").create("l"); + OptionBuilder.withArgName("logconfig").hasArg() + .withDescription("use the specified log4j xml configuration file. By " + + "default looks for a file named " + DEFAULT_LOG_CONFIG_FILENAME + + " in the same directory as the configuration file").withLongOpt("logconfig").create("l"); Option logwatchconfig = - OptionBuilder.withArgName("logwatch").hasArg() - .withDescription("monitor the log file configuration file for changes. Units are seconds. " - + "Zero means do not check for changes.").withLongOpt("logwatch").create("w"); + OptionBuilder.withArgName("logwatch").hasArg() + .withDescription("monitor the log file configuration file for changes. Units are seconds. " + + "Zero means do not check for changes.").withLongOpt("logwatch").create("w"); options.addOption(help); options.addOption(version); @@ -213,7 +215,7 @@ public class Main if (QpidHome == null) { - error = error + "\nNote: "+QPID_HOME+" is not set."; + error = error + "\nNote: " + QPID_HOME + " is not set."; } throw new InitException(error, null); @@ -239,10 +241,14 @@ public class Main ApplicationRegistry.initialise(new ConfigurationFileApplicationRegistry(configFile)); - _logger.info("Starting Qpid.AMQP broker"); + //fixme .. use QpidProperties.getVersionString when we have fixed the classpath issues + // that are causing the broker build to pick up the wrong properties file and hence say + // Starting Qpid Client + _brokerLogger.info("Starting Qpid Broker " + QpidProperties.getReleaseVersion() + + " build: " + QpidProperties.getBuildVersion()); ConnectorConfiguration connectorConfig = - ApplicationRegistry.getInstance().getConfiguredObject(ConnectorConfiguration.class); + ApplicationRegistry.getInstance().getConfiguredObject(ConnectorConfiguration.class); ByteBuffer.setUseDirectBuffers(connectorConfig.enableDirectBuffers); @@ -293,7 +299,7 @@ public class Main } protected void setupVirtualHosts(String configFileParent, String configFilePath) - throws ConfigurationException, AMQException, URLSyntaxException + throws ConfigurationException, AMQException, URLSyntaxException { String configVar = "${conf}"; @@ -320,7 +326,7 @@ public class Main if (fileNames[each].endsWith(".xml")) { VirtualHostConfiguration vHostConfig = - new VirtualHostConfiguration(configFilePath + "/" + fileNames[each]); + new VirtualHostConfiguration(configFilePath + "/" + fileNames[each]); vHostConfig.performBindings(); } } @@ -367,7 +373,7 @@ public class Main } acceptor.bind(bindAddress, handler, sconfig); - _logger.info("Qpid.AMQP listening on non-SSL address " + bindAddress); + _brokerLogger.info("Qpid.AMQP listening on non-SSL address " + bindAddress); } if (connectorConfig.enableSSL) @@ -376,11 +382,11 @@ public class Main try { acceptor.bind(new InetSocketAddress(connectorConfig.sslPort), handler, sconfig); - _logger.info("Qpid.AMQP listening on SSL port " + connectorConfig.sslPort); + _brokerLogger.info("Qpid.AMQP listening on SSL port " + connectorConfig.sslPort); } catch (IOException e) { - _logger.error("Unable to listen on SSL port: " + e, e); + _brokerLogger.error("Unable to listen on SSL port: " + e, e); } } } @@ -434,7 +440,7 @@ public class Main catch (NumberFormatException e) { System.err.println("Log watch configuration value of " + logWatchConfig + " is invalid. Must be " - + "a non-negative integer. Using default of zero (no watching configured"); + + "a non-negative integer. Using default of zero (no watching configured"); } if (logConfigFile.exists() && logConfigFile.canRead()) @@ -443,7 +449,7 @@ public class Main if (logWatchTime > 0) { System.out.println("log file " + logConfigFile.getAbsolutePath() + " will be checked for changes every " - + logWatchTime + " seconds"); + + logWatchTime + " seconds"); // log4j expects the watch interval in milliseconds DOMConfigurator.configureAndWatch(logConfigFile.getAbsolutePath(), logWatchTime * 1000); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java index 38c9e4950a..a14d4214e3 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/management/JMXManagedObjectRegistry.java @@ -83,7 +83,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry } - public void start() + public void start() throws IOException { // Check if the "QPID_OPTS" is set to use Out of the Box JMXAgent if (areOutOfTheBoxJMXOptionsSet()) @@ -97,76 +97,60 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry boolean security = appRegistry.getConfiguration().getBoolean("management.security-enabled", true); int port = appRegistry.getConfiguration().getInt("management.jmxport", 8999); - try + if (security) { - if (security) - { - // For SASL using JMXMP - _jmxURL = new JMXServiceURL("jmxmp", null, port); - - Map env = new HashMap(); - Map<String, PrincipalDatabase> map = appRegistry.getDatabaseManager().getDatabases(); - PrincipalDatabase db = null; - - for (Map.Entry<String, PrincipalDatabase> entry : map.entrySet()) - { - if (entry.getValue() instanceof Base64MD5PasswordFilePrincipalDatabase) - { - db = entry.getValue(); - break; - } - else if (entry.getValue() instanceof PlainPasswordFilePrincipalDatabase) - { - db = entry.getValue(); - } - } - - if (db instanceof Base64MD5PasswordFilePrincipalDatabase) - { - env.put("jmx.remote.profiles", "SASL/CRAM-MD5"); - CRAMMD5HashedInitialiser initialiser = new CRAMMD5HashedInitialiser(); - initialiser.initialise(db); - env.put("jmx.remote.sasl.callback.handler", initialiser.getCallbackHandler()); - } - else if (db instanceof PlainPasswordFilePrincipalDatabase) - { - env.put("jmx.remote.profiles", "SASL/PLAIN"); - env.put("jmx.remote.sasl.callback.handler", new UserCallbackHandler(db)); - } + // For SASL using JMXMP + _jmxURL = new JMXServiceURL("jmxmp", null, port); - // Enable the SSL security and server authentication - /* - SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory(); - SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory(); - env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf); - env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf); - */ + Map env = new HashMap(); + Map<String, PrincipalDatabase> map = appRegistry.getDatabaseManager().getDatabases(); + PrincipalDatabase db = null; - try + for (Map.Entry<String, PrincipalDatabase> entry : map.entrySet()) + { + if (entry.getValue() instanceof Base64MD5PasswordFilePrincipalDatabase) { - JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(_jmxURL, env, _mbeanServer); - MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance(); - cs.setMBeanServerForwarder(mbsf); - cs.start(); - _log.info("JMX: Starting JMXConnector server with SASL"); + db = entry.getValue(); + break; } - catch (java.net.MalformedURLException urlException) + else if (entry.getValue() instanceof PlainPasswordFilePrincipalDatabase) { - // When JMXMPConnector is not available - // java.net.MalformedURLException: Unsupported protocol: jmxmp - _log.info("JMX: Starting JMXConnector server"); - startJMXConnectorServer(port); + db = entry.getValue(); } } - else + + if (db instanceof Base64MD5PasswordFilePrincipalDatabase) + { + env.put("jmx.remote.profiles", "SASL/CRAM-MD5"); + CRAMMD5HashedInitialiser initialiser = new CRAMMD5HashedInitialiser(); + initialiser.initialise(db); + env.put("jmx.remote.sasl.callback.handler", initialiser.getCallbackHandler()); + } + else if (db instanceof PlainPasswordFilePrincipalDatabase) { - startJMXConnectorServer(port); + env.put("jmx.remote.profiles", "SASL/PLAIN"); + env.put("jmx.remote.sasl.callback.handler", new UserCallbackHandler(db)); } + + // Enable the SSL security and server authentication + /* + SslRMIClientSocketFactory csf = new SslRMIClientSocketFactory(); + SslRMIServerSocketFactory ssf = new SslRMIServerSocketFactory(); + env.put(RMIConnectorServer.RMI_CLIENT_SOCKET_FACTORY_ATTRIBUTE, csf); + env.put(RMIConnectorServer.RMI_SERVER_SOCKET_FACTORY_ATTRIBUTE, ssf); + */ + + JMXConnectorServer cs = JMXConnectorServerFactory.newJMXConnectorServer(_jmxURL, env, _mbeanServer); + MBeanServerForwarder mbsf = MBeanInvocationHandlerImpl.newProxyInstance(); + cs.setMBeanServerForwarder(mbsf); + cs.start(); + _log.warn("JMX: Started JMXConnector server with SASL"); + } - catch (Exception ex) + else { - _log.error("Error in initialising Managed Object Registry." + ex.getMessage()); - ex.printStackTrace(); + startJMXConnectorServer(port); + _log.warn("JMX: Started JMXConnector server with security disabled"); } } @@ -280,7 +264,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry String username = ncb.getDefaultName(); try { - authorized = _principalDatabase.verifyPassword(username, new String(pcb.getPassword())); + authorized = _principalDatabase.verifyPassword(username, pcb.getPassword()); } catch (AccountNotFoundException e) { diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java index a79d993afc..7d25fb8c69 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java +++ b/java/broker/src/main/java/org/apache/qpid/server/management/MBeanInvocationHandlerImpl.java @@ -18,6 +18,7 @@ package org.apache.qpid.server.management; import org.apache.qpid.AMQException; +import org.apache.qpid.server.security.access.AMQUserManagementMBean; import org.apache.log4j.Logger; import javax.management.remote.MBeanServerForwarder; @@ -122,8 +123,20 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler Principal principal = principals.iterator().next(); String identity = principal.getName(); + if (isAdminMethod(args)) + { + if (isAdmin(identity)) + { + return method.invoke(mbs, args); + } + else + { + throw new SecurityException("Access denied"); + } + } + // Following users can perform any operation other than "createMBean" and "unregisterMBean" - if (isAdmin(identity) || isAllowedToModify(identity)) + if (isAllowedToModify(identity)) { return method.invoke(mbs, args); } @@ -138,6 +151,41 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler throw new SecurityException("Access denied"); } + private boolean isAdminMethod(Object[] args) + { + if (args[0] instanceof ObjectName) + { + String mbeanMethod = (args.length > 1) ? (String) args[1] : null; + if (mbeanMethod == null) + { + if (args[0] instanceof ObjectName) + { + ObjectName object = (ObjectName) args[0]; + return object.getCanonicalName().contains("UserManagement"); + } + else + { + return false; + } + } + + try + { + MBeanInfo mbeanInfo = mbs.getMBeanInfo((ObjectName) args[0]); + if (mbeanInfo != null) + { + return mbeanInfo.getClassName().equals("org.apache.qpid.server.security.access.AMQUserManagementMBean"); + } + } + catch (JMException ex) + { + return false; + } + } + + return false; + } + // Initialises the user roles public static void setAccessRights(Properties accessRights) { @@ -155,7 +203,8 @@ public class MBeanInvocationHandlerImpl implements InvocationHandler private boolean isAllowedToModify(String userName) { - if (READWRITE.equals(_userRoles.getProperty(userName))) + if (ADMIN.equals(_userRoles.getProperty(userName)) + || READWRITE.equals(_userRoles.getProperty(userName))) { return true; } diff --git a/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java b/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java index 5f9bc9ddad..d8d87ef881 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java +++ b/java/broker/src/main/java/org/apache/qpid/server/management/ManagedObjectRegistry.java @@ -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 @@ -22,6 +22,7 @@ package org.apache.qpid.server.management; import javax.management.JMException; import java.rmi.RemoteException; +import java.io.IOException; /** * Handles the registration (and unregistration and so on) of managed objects. @@ -37,7 +38,7 @@ import java.rmi.RemoteException; */ public interface ManagedObjectRegistry { - void start(); + void start() throws IOException; void registerObject(ManagedObject managedObject) throws JMException; diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java index 20f123179f..fbb80494c1 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/AMQUserManagementMBean.java @@ -30,6 +30,7 @@ import org.apache.log4j.Logger; import org.apache.commons.configuration.ConfigurationException; import javax.management.JMException; +import javax.management.remote.JMXPrincipal; import javax.management.openmbean.TabularData; import javax.management.openmbean.TabularDataSupport; import javax.management.openmbean.TabularType; @@ -40,6 +41,7 @@ import javax.management.openmbean.OpenDataException; import javax.management.openmbean.CompositeData; import javax.management.openmbean.CompositeDataSupport; import javax.security.auth.login.AccountNotFoundException; +import javax.security.auth.Subject; import java.io.File; import java.io.FileInputStream; import java.io.IOException; @@ -47,8 +49,11 @@ import java.io.FileOutputStream; import java.util.Properties; import java.util.List; import java.util.Enumeration; +import java.util.Set; import java.util.concurrent.locks.ReentrantLock; import java.security.Principal; +import java.security.AccessControlContext; +import java.security.AccessController; /** MBean class for AMQUserManagementMBean. It implements all the management features exposed for managing users. */ @MBeanDescription("User Management Interface") @@ -250,8 +255,6 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana // Table of users // Username(string), Access rights Read,Write,Admin(bool,bool,bool) - reloadData(); - if (_userlistDataType == null) { _logger.warn("TabluarData not setup correctly"); @@ -411,7 +414,7 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana rights.renameTo(old); FileOutputStream output = new FileOutputStream(tmp); - _accessRights.store(output, ""); + _accessRights.store(output, "Last edited by user:" + getCurrentJMXUser()); output.close(); // Rename new file to main file @@ -434,6 +437,22 @@ public class AMQUserManagementMBean extends AMQManagedObject implements UserMana } } + private String getCurrentJMXUser() + { + AccessControlContext acc = AccessController.getContext(); + Subject subject = Subject.getSubject(acc); + + // Retrieve JMXPrincipal from Subject + Set<JMXPrincipal> principals = subject.getPrincipals(JMXPrincipal.class); + if (principals == null || principals.isEmpty()) + { + return "Unknown user principals were null"; + } + + Principal principal = principals.iterator().next(); + return principal.getName(); + } + /** * user=read user=write user=readwrite user=admin * diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java b/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java index ce5e9fa4a7..ec7031534b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/access/UserManagement.java @@ -28,6 +28,7 @@ import org.apache.qpid.AMQException; import javax.management.openmbean.TabularData; import javax.management.openmbean.CompositeData; import javax.management.JMException; +import javax.management.MBeanOperationInfo; import java.io.IOException; public interface UserManagement @@ -43,7 +44,8 @@ public interface UserManagement * * @return The result of the operation */ - @MBeanOperation(name = "setPassword", description = "Set password for user.") + @MBeanOperation(name = "setPassword", description = "Set password for user.", + impact = MBeanOperationInfo.ACTION) boolean setPassword(@MBeanOperationParameter(name = "username", description = "Username")String username, @MBeanOperationParameter(name = "password", description = "Password")char[] password); @@ -57,7 +59,8 @@ public interface UserManagement * * @return The result of the operation */ - @MBeanOperation(name = "setRights", description = "Set access rights for user.") + @MBeanOperation(name = "setRights", description = "Set access rights for user.", + impact = MBeanOperationInfo.ACTION) boolean setRights(@MBeanOperationParameter(name = "username", description = "Username")String username, @MBeanOperationParameter(name = "read", description = "Administration read")boolean read, @MBeanOperationParameter(name = "write", description = "Administration write")boolean write, @@ -74,7 +77,8 @@ public interface UserManagement * * @return The result of the operation */ - @MBeanOperation(name = "createUser", description = "Create new user from system.") + @MBeanOperation(name = "createUser", description = "Create new user from system.", + impact = MBeanOperationInfo.ACTION) boolean createUser(@MBeanOperationParameter(name = "username", description = "Username")String username, @MBeanOperationParameter(name = "password", description = "Password")char[] password, @MBeanOperationParameter(name = "read", description = "Administration read")boolean read, @@ -88,7 +92,8 @@ public interface UserManagement * * @return The result of the operation */ - @MBeanOperation(name = "deleteUser", description = "Delete user from system.") + @MBeanOperation(name = "deleteUser", description = "Delete user from system.", + impact = MBeanOperationInfo.ACTION) boolean deleteUser(@MBeanOperationParameter(name = "username", description = "Username")String username); @@ -97,15 +102,17 @@ public interface UserManagement * * @return The result of the operation */ -// @MBeanOperation(name = "reloadData", description = "Reload the authentication file from disk.") -// boolean reloadData(); + @MBeanOperation(name = "reloadData", description = "Reload the authentication file from disk.", + impact = MBeanOperationInfo.ACTION) + boolean reloadData(); /** * View users returns all the users that are currently available to the system. * * @return a table of users data (Username, read, write, admin) */ - @MBeanOperation(name = "viewUsers", description = "All users with access rights to the system.") + @MBeanOperation(name = "viewUsers", description = "All users with access rights to the system.", + impact = MBeanOperationInfo.INFO) TabularData viewUsers(); } 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 cd0a371b48..8ade3cdd98 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 @@ -153,27 +153,19 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase * * @throws AccountNotFoundException if the principal cannot be found */ - public boolean verifyPassword(String principal, String password) throws AccountNotFoundException + public boolean verifyPassword(String principal, char[] password) throws AccountNotFoundException { - try - { - char[] pwd = lookupPassword(principal); - byte[] passwordBytes = password.getBytes(DEFAULT_ENCODING); + char[] pwd = lookupPassword(principal); - int index = 0; - boolean verified = true; + int index = 0; + boolean verified = true; - while (verified & index < passwordBytes.length) - { - verified = (pwd[index] == (char) passwordBytes[index]); - index++; - } - return verified; - } - catch (UnsupportedEncodingException e) + while (verified & index < password.length) { - return false; + verified = (pwd[index] == password[index]); + index++; } + return verified; } public boolean updatePassword(Principal principal, char[] password) throws AccountNotFoundException @@ -590,7 +582,7 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase int index = 0; for (char c : _password) { - byteArray[index++] = (byte)c; + byteArray[index++] = (byte) c; } _encodedPassword = (new Base64()).encode(byteArray); } diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java index 90d08c963e..5170f6216c 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java @@ -121,13 +121,13 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase } } - public boolean verifyPassword(String principal, String password) throws AccountNotFoundException + public boolean verifyPassword(String principal, char[] password) throws AccountNotFoundException { try { char[] pwd = lookupPassword(principal); - return compareCharArray(pwd, convertPassword(password)); + return compareCharArray(pwd, password); } catch (IOException e) { @@ -135,22 +135,6 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase } } - 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, char[] password) throws AccountNotFoundException { return false; // updates denied diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java index 494d8e0bf4..a82f9ed40b 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java @@ -55,7 +55,7 @@ public interface PrincipalDatabase * @return true if password is correct * @throws AccountNotFoundException if the principal cannot be found */ - boolean verifyPassword(String principal, String password) + boolean verifyPassword(String principal, char[] password) throws AccountNotFoundException; /** diff --git a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java index 74c330f606..49cd71e978 100644 --- a/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java +++ b/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java @@ -79,18 +79,12 @@ public class PropertiesPrincipalDatabase implements PrincipalDatabase } } - public boolean verifyPassword(String principal, String password) throws AccountNotFoundException + public boolean verifyPassword(String principal, char[] password) throws AccountNotFoundException { + //fixme this is not correct as toCharArray is not safe based on the type of string. char[] pwd = _users.getProperty(principal).toCharArray(); - try - { - return compareCharArray(pwd, convertPassword(password)); - } - catch (UnsupportedEncodingException e) - { - return false; - } + return compareCharArray(pwd, password); } public boolean updatePassword(Principal principal, char[] password) throws AccountNotFoundException diff --git a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java index 0c1da5c278..a5c5763db1 100644 --- a/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java +++ b/java/broker/src/test/java/org/apache/qpid/server/queue/AMQQueueAlertTest.java @@ -64,7 +64,7 @@ public class AMQQueueAlertTest extends TestCase */ public void testMessageCountAlert() throws Exception { - _queue = new AMQQueue(new AMQShortString("testQueue1"), false, new AMQShortString("AMQueueAlertTest"), + _queue = new AMQQueue(new AMQShortString("testQueue1"), false, new AMQShortString("AMQueueAlertTest"), false, _virtualHost); _queueMBean = (AMQQueueMBean) _queue.getManagedObject(); @@ -87,7 +87,7 @@ public class AMQQueueAlertTest extends TestCase */ public void testMessageSizeAlert() throws Exception { - _queue = new AMQQueue(new AMQShortString("testQueue2"), false, new AMQShortString("AMQueueAlertTest"), + _queue = new AMQQueue(new AMQShortString("testQueue2"), false, new AMQShortString("AMQueueAlertTest"), false, _virtualHost); _queueMBean = (AMQQueueMBean) _queue.getManagedObject(); _queueMBean.setMaximumMessageCount(MAX_MESSAGE_COUNT); @@ -112,7 +112,7 @@ public class AMQQueueAlertTest extends TestCase */ public void testQueueDepthAlertNoSubscriber() throws Exception { - _queue = new AMQQueue(new AMQShortString("testQueue3"), false, new AMQShortString("AMQueueAlertTest"), + _queue = new AMQQueue(new AMQShortString("testQueue3"), false, new AMQShortString("AMQueueAlertTest"), false, _virtualHost); _queueMBean = (AMQQueueMBean) _queue.getManagedObject(); _queueMBean.setMaximumMessageCount(MAX_MESSAGE_COUNT); @@ -138,7 +138,7 @@ public class AMQQueueAlertTest extends TestCase */ public void testMessageAgeAlert() throws Exception { - _queue = new AMQQueue(new AMQShortString("testQueue4"), false, new AMQShortString("AMQueueAlertTest"), + _queue = new AMQQueue(new AMQShortString("testQueue4"), false, new AMQShortString("AMQueueAlertTest"), false, _virtualHost); _queueMBean = (AMQQueueMBean) _queue.getManagedObject(); _queueMBean.setMaximumMessageCount(MAX_MESSAGE_COUNT); @@ -175,19 +175,19 @@ public class AMQQueueAlertTest extends TestCase _queue = getNewQueue(); _queue.registerProtocolSession(protocolSession, channel.getChannelId(), new AMQShortString("consumer_tag"), true, null, false, false); - + _queueMBean = (AMQQueueMBean) _queue.getManagedObject(); _queueMBean.setMaximumMessageCount(9999l); // Set a high value, because this is not being tested _queueMBean.setMaximumQueueDepth(MAX_QUEUE_DEPTH); // Send messages(no of message to be little more than what can cause a Queue_Depth alert) - int messageCount = Math.round(MAX_QUEUE_DEPTH/MAX_MESSAGE_SIZE) + 10; + int messageCount = Math.round(MAX_QUEUE_DEPTH / MAX_MESSAGE_SIZE) + 10; long totalSize = (messageCount * MAX_MESSAGE_SIZE) >> 10; sendMessages(messageCount, MAX_MESSAGE_SIZE); // Check queueDepth. There should be no messages on the queue and as the subscriber is listening // so there should be no Queue_Deoth alert raised - assertTrue(_queueMBean.getQueueDepth() == 0); + assertEquals(new Long(0), new Long(_queueMBean.getQueueDepth())); Notification lastNotification = _queueMBean.getLastNotification(); assertNull(lastNotification); @@ -196,14 +196,13 @@ public class AMQQueueAlertTest extends TestCase _queue.unregisterProtocolSession(protocolSession, channel.getChannelId(), new AMQShortString("consumer_tag")); channel.requeue(); - assertTrue(_queueMBean.getQueueDepth() == totalSize); + assertEquals(new Long(totalSize), new Long(_queueMBean.getQueueDepth())); lastNotification = _queueMBean.getLastNotification(); assertNotNull(lastNotification); String notificationMsg = lastNotification.getMessage(); assertTrue(notificationMsg.startsWith(NotificationCheck.QUEUE_DEPTH_ALERT.name())); - // Connect a consumer again and check QueueDepth values. The queue should get emptied. // Messages will get delivered but still are unacknowledged. _queue.registerProtocolSession(protocolSession, channel.getChannelId(), @@ -213,19 +212,19 @@ public class AMQQueueAlertTest extends TestCase { Thread.sleep(100); } - assertTrue(_queueMBean.getQueueDepth() == 0); + assertEquals(new Long(0), new Long(_queueMBean.getQueueDepth())); // Kill the subscriber again. Now those messages should get requeued again. Check if the queue depth // value is correct. _queue.unregisterProtocolSession(protocolSession, channel.getChannelId(), new AMQShortString("consumer_tag")); channel.requeue(); - assertTrue(_queueMBean.getQueueDepth() == totalSize); + assertEquals(new Long(totalSize), new Long(_queueMBean.getQueueDepth())); protocolSession.closeSession(); // Check the clear queue _queueMBean.clearQueue(); - assertTrue(_queueMBean.getQueueDepth() == 0); + assertEquals(new Long(0), new Long(_queueMBean.getQueueDepth())); } protected AMQMessage message(final boolean immediate, long size) throws AMQException @@ -272,7 +271,7 @@ public class AMQQueueAlertTest extends TestCase private void sendMessages(long messageCount, long size) throws AMQException { - AMQMessage[] messages = new AMQMessage[(int)messageCount]; + AMQMessage[] messages = new AMQMessage[(int) messageCount]; for (int i = 0; i < messages.length; i++) { messages[i] = message(false, size); |
