summaryrefslogtreecommitdiff
path: root/qpid/java/broker/src/main/java/org/apache/qpid/server/security
diff options
context:
space:
mode:
Diffstat (limited to 'qpid/java/broker/src/main/java/org/apache/qpid/server/security')
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java3
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java10
-rwxr-xr-xqpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java40
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java27
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java99
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.java99
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java17
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java484
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java475
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java55
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PasswordPrincipal.java40
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java452
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java19
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java12
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java22
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java9
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java50
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java8
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java18
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java13
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java40
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java5
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java10
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java6
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java2
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainInitialiser.java4
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainPasswordCallback.java3
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServer.java68
-rw-r--r--qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java3
44 files changed, 803 insertions, 1359 deletions
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java
index ff80499bc2..704e50da5c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractPlugin.java
@@ -20,8 +20,8 @@
*/
package org.apache.qpid.server.security;
-import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
+
import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.ObjectType;
@@ -32,9 +32,9 @@ import org.apache.qpid.server.security.access.Operation;
*/
public abstract class AbstractPlugin implements SecurityPlugin
{
- protected final Logger _logger = Logger.getLogger(getClass());
+ private final Logger _logger = Logger.getLogger(getClass());
- protected ConfigurationPlugin _config;
+ private ConfigurationPlugin _config;
public Result getDefault()
{
@@ -50,4 +50,8 @@ public abstract class AbstractPlugin implements SecurityPlugin
_config = config;
}
+ public ConfigurationPlugin getConfig()
+ {
+ return _config;
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java
index ec11e2d39c..236931e8cd 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AbstractProxyPlugin.java
@@ -20,7 +20,6 @@
*/
package org.apache.qpid.server.security;
-import org.apache.commons.configuration.Configuration;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.ObjectType;
import org.apache.qpid.server.security.access.Operation;
@@ -28,8 +27,6 @@ import org.apache.qpid.server.security.access.Operation;
/**
* This {@link SecurityPlugin} proxies the authorise calls to a serries of methods, one per {@link Operation}.
*
- * Plugins that extend this class should override the relevant authorise method and implement their own
- * {@link #setConfiguration(Configuration)} method.
*/
public abstract class AbstractProxyPlugin extends AbstractPlugin
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java
index 3d8c77a86f..8f3bdf7738 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/AuthorizationHolder.java
@@ -20,12 +20,8 @@
*/
package org.apache.qpid.server.security;
-import java.security.Principal;
-
import javax.security.auth.Subject;
-
-import org.apache.qpid.server.security.auth.sasl.GroupPrincipal;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import java.security.Principal;
/**
* Represents the authorization of the logged on user.
@@ -35,8 +31,8 @@ public interface AuthorizationHolder
{
/**
* Returns the {@link Subject} of the authorized user. This is guaranteed to
- * contain at least one {@link UsernamePrincipal}, representing the the identity
- * used when the user logged on to the application, and zero or more {@link GroupPrincipal}
+ * contain at least one {@link org.apache.qpid.server.security.auth.sasl.UsernamePrincipal}, representing the the identity
+ * used when the user logged on to the application, and zero or more {@link org.apache.qpid.server.security.auth.sasl.GroupPrincipal}
* representing the group(s) to which the user belongs.
*
* @return the Subject
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
index 2a1ae8a870..436660cfaf 100755
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityManager.java
@@ -18,6 +18,19 @@
*/
package org.apache.qpid.server.security;
+import org.apache.commons.configuration.Configuration;
+import org.apache.commons.configuration.ConfigurationException;
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+import org.apache.qpid.server.exchange.Exchange;
+import org.apache.qpid.server.plugins.PluginManager;
+import org.apache.qpid.server.queue.AMQQueue;
+import org.apache.qpid.server.security.access.ObjectProperties;
+import org.apache.qpid.server.security.access.Operation;
+
import static org.apache.qpid.server.security.access.ObjectType.EXCHANGE;
import static org.apache.qpid.server.security.access.ObjectType.METHOD;
import static org.apache.qpid.server.security.access.ObjectType.QUEUE;
@@ -30,26 +43,17 @@ import static org.apache.qpid.server.security.access.Operation.PUBLISH;
import static org.apache.qpid.server.security.access.Operation.PURGE;
import static org.apache.qpid.server.security.access.Operation.UNBIND;
+import javax.security.auth.Subject;
import java.net.SocketAddress;
-import java.security.Principal;
-import java.util.*;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.LinkedHashMap;
+import java.util.List;
+import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap;
-import javax.security.auth.Subject;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.log4j.Logger;
-import org.apache.qpid.framing.AMQShortString;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.exchange.Exchange;
-import org.apache.qpid.server.plugins.PluginManager;
-import org.apache.qpid.server.queue.AMQQueue;
-import org.apache.qpid.server.security.access.ObjectProperties;
-import org.apache.qpid.server.security.access.Operation;
-
/**
* The security manager contains references to all loaded {@link SecurityPlugin}s and delegates security decisions to them based
* on virtual host name. The plugins can be external <em>OSGi</em> .jar files that export the required classes or just internal
@@ -61,7 +65,7 @@ public class SecurityManager
{
private static final Logger _logger = Logger.getLogger(SecurityManager.class);
- /** Container for the {@link Principal} that is using to this thread. */
+ /** Container for the {@link java.security.Principal} that is using to this thread. */
private static final ThreadLocal<Subject> _subject = new ThreadLocal<Subject>();
private static final ThreadLocal<Boolean> _accessChecksDisabled = new ThreadLocal<Boolean>()
{
@@ -101,7 +105,7 @@ public class SecurityManager
public void validateConfiguration() throws ConfigurationException
{
- if (_configuration.isEmpty())
+ if (getConfig().isEmpty())
{
throw new ConfigurationException("security section is incomplete, no elements found.");
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java
index 5ee7833c4c..21c2d1cda5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/SecurityPluginActivator.java
@@ -21,10 +21,11 @@
package org.apache.qpid.server.security;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
import org.osgi.framework.BundleActivator;
import org.osgi.framework.BundleContext;
+import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
+
/**
* An OSGi {@link BundleActivator} that loads a {@link SecurityPluginFactory}.
*/
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
index 8a52d31f97..a9ec4d1647 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectProperties.java
@@ -18,13 +18,17 @@
*/
package org.apache.qpid.server.security.access;
-import java.util.*;
-
import org.apache.commons.lang.StringUtils;
+
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.server.exchange.Exchange;
import org.apache.qpid.server.queue.AMQQueue;
+import java.util.ArrayList;
+import java.util.EnumMap;
+import java.util.List;
+import java.util.Map;
+
/**
* An set of properties for an access control v2 rule {@link ObjectType}.
*
@@ -315,19 +319,28 @@ public class ObjectProperties
|| ruleValue.equals(STAR)
|| (ruleValue.endsWith(STAR)
&& thisValue != null
- && thisValue.length() > ruleValue.length()
- && thisValue.startsWith(ruleValue.substring(0, ruleValue.length() - 2)));
+ && thisValue.length() >= ruleValue.length() - 1
+ && thisValue.startsWith(ruleValue.substring(0, ruleValue.length() - 1)));
}
@Override
public boolean equals(Object o)
{
- if (this == o) return true;
- if (o == null || getClass() != o.getClass()) return false;
+ if (this == o)
+ {
+ return true;
+ }
+ if (o == null || getClass() != o.getClass())
+ {
+ return false;
+ }
ObjectProperties that = (ObjectProperties) o;
- if (_properties != null ? !_properties.equals(that._properties) : that._properties != null) return false;
+ if (_properties != null ? !_properties.equals(that._properties) : that._properties != null)
+ {
+ return false;
+ }
return true;
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
index 69c7ff185a..90ecd1dd17 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/ObjectType.java
@@ -18,7 +18,15 @@
*/
package org.apache.qpid.server.security.access;
-import static org.apache.qpid.server.security.access.Operation.*;
+import static org.apache.qpid.server.security.access.Operation.ACCESS;
+import static org.apache.qpid.server.security.access.Operation.BIND;
+import static org.apache.qpid.server.security.access.Operation.CONSUME;
+import static org.apache.qpid.server.security.access.Operation.CREATE;
+import static org.apache.qpid.server.security.access.Operation.DELETE;
+import static org.apache.qpid.server.security.access.Operation.PUBLISH;
+import static org.apache.qpid.server.security.access.Operation.PURGE;
+import static org.apache.qpid.server.security.access.Operation.UNBIND;
+import static org.apache.qpid.server.security.access.Operation.UPDATE;
import java.util.EnumSet;
import java.util.Set;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java
deleted file mode 100644
index db18a89231..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/AllowAll.java
+++ /dev/null
@@ -1,99 +0,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
- *
- * 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.access.plugins;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.SecurityPluginFactory;
-
-/** Always allow. */
-public class AllowAll extends BasicPlugin
-{
- public static class AllowAllConfiguration extends ConfigurationPlugin {
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public List<String> getParentPaths()
- {
- return Arrays.asList("security.allow-all", "virtualhosts.virtualhost.security.allow-all");
- }
-
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new AllowAllConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
- };
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- public void validateConfiguration() throws ConfigurationException
- {
-// if (!_configuration.isEmpty())
-// {
-// throw new ConfigurationException("allow-all section takes no elements.");
-// }
- }
-
- }
-
- public static final SecurityPluginFactory<AllowAll> FACTORY = new SecurityPluginFactory<AllowAll>()
- {
- public AllowAll newInstance(ConfigurationPlugin config) throws ConfigurationException
- {
- AllowAllConfiguration configuration = config.getConfiguration(AllowAllConfiguration.class.getName());
-
- // If there is no configuration for this plugin then don't load it.
- if (configuration == null)
- {
- return null;
- }
-
- AllowAll plugin = new AllowAll();
- plugin.configure(configuration);
- return plugin;
- }
-
- public String getPluginName()
- {
- return AllowAll.class.getName();
- }
-
- public Class<AllowAll> getPluginClass()
- {
- return AllowAll.class;
- }
- };
-
- @Override
- public Result getDefault()
- {
- return Result.ALLOWED;
- }
-
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java
index f3161551dc..4df135a4ca 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/BasicPlugin.java
@@ -20,16 +20,14 @@
*/
package org.apache.qpid.server.security.access.plugins;
-import org.apache.commons.configuration.ConfigurationException;
import org.apache.qpid.server.security.AbstractPlugin;
import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.SecurityPlugin;
import org.apache.qpid.server.security.access.ObjectProperties;
import org.apache.qpid.server.security.access.ObjectType;
import org.apache.qpid.server.security.access.Operation;
/**
- * This {@link SecurityPlugin} simply abstains from all authorisation requests and ignores configuration.
+ * This {@link org.apache.qpid.server.security.SecurityPlugin} simply abstains from all authorisation requests and ignores configuration.
*/
public abstract class BasicPlugin extends AbstractPlugin
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.java
deleted file mode 100644
index 6c0fb1eaa4..0000000000
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/DenyAll.java
+++ /dev/null
@@ -1,99 +0,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
- *
- * 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.access.plugins;
-
-import java.util.Arrays;
-import java.util.List;
-
-import org.apache.commons.configuration.Configuration;
-import org.apache.commons.configuration.ConfigurationException;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
-import org.apache.qpid.server.security.Result;
-import org.apache.qpid.server.security.SecurityPluginFactory;
-
-/** Always Deny. */
-public class DenyAll extends BasicPlugin
-{
- public static class DenyAllConfiguration extends ConfigurationPlugin {
- public static final ConfigurationPluginFactory FACTORY = new ConfigurationPluginFactory()
- {
- public List<String> getParentPaths()
- {
- return Arrays.asList("security.deny-all", "virtualhosts.virtualhost.security.deny-all");
- }
-
- public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
- {
- ConfigurationPlugin instance = new DenyAllConfiguration();
- instance.setConfiguration(path, config);
- return instance;
- }
- };
-
- public String[] getElementsProcessed()
- {
- return new String[] { "" };
- }
-
- public void validateConfiguration() throws ConfigurationException
- {
- if (!_configuration.isEmpty())
- {
- throw new ConfigurationException("deny-all section takes no elements.");
- }
- }
-
- }
-
- public static final SecurityPluginFactory<DenyAll> FACTORY = new SecurityPluginFactory<DenyAll>()
- {
- public DenyAll newInstance(ConfigurationPlugin config) throws ConfigurationException
- {
- DenyAllConfiguration configuration = config.getConfiguration(DenyAllConfiguration.class.getName());
-
- // If there is no configuration for this plugin then don't load it.
- if (configuration == null)
- {
- return null;
- }
-
- DenyAll plugin = new DenyAll();
- plugin.configure(configuration);
- return plugin;
- }
-
- public String getPluginName()
- {
- return DenyAll.class.getName();
- }
-
- public Class<DenyAll> getPluginClass()
- {
- return DenyAll.class;
- }
- };
-
- @Override
- public Result getDefault()
- {
- return Result.DENIED;
- }
-
-}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java
index bd99cdd1fa..4b7a2fb457 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/access/plugins/LegacyAccess.java
@@ -18,18 +18,19 @@
*/
package org.apache.qpid.server.security.access.plugins;
-import java.util.Arrays;
-import java.util.List;
-
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
+
import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
-import org.apache.qpid.server.configuration.VirtualHostConfiguration;
-import org.apache.qpid.server.configuration.ServerConfiguration;
import org.apache.qpid.server.configuration.plugins.ConfigurationPluginFactory;
import org.apache.qpid.server.security.SecurityPluginFactory;
-/** Always Abstain. */
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * The <code>LegacyAccess</code> plugin is used internally and simply ignores legacy elements of the configuration file.
+ */
public class LegacyAccess extends BasicPlugin
{
public static class LegacyAccessConfiguration extends ConfigurationPlugin {
@@ -37,9 +38,7 @@ public class LegacyAccess extends BasicPlugin
{
public List<String> getParentPaths()
{
- return Arrays.asList("security.jmx", "virtualhosts.virtualhost.security.jmx",
- "security.msg-auth", "virtualhosts.virtualhost.security.msg-auth",
- "security.principal-databases", "virtualhosts.virtualhost.security.principal-databases");
+ return Arrays.asList("security.msg-auth", "virtualhosts.virtualhost.security.msg-auth");
}
public ConfigurationPlugin newInstance(String path, Configuration config) throws ConfigurationException
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
index 8c2d60a660..949c0f2b89 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java
@@ -53,8 +53,8 @@ public class AuthenticationResult
ERROR
}
- public final AuthenticationStatus _status;
- public final byte[] _challenge;
+ private final AuthenticationStatus _status;
+ private final byte[] _challenge;
private final Exception _cause;
private final Subject _subject;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java
new file mode 100644
index 0000000000..7088fae50c
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/AbstractPasswordFilePrincipalDatabase.java
@@ -0,0 +1,484 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.security.auth.database;
+
+import org.apache.log4j.Logger;
+import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.AccountNotFoundException;
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.FileReader;
+import java.io.IOException;
+import java.io.PrintStream;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Random;
+import java.util.concurrent.locks.ReentrantLock;
+import java.util.regex.Pattern;
+
+public abstract class AbstractPasswordFilePrincipalDatabase<U extends PasswordPrincipal> implements PrincipalDatabase
+{
+ private final Pattern _regexp = Pattern.compile(":");
+
+ private final Map<String, AuthenticationProviderInitialiser> _saslServers =
+ new HashMap<String, AuthenticationProviderInitialiser>();
+
+ protected static final String DEFAULT_ENCODING = "utf-8";
+ private final Map<String, U> _userMap = new HashMap<String, U>();
+ private final ReentrantLock _userUpdate = new ReentrantLock();
+ private final Random _random = new Random();
+ private File _passwordFile;
+
+
+ protected AbstractPasswordFilePrincipalDatabase(UsernamePasswordInitialiser... initialisers)
+ {
+ for(UsernamePasswordInitialiser initialiser : initialisers)
+ {
+ initialiser.initialise(this);
+ _saslServers.put(initialiser.getMechanismName(), initialiser);
+ }
+ }
+
+ public final void setPasswordFile(String passwordFile) throws IOException
+ {
+ File f = new File(passwordFile);
+ getLogger().info("PasswordFile using file " + f.getAbsolutePath());
+ _passwordFile = f;
+ if (!f.exists())
+ {
+ throw new FileNotFoundException("Cannot find password file " + f);
+ }
+ if (!f.canRead())
+ {
+ throw new FileNotFoundException("Cannot read password file " + f +
+ ". Check permissions.");
+ }
+
+ loadPasswordFile();
+ }
+
+ /**
+ * SASL Callback Mechanism - sets the Password in the PasswordCallback based on the value in the PasswordFile
+ * If you want to change the password for a user, use updatePassword instead.
+ *
+ * @param principal The Principal to set the password for
+ * @param callback The PasswordCallback to call setPassword on
+ *
+ * @throws javax.security.auth.login.AccountNotFoundException If the Principal cannot be found in this Database
+ */
+ public final void setPassword(Principal principal, PasswordCallback callback) throws AccountNotFoundException
+ {
+ if (_passwordFile == null)
+ {
+ throw new AccountNotFoundException("Unable to locate principal since no password file was specified during initialisation");
+ }
+ if (principal == null)
+ {
+ throw new IllegalArgumentException("principal must not be null");
+ }
+ char[] pwd = lookupPassword(principal.getName());
+
+ if (pwd != null)
+ {
+ callback.setPassword(pwd);
+ }
+ else
+ {
+ throw new AccountNotFoundException("No account found for principal " + principal);
+ }
+ }
+
+
+ /**
+ * 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 The principal name to lookup
+ *
+ * @return a char[] for use in SASL.
+ */
+ protected final char[] lookupPassword(String name)
+ {
+ U user = _userMap.get(name);
+ if (user == null)
+ {
+ return null;
+ }
+ else
+ {
+ return user.getPassword();
+ }
+ }
+
+ protected 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;
+ }
+
+ /**
+ * Changes the password for the specified user
+ *
+ * @param principal to change the password for
+ * @param password plaintext password to set the password too
+ */
+ public boolean updatePassword(Principal principal, char[] password) throws AccountNotFoundException
+ {
+ U user = _userMap.get(principal.getName());
+
+ if (user == null)
+ {
+ throw new AccountNotFoundException(principal.getName());
+ }
+
+ char[] orig = user.getPassword();
+ _userUpdate.lock();
+ try
+ {
+ user.setPassword(password);
+
+ savePasswordFile();
+
+ return true;
+ }
+ catch (IOException e)
+ {
+ getLogger().error("Unable to save password file due to '" + e.getMessage()
+ + "', password change for user '" + principal + "' discarded");
+ //revert the password change
+ user.restorePassword(orig);
+
+ return false;
+ }
+ finally
+ {
+ _userUpdate.unlock();
+ }
+ }
+
+
+ private void loadPasswordFile() throws IOException
+ {
+ try
+ {
+ _userUpdate.lock();
+ _userMap.clear();
+
+ BufferedReader reader = null;
+ try
+ {
+ reader = new BufferedReader(new FileReader(_passwordFile));
+ String line;
+
+ while ((line = reader.readLine()) != null)
+ {
+ String[] result = _regexp.split(line);
+ if (result == null || result.length < 2 || result[0].startsWith("#"))
+ {
+ continue;
+ }
+
+ U user = createUserFromFileData(result);
+ getLogger().info("Created user:" + user);
+ _userMap.put(user.getName(), user);
+ }
+ }
+ finally
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+ }
+ }
+ finally
+ {
+ _userUpdate.unlock();
+ }
+ }
+
+ protected abstract U createUserFromFileData(String[] result);
+
+
+ protected abstract Logger getLogger();
+
+ protected File createTempFileOnSameFilesystem()
+ {
+ File liveFile = _passwordFile;
+ File tmp;
+
+ do
+ {
+ tmp = new File(liveFile.getPath() + _random.nextInt() + ".tmp");
+ }
+ while(tmp.exists());
+
+ tmp.deleteOnExit();
+ return tmp;
+ }
+
+ protected void swapTempFileToLive(final File temp) throws IOException
+ {
+ File live = _passwordFile;
+ // Remove any existing ".old" file
+ final File old = new File(live.getAbsoluteFile() + ".old");
+ if (old.exists())
+ {
+ old.delete();
+ }
+
+ // Create an new ".old" file
+ if(!live.renameTo(old))
+ {
+ //unable to rename the existing file to the backup name
+ getLogger().error("Could not backup the existing password file");
+ throw new IOException("Could not backup the existing password file");
+ }
+
+ // Move temp file to be the new "live" file
+ if(!temp.renameTo(live))
+ {
+ //failed to rename the new file to the required filename
+ if(!old.renameTo(live))
+ {
+ //unable to return the backup to required filename
+ getLogger().error(
+ "Could not rename the new password file into place, and unable to restore original file");
+ throw new IOException("Could not rename the new password file into place, and unable to restore original file");
+ }
+
+ getLogger().error("Could not rename the new password file into place");
+ throw new IOException("Could not rename the new password file into place");
+ }
+ }
+
+ protected void savePasswordFile() throws IOException
+ {
+ try
+ {
+ _userUpdate.lock();
+
+ BufferedReader reader = null;
+ PrintStream writer = null;
+
+ File tmp = createTempFileOnSameFilesystem();
+
+ try
+ {
+ writer = new PrintStream(tmp);
+ reader = new BufferedReader(new FileReader(_passwordFile));
+ String line;
+
+ while ((line = reader.readLine()) != null)
+ {
+ String[] result = _regexp.split(line);
+ if (result == null || result.length < 2 || result[0].startsWith("#"))
+ {
+ writer.write(line.getBytes(DEFAULT_ENCODING));
+ writer.println();
+ continue;
+ }
+
+ U user = _userMap.get(result[0]);
+
+ 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
+ {
+ byte[] encodedPassword = user.getEncodedPassword();
+
+ writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING));
+ writer.write(encodedPassword);
+ writer.println();
+
+ user.saved();
+ }
+ }
+ }
+
+ for (U user : _userMap.values())
+ {
+ if (user.isModified())
+ {
+ byte[] encodedPassword;
+ encodedPassword = user.getEncodedPassword();
+ writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING));
+ writer.write(encodedPassword);
+ writer.println();
+ user.saved();
+ }
+ }
+ }
+ catch(IOException e)
+ {
+ getLogger().error("Unable to create the new password file: " + e);
+ throw new IOException("Unable to create the new password file",e);
+ }
+ finally
+ {
+
+ try
+ {
+ if (reader != null)
+ {
+ reader.close();
+ }
+ }
+ finally
+ {
+ if (writer != null)
+ {
+ writer.close();
+ }
+ }
+
+ }
+
+ swapTempFileToLive(tmp);
+ }
+ finally
+ {
+ _userUpdate.unlock();
+ }
+ }
+
+ protected abstract U createUserFromPassword(Principal principal, char[] passwd);
+
+
+ public void reload() throws IOException
+ {
+ loadPasswordFile();
+ }
+
+ public Map<String, AuthenticationProviderInitialiser> getMechanisms()
+ {
+ return _saslServers;
+ }
+
+ public List<Principal> getUsers()
+ {
+ return new LinkedList<Principal>(_userMap.values());
+ }
+
+ public Principal getUser(String username)
+ {
+ if (_userMap.containsKey(username))
+ {
+ return new UsernamePrincipal(username);
+ }
+ return null;
+ }
+
+ public boolean deletePrincipal(Principal principal) throws AccountNotFoundException
+ {
+ U user = _userMap.get(principal.getName());
+
+ if (user == null)
+ {
+ throw new AccountNotFoundException(principal.getName());
+ }
+
+ try
+ {
+ _userUpdate.lock();
+ user.delete();
+
+ try
+ {
+ savePasswordFile();
+ }
+ catch (IOException e)
+ {
+ getLogger().error("Unable to remove user '" + user.getName() + "' from password file.");
+ return false;
+ }
+
+ _userMap.remove(user.getName());
+ }
+ finally
+ {
+ _userUpdate.unlock();
+ }
+
+ return true;
+ }
+
+ public boolean createPrincipal(Principal principal, char[] password)
+ {
+ if (_userMap.get(principal.getName()) != null)
+ {
+ return false;
+ }
+
+ U user = createUserFromPassword(principal, password);
+
+
+ try
+ {
+ _userUpdate.lock();
+ _userMap.put(user.getName(), user);
+
+ try
+ {
+ savePasswordFile();
+ return true;
+ }
+ catch (IOException e)
+ {
+ //remove the use on failure.
+ _userMap.remove(user.getName());
+ return false;
+ }
+ }
+ finally
+ {
+ _userUpdate.unlock();
+ }
+ }
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
index 5a92b33e43..63eb768035 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java
@@ -21,29 +21,12 @@
package org.apache.qpid.server.security.auth.database;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.security.auth.management.AMQUserManagementMBean;
-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.CRAMMD5HexInitialiser;
+
import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser;
-import org.apache.qpid.util.FileUtils;
+import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexInitialiser;
-import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintStream;
import java.security.Principal;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.regex.Pattern;
/**
* Represents a user database where the account information is stored in a simple flat file.
@@ -52,100 +35,19 @@ import java.util.regex.Pattern;
*
* where a carriage return separates each username/password pair. Passwords are assumed to be in plain text.
*/
-public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
+public class Base64MD5PasswordFilePrincipalDatabase extends AbstractPasswordFilePrincipalDatabase<HashedUser>
{
- private static final Logger _logger = Logger.getLogger(Base64MD5PasswordFilePrincipalDatabase.class);
-
- private File _passwordFile;
-
- private Pattern _regexp = Pattern.compile(":");
-
- private Map<String, AuthenticationProviderInitialiser> _saslServers;
-
- AMQUserManagementMBean _mbean;
- public static final String DEFAULT_ENCODING = "utf-8";
- private Map<String, HashedUser> _users = new HashMap<String, HashedUser>();
- private ReentrantLock _userUpdate = new ReentrantLock();
+ private final Logger _logger = Logger.getLogger(Base64MD5PasswordFilePrincipalDatabase.class);
public Base64MD5PasswordFilePrincipalDatabase()
{
- _saslServers = new HashMap<String, AuthenticationProviderInitialiser>();
-
/**
* Create Authenticators for MD5 Password file.
*/
+ super(new CRAMMD5HashedInitialiser(), new CRAMMD5HexInitialiser());
- // Accept Plain incomming and hash it for comparison to the file.
- CRAMMD5HashedInitialiser cram = new CRAMMD5HashedInitialiser();
- cram.initialise(this);
- _saslServers.put(cram.getMechanismName(), cram);
-
- //Add the Hex initialiser
- CRAMMD5HexInitialiser cramHex = new CRAMMD5HexInitialiser();
- cramHex.initialise(this);
- _saslServers.put(cramHex.getMechanismName(), cramHex);
-
- //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 IOException
- {
- File f = new File(passwordFile);
- _logger.info("PasswordFilePrincipalDatabase using file " + f.getAbsolutePath());
- _passwordFile = f;
- if (!f.exists())
- {
- throw new FileNotFoundException("Cannot find password file " + f);
- }
- if (!f.canRead())
- {
- throw new FileNotFoundException("Cannot read password file " + f +
- ". Check permissions.");
- }
-
- loadPasswordFile();
}
- /**
- * SASL Callback Mechanism - sets the Password in the PasswordCallback based on the value in the PasswordFile
- * If you want to change the password for a user, use updatePassword instead.
- *
- * @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)
- {
- throw new AccountNotFoundException("Unable to locate principal since no password file was specified during initialisation");
- }
- if (principal == null)
- {
- throw new IllegalArgumentException("principal must not be null");
- }
-
- char[] pwd = lookupPassword(principal.getName());
-
- if (pwd != null)
- {
- callback.setPassword(pwd);
- }
- else
- {
- throw new AccountNotFoundException("No account found for principal " + principal);
- }
- }
/**
* Used to verify that the presented Password is correct. Currently only used by Management Console
@@ -180,7 +82,7 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
}
catch (Exception e1)
{
- _logger.warn("Unable to hash password for user '" + principal + "' for comparison");
+ getLogger().warn("Unable to hash password for user '" + principal + "' for comparison");
return false;
}
@@ -194,374 +96,21 @@ public class Base64MD5PasswordFilePrincipalDatabase implements PrincipalDatabase
return compareCharArray(pwd, hashedPassword);
}
-
- 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;
- }
- /**
- * Changes the password for the specified user
- *
- * @param principal to change the password for
- * @param password plaintext password to set the password too
- */
- public boolean updatePassword(Principal principal, char[] password) throws AccountNotFoundException
+ protected HashedUser createUserFromPassword(Principal principal, char[] passwd)
{
- HashedUser user = _users.get(principal.getName());
-
- if (user == null)
- {
- throw new AccountNotFoundException(principal.getName());
- }
-
- try
- {
- try
- {
- _userUpdate.lock();
- char[] orig = user.getPassword();
- user.setPassword(password,false);
-
- try
- {
- savePasswordFile();
- }
- catch (IOException e)
- {
- _logger.error("Unable to save password file, password change for user'"
- + principal + "' will revert at restart");
- //revert the password change
- user.setPassword(orig,true);
- return false;
- }
- return true;
- }
- finally
- {
- _userUpdate.unlock();
- }
- }
- catch (Exception e)
- {
- return false;
- }
+ return new HashedUser(principal.getName(), passwd);
}
- public boolean createPrincipal(Principal principal, char[] password)
- {
- if (_users.get(principal.getName()) != null)
- {
- return false;
- }
- HashedUser user;
- try
- {
- user = new HashedUser(principal.getName(), password);
- }
- catch (Exception e1)
- {
- _logger.warn("Unable to create new user '" + principal.getName() + "'");
- return false;
- }
-
-
- try
- {
- _userUpdate.lock();
- _users.put(user.getName(), user);
-
- try
- {
- savePasswordFile();
- return true;
- }
- catch (IOException e)
- {
- //remove the use on failure.
- _users.remove(user.getName());
- return false;
- }
- }
- finally
- {
- _userUpdate.unlock();
- }
- }
-
- public boolean deletePrincipal(Principal principal) throws AccountNotFoundException
- {
- HashedUser 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
- {
- _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 The principal name to lookup
- *
- * @return a char[] for use in SASL.
- */
- private char[] lookupPassword(String name)
+ protected HashedUser createUserFromFileData(String[] result)
{
- HashedUser user = _users.get(name);
- if (user == null)
- {
- return null;
- }
- else
- {
- return user.getPassword();
- }
- }
-
- private void loadPasswordFile() throws IOException
- {
- try
- {
- _userUpdate.lock();
- _users.clear();
-
- BufferedReader reader = null;
- try
- {
- reader = new BufferedReader(new FileReader(_passwordFile));
- String line;
-
- while ((line = reader.readLine()) != null)
- {
- String[] result = _regexp.split(line);
- if (result == null || result.length < 2 || result[0].startsWith("#"))
- {
- continue;
- }
-
- HashedUser user = new HashedUser(result);
- _logger.info("Created user:" + user);
- _users.put(user.getName(), user);
- }
- }
- finally
- {
- if (reader != null)
- {
- reader.close();
- }
- }
- }
- finally
- {
- _userUpdate.unlock();
- }
- }
-
- private void savePasswordFile() throws IOException
- {
- try
- {
- _userUpdate.lock();
-
- BufferedReader reader = null;
- PrintStream writer = null;
-
- Random r = new Random();
- File tmp;
- do
- {
- tmp = new File(_passwordFile.getPath() + r.nextInt() + ".tmp");
- }
- while(tmp.exists());
-
- tmp.deleteOnExit();
-
- try
- {
- writer = new PrintStream(tmp);
- reader = new BufferedReader(new FileReader(_passwordFile));
- String line;
-
- while ((line = reader.readLine()) != null)
- {
- String[] result = _regexp.split(line);
- if (result == null || result.length < 2 || result[0].startsWith("#"))
- {
- writer.write(line.getBytes(DEFAULT_ENCODING));
- writer.println();
- continue;
- }
-
- HashedUser user = _users.get(result[0]);
-
- 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.getEncodedPassword();
-
- 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();
- }
- }
- }
- }
-
- for (HashedUser user : _users.values())
- {
- if (user.isModified())
- {
- byte[] encodedPassword;
- try
- {
- encodedPassword = user.getEncodedPassword();
- 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");
- }
- }
- }
- }
- catch(IOException e)
- {
- _logger.error("Unable to create the new password file: " + e);
- throw new IOException("Unable to create the new password file" + e);
- }
- finally
- {
- if (reader != null)
- {
- reader.close();
- }
-
- if (writer != null)
- {
- writer.close();
- }
- }
-
- // Swap temp file to main password file.
- File old = new File(_passwordFile.getAbsoluteFile() + ".old");
- if (old.exists())
- {
- old.delete();
- }
-
- if(!_passwordFile.renameTo(old))
- {
- //unable to rename the existing file to the backup name
- _logger.error("Could not backup the existing password file");
- throw new IOException("Could not backup the existing password file");
- }
-
- if(!tmp.renameTo(_passwordFile))
- {
- //failed to rename the new file to the required filename
-
- if(!old.renameTo(_passwordFile))
- {
- //unable to return the backup to required filename
- _logger.error("Could not rename the new password file into place, and unable to restore original file");
- throw new IOException("Could not rename the new password file into place, and unable to restore original file");
- }
-
- _logger.error("Could not rename the new password file into place");
- throw new IOException("Could not rename the new password file into place");
- }
- }
- finally
- {
- _userUpdate.unlock();
- }
+ return new HashedUser(result);
}
- public void reload() throws IOException
+ protected Logger getLogger()
{
- loadPasswordFile();
+ return _logger;
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java
index 3690e7f92a..b9de1587b5 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/HashedUser.java
@@ -20,26 +20,25 @@
*/
package org.apache.qpid.server.security.auth.database;
-import org.apache.commons.codec.EncoderException;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
import java.io.UnsupportedEncodingException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;
-import java.security.Principal;
-public class HashedUser implements Principal
+
+public class HashedUser implements PasswordPrincipal
{
private static final Logger _logger = Logger.getLogger(HashedUser.class);
- String _name;
- char[] _password;
- byte[] _encodedPassword = null;
+ private String _name;
+ private char[] _password;
+ private byte[] _encodedPassword = null;
private boolean _modified = false;
private boolean _deleted = false;
- HashedUser(String[] data) throws UnsupportedEncodingException
+ HashedUser(String[] data)
{
if (data.length != 2)
{
@@ -48,7 +47,15 @@ public class HashedUser implements Principal
_name = data[0];
- byte[] encoded_password = data[1].getBytes(Base64MD5PasswordFilePrincipalDatabase.DEFAULT_ENCODING);
+ byte[] encoded_password;
+ try
+ {
+ encoded_password = data[1].getBytes(Base64MD5PasswordFilePrincipalDatabase.DEFAULT_ENCODING);
+ }
+ catch (UnsupportedEncodingException e)
+ {
+ throw new RuntimeException("MD5 encoding not supported, even though the Java standard requires it",e);
+ }
Base64 b64 = new Base64();
byte[] decoded = b64.decode(encoded_password);
@@ -64,15 +71,23 @@ public class HashedUser implements Principal
}
}
- public HashedUser(String name, char[] password) throws UnsupportedEncodingException, NoSuchAlgorithmException
+ public HashedUser(String name, char[] password)
{
_name = name;
setPassword(password,false);
}
- public static byte[] getMD5(byte[] data) throws NoSuchAlgorithmException, UnsupportedEncodingException
+ public static byte[] getMD5(byte[] data)
{
- MessageDigest md = MessageDigest.getInstance("MD5");
+ MessageDigest md = null;
+ try
+ {
+ md = MessageDigest.getInstance("MD5");
+ }
+ catch (NoSuchAlgorithmException e)
+ {
+ throw new RuntimeException("MD5 not supported although Java compliance requires it");
+ }
for (byte b : data)
{
@@ -92,12 +107,22 @@ public class HashedUser implements Principal
return _name;
}
- char[] getPassword()
+ public char[] getPassword()
{
return _password;
}
- void setPassword(char[] password, boolean alreadyHashed) throws UnsupportedEncodingException, NoSuchAlgorithmException
+ public void setPassword(char[] password)
+ {
+ setPassword(password, false);
+ }
+
+ public void restorePassword(char[] password)
+ {
+ setPassword(password, true);
+ }
+
+ void setPassword(char[] password, boolean alreadyHashed)
{
if(alreadyHashed){
_password = password;
@@ -126,7 +151,7 @@ public class HashedUser implements Principal
_encodedPassword = null;
}
- byte[] getEncodedPassword() throws EncoderException, UnsupportedEncodingException, NoSuchAlgorithmException
+ public byte[] getEncodedPassword()
{
if (_encodedPassword == null)
{
@@ -135,7 +160,7 @@ public class HashedUser implements Principal
return _encodedPassword;
}
- private void encodePassword() throws EncoderException, UnsupportedEncodingException, NoSuchAlgorithmException
+ private void encodePassword()
{
byte[] byteArray = new byte[_password.length];
int index = 0;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PasswordPrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PasswordPrincipal.java
new file mode 100644
index 0000000000..8e12d5f0a3
--- /dev/null
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PasswordPrincipal.java
@@ -0,0 +1,40 @@
+/*
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ *
+ */
+package org.apache.qpid.server.security.auth.database;
+
+import java.security.Principal;
+
+interface PasswordPrincipal extends Principal
+{
+ char[] getPassword();
+ byte[] getEncodedPassword();
+
+ void setPassword(char[] password);
+ void restorePassword(char[] password);
+
+ boolean isDeleted();
+
+ boolean isModified();
+
+ void saved();
+
+ void delete();
+}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
index 7cb34da804..bfd04adb3f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java
@@ -21,29 +21,13 @@
package org.apache.qpid.server.security.auth.database;
import org.apache.log4j.Logger;
-import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+
import org.apache.qpid.server.security.auth.sasl.amqplain.AmqPlainInitialiser;
-import org.apache.qpid.server.security.auth.sasl.anonymous.AnonymousInitialiser;
import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser;
import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
-import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
-import java.io.BufferedReader;
-import java.io.File;
-import java.io.FileNotFoundException;
-import java.io.FileReader;
-import java.io.IOException;
-import java.io.PrintStream;
import java.security.Principal;
-import java.util.HashMap;
-import java.util.LinkedList;
-import java.util.List;
-import java.util.Map;
-import java.util.Random;
-import java.util.concurrent.locks.ReentrantLock;
-import java.util.regex.Pattern;
/**
* Represents a user database where the account information is stored in a simple flat file.
@@ -52,102 +36,19 @@ import java.util.regex.Pattern;
*
* where a carriage return separates each username/password pair. Passwords are assumed to be in plain text.
*/
-public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase
+public class PlainPasswordFilePrincipalDatabase extends AbstractPasswordFilePrincipalDatabase<PlainUser>
{
- public static final String DEFAULT_ENCODING = "utf-8";
-
- private static final Logger _logger = Logger.getLogger(PlainPasswordFilePrincipalDatabase.class);
-
- private File _passwordFile;
-
- private Pattern _regexp = Pattern.compile(":");
- private Map<String, AuthenticationProviderInitialiser> _saslServers;
-
- private Map<String, PlainUser> _users = new HashMap<String, PlainUser>();
- private ReentrantLock _userUpdate = new ReentrantLock();
+ private final Logger _logger = Logger.getLogger(PlainPasswordFilePrincipalDatabase.class);
public PlainPasswordFilePrincipalDatabase()
{
- _saslServers = new HashMap<String, AuthenticationProviderInitialiser>();
-
/**
* Create Authenticators for Plain Password file.
*/
-
- // Accept AMQPlain incomming and compare it to the file.
- AmqPlainInitialiser amqplain = new AmqPlainInitialiser();
- amqplain.initialise(this);
-
-
-
- // Accept AMQPlain incomming and compare it to the file.
- AnonymousInitialiser anonymous = new AnonymousInitialiser();
- anonymous.initialise(this);
-
-
- // Accept Plain incomming and compare it to the file.
- PlainInitialiser plain = new PlainInitialiser();
- plain.initialise(this);
-
- // Accept MD5 incomming and Hash file value for comparison
- CRAMMD5Initialiser cram = new CRAMMD5Initialiser();
- cram.initialise(this);
-
- _saslServers.put(amqplain.getMechanismName(), amqplain);
- _saslServers.put(plain.getMechanismName(), plain);
- _saslServers.put(cram.getMechanismName(), cram);
- _saslServers.put(anonymous.getMechanismName(), anonymous);
- }
-
- public void setPasswordFile(String passwordFile) throws IOException
- {
- File f = new File(passwordFile);
- _logger.info("PlainPasswordFile using file " + f.getAbsolutePath());
- _passwordFile = f;
- if (!f.exists())
- {
- throw new FileNotFoundException("Cannot find password file " + f);
- }
- if (!f.canRead())
- {
- throw new FileNotFoundException("Cannot read password file " + f +
- ". Check permissions.");
- }
-
- loadPasswordFile();
+ super(new AmqPlainInitialiser(), new PlainInitialiser(), new CRAMMD5Initialiser());
}
- /**
- * SASL Callback Mechanism - sets the Password in the PasswordCallback based on the value in the PasswordFile
- * If you want to change the password for a user, use updatePassword instead.
- *
- * @param principal The Principal to set the password for
- * @param callback The PasswordCallback to call setPassword on
- *
- * @throws AccountNotFoundException If the Principal cannot be found in this Database
- */
- public void setPassword(Principal principal, PasswordCallback callback) throws AccountNotFoundException
- {
- if (_passwordFile == null)
- {
- throw new AccountNotFoundException("Unable to locate principal since no password file was specified during initialisation");
- }
- if (principal == null)
- {
- throw new IllegalArgumentException("principal must not be null");
- }
- char[] pwd = lookupPassword(principal.getName());
-
- if (pwd != null)
- {
- callback.setPassword(pwd);
- }
- else
- {
- throw new AccountNotFoundException("No account found for principal " + principal);
- }
- }
/**
* Used to verify that the presented Password is correct. Currently only used by Management Console
@@ -173,352 +74,21 @@ public class PlainPasswordFilePrincipalDatabase implements PrincipalDatabase
}
- /**
- * Changes the password for the specified user
- *
- * @param principal to change the password for
- * @param password plaintext password to set the password too
- */
- public boolean updatePassword(Principal principal, char[] password) throws AccountNotFoundException
+ protected PlainUser createUserFromPassword(Principal principal, char[] passwd)
{
- PlainUser user = _users.get(principal.getName());
-
- if (user == null)
- {
- throw new AccountNotFoundException(principal.getName());
- }
-
- char[] orig = user.getPassword();
- _userUpdate.lock();
- try
- {
- user.setPassword(password);
-
- savePasswordFile();
-
- return true;
- }
- catch (IOException e)
- {
- _logger.error("Unable to save password file due to '"+e.getMessage()
- +"', password change for user '" + principal + "' discarded");
- //revert the password change
- user.setPassword(orig);
- return false;
- }
- finally
- {
- _userUpdate.unlock();
- }
+ return new PlainUser(principal.getName(), passwd);
}
- public boolean createPrincipal(Principal principal, char[] password)
- {
- if (_users.get(principal.getName()) != null)
- {
- return false;
- }
-
- PlainUser user = new PlainUser(principal.getName(), password);
-
- try
- {
- _userUpdate.lock();
- _users.put(user.getName(), user);
-
- try
- {
- savePasswordFile();
- return true;
- }
- catch (IOException e)
- {
- //remove the use on failure.
- _users.remove(user.getName());
- _logger.warn("Unable to create user '" + user.getName());
- return false;
- }
- }
- finally
- {
- _userUpdate.unlock();
- }
- }
- public boolean deletePrincipal(Principal principal) throws AccountNotFoundException
+ @Override
+ protected PlainUser createUserFromFileData(String[] result)
{
- PlainUser user = _users.get(principal.getName());
-
- if (user == null)
- {
- throw new AccountNotFoundException(principal.getName());
- }
-
- try
- {
- _userUpdate.lock();
- user.delete();
-
- try
- {
- savePasswordFile();
- }
- catch (IOException e)
- {
- _logger.error("Unable to remove user '" + user.getName() + "' from password file.");
- return false;
- }
-
- _users.remove(user.getName());
- }
- finally
- {
- _userUpdate.unlock();
- }
-
- return true;
+ return new PlainUser(result);
}
- 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;
- }
-
- 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 The principal name to lookup
- *
- * @return a char[] for use in SASL.
- */
- private char[] lookupPassword(String name)
- {
- PlainUser user = _users.get(name);
- if (user == null)
- {
- return null;
- }
- else
- {
- return user.getPassword();
- }
- }
-
- private void loadPasswordFile() throws IOException
- {
- try
- {
- _userUpdate.lock();
- _users.clear();
-
- BufferedReader reader = null;
- try
- {
- reader = new BufferedReader(new FileReader(_passwordFile));
- String line;
-
- while ((line = reader.readLine()) != null)
- {
- String[] result = _regexp.split(line);
- if (result == null || result.length < 2 || result[0].startsWith("#"))
- {
- continue;
- }
-
- PlainUser user = new PlainUser(result);
- _logger.info("Created user:" + user);
- _users.put(user.getName(), user);
- }
- }
- finally
- {
- if (reader != null)
- {
- reader.close();
- }
- }
- }
- finally
- {
- _userUpdate.unlock();
- }
- }
-
- private void savePasswordFile() throws IOException
- {
- try
- {
- _userUpdate.lock();
-
- BufferedReader reader = null;
- PrintStream writer = null;
-
- final File tmp = createTempFileOnSameFilesystem(_passwordFile);
-
- try
- {
- writer = new PrintStream(tmp);
- reader = new BufferedReader(new FileReader(_passwordFile));
- String line;
-
- while ((line = reader.readLine()) != null)
- {
- String[] result = _regexp.split(line);
- if (result == null || result.length < 2 || result[0].startsWith("#"))
- {
- writer.write(line.getBytes(DEFAULT_ENCODING));
- writer.println();
- continue;
- }
-
- PlainUser user = _users.get(result[0]);
-
- 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
- {
- byte[] password = user.getPasswordBytes();
-
- writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING));
- writer.write(password);
- writer.println();
-
- user.saved();
- }
- }
- }
-
- for (PlainUser user : _users.values())
- {
- if (user.isModified())
- {
- byte[] password;
- password = user.getPasswordBytes();
- writer.write((user.getName() + ":").getBytes(DEFAULT_ENCODING));
- writer.write(password);
- writer.println();
- user.saved();
- }
- }
- }
- catch(IOException e)
- {
- _logger.error("Unable to create the new password file: " + e);
- throw new IOException("Unable to create the new password file" + e);
- }
- finally
- {
- if (writer != null)
- {
- writer.close();
- }
- if (reader != null)
- {
- reader.close();
- }
- }
-
- swapTempFileToLive(_passwordFile, tmp);
-
- }
- finally
- {
- _userUpdate.unlock();
- }
- }
-
- private void swapTempFileToLive(final File live, final File temp) throws IOException
- {
- // Remove any existing ".old" file
- final File old = new File(live.getAbsoluteFile() + ".old");
- if (old.exists())
- {
- old.delete();
- }
-
- // Create an new ".old" file
- if(!live.renameTo(old))
- {
- //unable to rename the existing file to the backup name
- _logger.error("Could not backup the existing password file");
- throw new IOException("Could not backup the existing password file");
- }
-
- // Move temp file to be the new "live" file
- if(!temp.renameTo(live))
- {
- //failed to rename the new file to the required filename
- if(!old.renameTo(live))
- {
- //unable to return the backup to required filename
- _logger.error("Could not rename the new password file into place, and unable to restore original file");
- throw new IOException("Could not rename the new password file into place, and unable to restore original file");
- }
-
- _logger.error("Could not rename the new password file into place");
- throw new IOException("Could not rename the new password file into place");
- }
- }
-
- private File createTempFileOnSameFilesystem(final File liveFile)
- {
- File tmp;
- final Random r = new Random();
-
- do
- {
- tmp = new File(liveFile.getPath() + r.nextInt() + ".tmp");
- }
- while(tmp.exists());
-
- tmp.deleteOnExit();
- return tmp;
- }
-
- public void reload() throws IOException
+ protected Logger getLogger()
{
- loadPasswordFile();
+ return _logger;
}
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java
index 46a78a55aa..bf9bfc6c99 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PlainUser.java
@@ -20,11 +20,7 @@
*/
package org.apache.qpid.server.security.auth.database;
-import org.apache.log4j.Logger;
-
-import java.security.Principal;
-
-public class PlainUser implements Principal
+public class PlainUser implements PasswordPrincipal
{
private String _name;
private char[] _password;
@@ -61,12 +57,12 @@ public class PlainUser implements Principal
return _name;
}
- char[] getPassword()
+ public char[] getPassword()
{
return _password;
}
- byte[] getPasswordBytes()
+ public byte[] getEncodedPassword()
{
byte[] byteArray = new byte[_password.length];
int index = 0;
@@ -77,7 +73,14 @@ public class PlainUser implements Principal
return byteArray;
}
- void setPassword(char[] password)
+
+
+ public void restorePassword(char[] password)
+ {
+ setPassword(password);
+ }
+
+ public void setPassword(char[] password)
{
_password = password;
_modified = true;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
index ef37e043a6..67f4b7344a 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java
@@ -22,14 +22,12 @@ package org.apache.qpid.server.security.auth.database;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import javax.security.auth.callback.PasswordCallback;
+import javax.security.auth.login.AccountNotFoundException;
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;
+import java.util.Map;
/** Represents a "user database" which is really a way of storing principals (i.e. usernames) and passwords. */
public interface PrincipalDatabase
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
index ff8851306f..4203cb0e07 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/database/PropertiesPrincipalDatabase.java
@@ -27,14 +27,14 @@ import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
-import java.util.Properties;
-import java.util.Map;
-import java.util.HashMap;
-import java.util.List;
-import java.util.LinkedList;
-import java.security.Principal;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
+import java.security.Principal;
+import java.util.HashMap;
+import java.util.LinkedList;
+import java.util.List;
+import java.util.Map;
+import java.util.Properties;
public class PropertiesPrincipalDatabase implements PrincipalDatabase
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
index 208130379e..1314a5d6a6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/management/AMQUserManagementMBean.java
@@ -20,9 +20,14 @@
*/
package org.apache.qpid.server.security.auth.management;
-import java.io.IOException;
-import java.security.Principal;
-import java.util.List;
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.management.common.mbeans.UserManagement;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
+import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
+import org.apache.qpid.server.management.AMQManagedObject;
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
import javax.management.JMException;
import javax.management.openmbean.CompositeData;
@@ -35,14 +40,9 @@ import javax.management.openmbean.TabularData;
import javax.management.openmbean.TabularDataSupport;
import javax.management.openmbean.TabularType;
import javax.security.auth.login.AccountNotFoundException;
-
-import org.apache.log4j.Logger;
-import org.apache.qpid.management.common.mbeans.UserManagement;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanDescription;
-import org.apache.qpid.management.common.mbeans.annotations.MBeanOperation;
-import org.apache.qpid.server.management.AMQManagedObject;
-import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.List;
/** MBean class for AMQUserManagementMBean. It implements all the management features exposed for managing users. */
@MBeanDescription("User Management Interface")
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
index 82eb7d3621..03cc12d06c 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java
@@ -20,21 +20,20 @@
*/
package org.apache.qpid.server.security.auth.manager;
-import javax.security.auth.Subject;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
import org.apache.qpid.amqp_1_0.transport.CallbackHanderSource;
import org.apache.qpid.common.Closeable;
import org.apache.qpid.server.plugins.Plugin;
import org.apache.qpid.server.security.auth.AuthenticationResult;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+
/**
* Implementations of the AuthenticationManager are responsible for determining
* the authenticity of a user's credentials.
*
* If the authentication is successful, the manager is responsible for producing a populated
- * {@link Subject} containing the user's identity and zero or more principals representing
+ * {@link javax.security.auth.Subject} containing the user's identity and zero or more principals representing
* groups to which the user belongs.
* <p>
* The {@link #initialise()} method is responsible for registering SASL mechanisms required by
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
index 978ad2b1f3..b5d70d9200 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java
@@ -20,29 +20,10 @@
*/
package org.apache.qpid.server.security.auth.manager;
-import java.lang.reflect.InvocationTargetException;
-import java.lang.reflect.Method;
-import java.security.Security;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashMap;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Map;
-import java.util.Map.Entry;
-import java.util.TreeMap;
-
-import javax.security.auth.Subject;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.login.AccountNotFoundException;
-import javax.security.sasl.Sasl;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-import javax.security.sasl.SaslServerFactory;
-
import org.apache.commons.configuration.Configuration;
import org.apache.commons.configuration.ConfigurationException;
import org.apache.log4j.Logger;
+
import org.apache.qpid.configuration.PropertyException;
import org.apache.qpid.configuration.PropertyUtils;
import org.apache.qpid.server.configuration.plugins.ConfigurationPlugin;
@@ -55,6 +36,25 @@ import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialis
import org.apache.qpid.server.security.auth.sasl.JCAProvider;
import org.apache.qpid.server.security.auth.sasl.UsernamePrincipal;
+import javax.security.auth.Subject;
+import javax.security.auth.callback.CallbackHandler;
+import javax.security.auth.login.AccountNotFoundException;
+import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
+import javax.security.sasl.SaslServerFactory;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.security.Security;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
+import java.util.Map.Entry;
+import java.util.TreeMap;
+
/**
* Concrete implementation of the AuthenticationManager that determines if supplied
@@ -95,9 +95,9 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
*/
private final Map<String, Map<String, ?>> _serverCreationProperties = new HashMap<String, Map<String, ?>>();
- protected PrincipalDatabase _principalDatabase = null;
+ private PrincipalDatabase _principalDatabase = null;
- protected AMQUserManagementMBean _mbean = null;
+ private AMQUserManagementMBean _mbean = null;
public static final AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager> FACTORY = new AuthenticationManagerPluginFactory<PrincipalDatabaseAuthenticationManager>()
{
@@ -160,13 +160,13 @@ public class PrincipalDatabaseAuthenticationManager implements AuthenticationMan
public String getPrincipalDatabaseClass()
{
- return _configuration.getString("principal-database.class");
+ return getConfig().getString("principal-database.class");
}
public Map<String,String> getPdClassAttributeMap() throws ConfigurationException
{
- final List<String> argumentNames = _configuration.getList("principal-database.attributes.attribute.name");
- final List<String> argumentValues = _configuration.getList("principal-database.attributes.attribute.value");
+ final List<String> argumentNames = getConfig().getList("principal-database.attributes.attribute.name");
+ final List<String> argumentValues = getConfig().getList("principal-database.attributes.attribute.value");
final Map<String,String> attributes = new HashMap<String,String>(argumentNames.size());
for (int i = 0; i < argumentNames.size(); i++)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
index b7985ad972..e27fd99f90 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/rmi/RMIPasswordAuthenticator.java
@@ -20,14 +20,14 @@
*/
package org.apache.qpid.server.security.auth.rmi;
-import javax.management.remote.JMXAuthenticator;
-import javax.management.remote.JMXPrincipal;
-import javax.security.auth.Subject;
-
import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus;
import org.apache.qpid.server.security.auth.manager.AuthenticationManager;
+import javax.management.remote.JMXAuthenticator;
+import javax.management.remote.JMXPrincipal;
+import javax.security.auth.Subject;
+
public class RMIPasswordAuthenticator implements JMXAuthenticator
{
static final String UNABLE_TO_LOOKUP = "The broker was unable to lookup the user details";
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java
index bc5d8a4f2b..c227aa14e8 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/AuthenticationProviderInitialiser.java
@@ -20,10 +20,9 @@
*/
package org.apache.qpid.server.security.auth.sasl;
-import java.util.Map;
-
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.SaslServerFactory;
+import java.util.Map;
public interface AuthenticationProviderInitialiser
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
index d6f6c714e2..8711e1b385 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/JCAProvider.java
@@ -20,11 +20,10 @@
*/
package org.apache.qpid.server.security.auth.sasl;
+import javax.security.sasl.SaslServerFactory;
import java.security.Provider;
import java.util.Map;
-import javax.security.sasl.SaslServerFactory;
-
public class JCAProvider extends Provider
{
public JCAProvider(String name, Map<String, Class<? extends SaslServerFactory>> providerMap)
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
index 5c13e03886..f4e8f800c6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePasswordInitialiser.java
@@ -20,9 +20,10 @@
*/
package org.apache.qpid.server.security.auth.sasl;
-import java.io.IOException;
-import java.security.Principal;
-import java.util.Map;
+import org.apache.commons.configuration.Configuration;
+import org.apache.log4j.Logger;
+
+import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
@@ -31,14 +32,9 @@ import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.auth.login.AccountNotFoundException;
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;
+import java.io.IOException;
+import java.security.Principal;
+import java.util.Map;
public abstract class UsernamePasswordInitialiser implements AuthenticationProviderInitialiser
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
index b4ee13fe6b..9e7db94216 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/UsernamePrincipal.java
@@ -20,11 +20,10 @@
*/
package org.apache.qpid.server.security.auth.sasl;
+import javax.security.auth.Subject;
import java.security.Principal;
import java.util.Set;
-import javax.security.auth.Subject;
-
/** A principal that is just a wrapper for a simple username. */
public class UsernamePrincipal implements Principal
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java
index 7acc6322d1..860307215f 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java
@@ -20,10 +20,10 @@
*/
package org.apache.qpid.server.security.auth.sasl.amqplain;
-import javax.security.sasl.SaslServerFactory;
-
import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
+import javax.security.sasl.SaslServerFactory;
+
public class AmqPlainInitialiser extends UsernamePasswordInitialiser
{
public String getMechanismName()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java
index dee40e7069..eecc704011 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java
@@ -20,9 +20,9 @@
*/
package org.apache.qpid.server.security.auth.sasl.amqplain;
-import java.io.ByteArrayInputStream;
-import java.io.DataInputStream;
-import java.io.IOException;
+import org.apache.qpid.framing.AMQFrameDecodingException;
+import org.apache.qpid.framing.FieldTable;
+import org.apache.qpid.framing.FieldTableFactory;
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
@@ -32,10 +32,9 @@ import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.AuthorizeCallback;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
-
-import org.apache.qpid.framing.AMQFrameDecodingException;
-import org.apache.qpid.framing.FieldTable;
-import org.apache.qpid.framing.FieldTableFactory;
+import java.io.ByteArrayInputStream;
+import java.io.DataInputStream;
+import java.io.IOException;
public class AmqPlainSaslServer implements SaslServer
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java
index 17d123eb0d..3a73f577fe 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java
@@ -20,13 +20,12 @@
*/
package org.apache.qpid.server.security.auth.sasl.amqplain;
-import java.util.Map;
-
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslServerFactory;
+import java.util.Map;
public class AmqPlainSaslServerFactory implements SaslServerFactory
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java
index e35e999766..83369a84c7 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousInitialiser.java
@@ -20,53 +20,17 @@
*/
package org.apache.qpid.server.security.auth.sasl.anonymous;
-import javax.security.auth.callback.Callback;
-import javax.security.auth.callback.CallbackHandler;
-import javax.security.auth.callback.UnsupportedCallbackException;
-import javax.security.sasl.SaslServerFactory;
-
-import org.apache.commons.configuration.Configuration;
-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.UsernamePasswordInitialiser;
-import java.io.IOException;
-import java.util.Map;
+import javax.security.sasl.SaslServerFactory;
-public class AnonymousInitialiser implements AuthenticationProviderInitialiser
+public class AnonymousInitialiser extends UsernamePasswordInitialiser
{
public String getMechanismName()
{
return "ANONYMOUS";
}
- public void initialise(String baseConfigPath, Configuration configuration, Map<String, PrincipalDatabase> principalDatabases) throws Exception
- {
- }
-
- public void initialise(PrincipalDatabase db)
- {
- }
-
- public CallbackHandler getCallbackHandler()
- {
- return new CallbackHandler()
- {
-
- public Callback[] _callbacks;
-
- public void handle(Callback[] callbacks) throws IOException, UnsupportedCallbackException
- {
- _callbacks =callbacks;
- }
- };
- }
-
- public Map<String, ?> getProperties()
- {
- return null;
- }
-
public Class<? extends SaslServerFactory> getServerFactoryClassForJCARegistration()
{
return AnonymousSaslServerFactory.class;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java
index de695032ab..4650234972 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/anonymous/AnonymousSaslServerFactory.java
@@ -20,15 +20,12 @@
*/
package org.apache.qpid.server.security.auth.sasl.anonymous;
-import org.apache.qpid.server.security.auth.sasl.amqplain.AmqPlainSaslServer;
-
-import java.util.Map;
-
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslServerFactory;
+import java.util.Map;
public class AnonymousSaslServerFactory implements SaslServerFactory
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java
index 97f9a4e91a..842215c3eb 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedInitialiser.java
@@ -20,8 +20,8 @@
*/
package org.apache.qpid.server.security.auth.sasl.crammd5;
-import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
import javax.security.sasl.SaslServerFactory;
import java.util.Map;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java
index f6cab084ea..a2d9fa5e3e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedSaslServer.java
@@ -20,11 +20,11 @@
*/
package org.apache.qpid.server.security.auth.sasl.crammd5;
-import javax.security.sasl.SaslServer;
-import javax.security.sasl.SaslException;
+import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslServerFactory;
-import javax.security.auth.callback.CallbackHandler;
import java.util.Enumeration;
import java.util.Map;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java
index 5298b5cc63..4e82940439 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HashedServerFactory.java
@@ -20,13 +20,12 @@
*/
package org.apache.qpid.server.security.auth.sasl.crammd5;
-import java.util.Map;
-
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslServerFactory;
+import java.util.Map;
public class CRAMMD5HashedServerFactory implements SaslServerFactory
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
index 139818735f..478f195530 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java
@@ -21,16 +21,16 @@
package org.apache.qpid.server.security.auth.sasl.crammd5;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
-import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser;
+import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
-import javax.security.sasl.SaslServerFactory;
import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.login.AccountNotFoundException;
-import java.util.Map;
-import java.util.List;
-import java.security.Principal;
+import javax.security.sasl.SaslServerFactory;
import java.io.IOException;
+import java.security.Principal;
+import java.util.List;
+import java.util.Map;
public class CRAMMD5HexInitialiser extends UsernamePasswordInitialiser
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java
index 192ff74bff..e19baaa7c6 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexSaslServer.java
@@ -20,11 +20,11 @@
*/
package org.apache.qpid.server.security.auth.sasl.crammd5;
-import javax.security.sasl.SaslServer;
-import javax.security.sasl.SaslException;
+import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.Sasl;
+import javax.security.sasl.SaslException;
+import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslServerFactory;
-import javax.security.auth.callback.CallbackHandler;
import java.util.Enumeration;
import java.util.Map;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java
index ce0e19abf9..06c9108a73 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexServerFactory.java
@@ -20,13 +20,12 @@
*/
package org.apache.qpid.server.security.auth.sasl.crammd5;
-import java.util.Map;
-
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslServerFactory;
+import java.util.Map;
public class CRAMMD5HexServerFactory implements SaslServerFactory
{
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java
index 264832888d..83e33d5491 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5Initialiser.java
@@ -20,8 +20,8 @@
*/
package org.apache.qpid.server.security.auth.sasl.crammd5;
-import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
import org.apache.qpid.server.security.auth.database.PrincipalDatabase;
+import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
import javax.security.sasl.SaslServerFactory;
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainInitialiser.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainInitialiser.java
index 1d16cd8755..67676d363e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainInitialiser.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainInitialiser.java
@@ -20,10 +20,10 @@
*/
package org.apache.qpid.server.security.auth.sasl.plain;
-import javax.security.sasl.SaslServerFactory;
-
import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser;
+import javax.security.sasl.SaslServerFactory;
+
public class PlainInitialiser extends UsernamePasswordInitialiser
{
public String getMechanismName()
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainPasswordCallback.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainPasswordCallback.java
index 7230e8ee53..0ea2f3c92e 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainPasswordCallback.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainPasswordCallback.java
@@ -20,9 +20,8 @@
*/
package org.apache.qpid.server.security.auth.sasl.plain;
-import java.util.Arrays;
-
import javax.security.auth.callback.PasswordCallback;
+import java.util.Arrays;
/**
* Custom PasswordCallback for use during the PLAIN authentication process.
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServer.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServer.java
index 847a3a34ce..a811806c00 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServer.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServer.java
@@ -20,16 +20,14 @@
*/
package org.apache.qpid.server.security.auth.sasl.plain;
-import java.io.IOException;
-
import javax.security.auth.callback.Callback;
import javax.security.auth.callback.CallbackHandler;
import javax.security.auth.callback.NameCallback;
-import javax.security.auth.callback.PasswordCallback;
import javax.security.auth.callback.UnsupportedCallbackException;
import javax.security.sasl.AuthorizeCallback;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
+import java.io.IOException;
public class PlainSaslServer implements SaslServer
{
@@ -53,57 +51,65 @@ public class PlainSaslServer implements SaslServer
public byte[] evaluateResponse(byte[] response) throws SaslException
{
- try
+ int authzidNullPosition = findNullPosition(response, 0);
+ if (authzidNullPosition < 0)
{
- int authzidNullPosition = findNullPosition(response, 0);
- if (authzidNullPosition < 0)
- {
- throw new SaslException("Invalid PLAIN encoding, authzid null terminator not found");
- }
- int authcidNullPosition = findNullPosition(response, authzidNullPosition + 1);
- if (authcidNullPosition < 0)
- {
- throw new SaslException("Invalid PLAIN encoding, authcid null terminator not found");
- }
+ throw new SaslException("Invalid PLAIN encoding, authzid null terminator not found");
+ }
+ int authcidNullPosition = findNullPosition(response, authzidNullPosition + 1);
+ if (authcidNullPosition < 0)
+ {
+ throw new SaslException("Invalid PLAIN encoding, authcid null terminator not found");
+ }
+
+ PlainPasswordCallback passwordCb;
+ AuthorizeCallback authzCb;
+ try
+ {
// we do not currently support authcid in any meaningful way
- // String authcid = new String(response, 0, authzidNullPosition, "utf8");
String authzid = new String(response, authzidNullPosition + 1, authcidNullPosition - authzidNullPosition - 1, "utf8");
// TODO: should not get pwd as a String but as a char array...
int passwordLen = response.length - authcidNullPosition - 1;
String pwd = new String(response, authcidNullPosition + 1, passwordLen, "utf8");
-
+
// we do not care about the prompt but it throws if null
NameCallback nameCb = new NameCallback("prompt", authzid);
- PlainPasswordCallback passwordCb = new PlainPasswordCallback("prompt", false, pwd);
- AuthorizeCallback authzCb = new AuthorizeCallback(authzid, authzid);
+ passwordCb = new PlainPasswordCallback("prompt", false, pwd);
+ authzCb = new AuthorizeCallback(authzid, authzid);
Callback[] callbacks = new Callback[]{nameCb, passwordCb, authzCb};
_cbh.handle(callbacks);
- if (passwordCb.isAuthenticated())
- {
- _complete = true;
- }
- if (authzCb.isAuthorized() && _complete)
- {
- _authorizationId = authzCb.getAuthenticationID();
- return null;
- }
- else
- {
- throw new SaslException("Authentication failed");
- }
}
catch (IOException e)
{
+ if(e instanceof SaslException)
+ {
+ throw (SaslException) e;
+ }
throw new SaslException("Error processing data: " + e, e);
}
catch (UnsupportedCallbackException e)
{
throw new SaslException("Unable to obtain data from callback handler: " + e, e);
}
+
+ if (passwordCb.isAuthenticated())
+ {
+ _complete = true;
+ }
+
+ if (authzCb.isAuthorized() && _complete)
+ {
+ _authorizationId = authzCb.getAuthenticationID();
+ return null;
+ }
+ else
+ {
+ throw new SaslException("Authentication failed");
+ }
}
diff --git a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
index 3144bfbce6..445e5ef812 100644
--- a/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
+++ b/qpid/java/broker/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainSaslServerFactory.java
@@ -20,13 +20,12 @@
*/
package org.apache.qpid.server.security.auth.sasl.plain;
-import java.util.Map;
-
import javax.security.auth.callback.CallbackHandler;
import javax.security.sasl.Sasl;
import javax.security.sasl.SaslException;
import javax.security.sasl.SaslServer;
import javax.security.sasl.SaslServerFactory;
+import java.util.Map;
public class PlainSaslServerFactory implements SaslServerFactory
{