diff options
author | Robert Godfrey <rgodfrey@apache.org> | 2014-07-24 11:27:03 +0000 |
---|---|---|
committer | Robert Godfrey <rgodfrey@apache.org> | 2014-07-24 11:27:03 +0000 |
commit | 9b3ec0dcc943c0f1837cfc50e8c3613552af3aca (patch) | |
tree | f57c9042840e8986cfa14c4231fecf6f73548f90 | |
parent | d15fe159dfee37f209b66aa896e4b901e901b241 (diff) | |
download | qpid-python-9b3ec0dcc943c0f1837cfc50e8c3613552af3aca.tar.gz |
QPID-5922 : [Java Broker] restrict the use of PLAIN authentication to secure channels
git-svn-id: https://svn.apache.org/repos/asf/qpid/trunk/qpid@1613068 13f79535-47bb-0310-9956-ffa450edef68
49 files changed, 506 insertions, 616 deletions
diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java index 71f951a1e1..021431b756 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/AuthenticationProvider.java @@ -22,6 +22,7 @@ package org.apache.qpid.server.model; import java.security.Principal; import java.util.Collection; +import java.util.List; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; @@ -39,8 +40,9 @@ public interface AuthenticationProvider<X extends AuthenticationProvider<X>> ext * A temporary method to create SubjectCreator. * * TODO: move all the functionality from SubjectCreator into AuthenticationProvider + * @param secure */ - SubjectCreator getSubjectCreator(); + SubjectCreator getSubjectCreator(final boolean secure); /** * Returns the preferences provider associated with this authentication provider @@ -61,8 +63,12 @@ public interface AuthenticationProvider<X extends AuthenticationProvider<X>> ext * * @return SASL mechanism names, space separated. */ - String getMechanisms(); + @DerivedAttribute + List<String> getMechanisms(); + + @ManagedAttribute( defaultValue = "[ \"PLAIN\" ]") + List<String> getSecureOnlyMechanisms(); /** * Creates a SASL server for the specified mechanism name for the given * fully qualified domain name. diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java index 53c1e7f7f4..8c8c5d4b9d 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/Broker.java @@ -170,8 +170,9 @@ public interface Broker<X extends Broker<X>> extends ConfiguredObject<X>, EventL * TODO: move the authentication related functionality into host aliases and AuthenticationProviders * * @param localAddress The (listening) socket address for which the AuthenticationManager is required + * @param secure */ - SubjectCreator getSubjectCreator(SocketAddress localAddress); + SubjectCreator getSubjectCreator(SocketAddress localAddress, final boolean secure); Collection<KeyStore<?>> getKeyStores(); diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/ExternalFileBasedAuthenticationManager.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/ExternalFileBasedAuthenticationManager.java index 055890e73c..45294a82fa 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/ExternalFileBasedAuthenticationManager.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/ExternalFileBasedAuthenticationManager.java @@ -26,4 +26,6 @@ public interface ExternalFileBasedAuthenticationManager<X extends ExternalFileBa @ManagedAttribute( mandatory = true, description = "File location") public String getPath(); + + } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/Transport.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/Transport.java index 7338e5046a..6ea74c2963 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/Transport.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/Transport.java @@ -24,12 +24,30 @@ import java.util.EnumSet; public enum Transport { + TCP, - SSL, + SSL(true), WS, - WSS, + WSS(true), SCTP; + Transport() + { + this(false); + } + + Transport(boolean secure) + { + _secure = secure; + } + + private boolean _secure; + + public final boolean isSecure() + { + return _secure; + } + public static Transport valueOfObject(Object transportObject) { Transport transport; diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java b/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java index 2aba33104a..651a6a909b 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/model/adapter/BrokerAdapter.java @@ -848,7 +848,7 @@ public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> imple } @Override - public SubjectCreator getSubjectCreator(SocketAddress localAddress) + public SubjectCreator getSubjectCreator(SocketAddress localAddress, final boolean secure) { AuthenticationProvider provider = getAuthenticationProvider(localAddress); @@ -857,7 +857,7 @@ public class BrokerAdapter extends AbstractConfiguredObject<BrokerAdapter> imple throw new IllegalConfigurationException("Unable to determine authentication provider for address: " + localAddress); } - return provider.getSubjectCreator(); + return provider.getSubjectCreator(secure); } @Override diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java index 066c05b898..ac8d002577 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/SubjectCreator.java @@ -21,45 +21,47 @@ package org.apache.qpid.server.security; import java.security.Principal; +import java.util.ArrayList; import java.util.Collection; import java.util.Collections; import java.util.HashSet; +import java.util.List; import java.util.Set; import javax.security.auth.Subject; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; +import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.GroupProvider; -import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; import org.apache.qpid.server.security.auth.AuthenticationResult; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; -import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; -import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager; /** * Creates a {@link Subject} formed by the {@link Principal}'s returned from: * <ol> - * <li>Authenticating using an {@link AuthenticationManager}</li> - * <li>A {@link GroupPrincipalAccessor}</li> + * <li>Authenticating using an {@link AuthenticationProvider}</li> * </ol> * * <p> - * SubjectCreator is a facade to the {@link AuthenticationManager}, and is intended to be + * SubjectCreator is a facade to the {@link AuthenticationProvider}, and is intended to be * the single place that {@link Subject}'s are created in the broker. * </p> */ public class SubjectCreator { - private AuthenticationManager _authenticationManager; + private final boolean _secure; + private AuthenticationProvider<?> _authenticationProvider; private Collection<GroupProvider> _groupProviders; - public SubjectCreator(AuthenticationManager authenticationManager, Collection<GroupProvider> groupProviders) + public SubjectCreator(AuthenticationProvider<?> authenticationProvider, + Collection<GroupProvider> groupProviders, + final boolean secure) { - _authenticationManager = authenticationManager; + _authenticationProvider = authenticationProvider; _groupProviders = groupProviders; + _secure = secure; } /** @@ -67,17 +69,27 @@ public class SubjectCreator * * @return SASL mechanism names, space separated. */ - public String getMechanisms() + public List<String> getMechanisms() { - return _authenticationManager.getMechanisms(); + List<String> mechanisms = _authenticationProvider.getMechanisms(); + if(!_secure) + { + mechanisms = new ArrayList<>(mechanisms); + mechanisms.removeAll(_authenticationProvider.getSecureOnlyMechanisms()); + } + return mechanisms; } /** - * @see AuthenticationManager#createSaslServer(String, String, Principal) + * @see AuthenticationProvider#createSaslServer(String, String, Principal) */ public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException { - return _authenticationManager.createSaslServer(mechanism, localFQDN, externalPrincipal); + if(!getMechanisms().contains(mechanism)) + { + throw new SaslException("Unsupported mechanism: " + mechanism + ".\nSupported mechanisms: " + getMechanisms()); + } + return _authenticationProvider.createSaslServer(mechanism, localFQDN, externalPrincipal); } /** @@ -88,7 +100,7 @@ public class SubjectCreator */ public SubjectAuthenticationResult authenticate(SaslServer server, byte[] response) { - AuthenticationResult authenticationResult = _authenticationManager.authenticate(server, response); + AuthenticationResult authenticationResult = _authenticationProvider.authenticate(server, response); if(server.isComplete()) { String username = server.getAuthorizationID(); @@ -106,7 +118,7 @@ public class SubjectCreator */ public SubjectAuthenticationResult authenticate(String username, String password) { - final AuthenticationResult authenticationResult = _authenticationManager.authenticate(username, password); + final AuthenticationResult authenticationResult = _authenticationProvider.authenticate(username, password); return createResultWithGroups(username, authenticationResult); } @@ -141,18 +153,7 @@ public class SubjectCreator return authenticationSubject; } - public Subject createSubjectWithGroups(String username) - { - Subject authenticationSubject = new Subject(); - - authenticationSubject.getPrincipals().add(new AuthenticatedPrincipal(username)); - authenticationSubject.getPrincipals().addAll(getGroupPrincipals(username)); - authenticationSubject.setReadOnly(); - - return authenticationSubject; - } - - public Set<Principal> getGroupPrincipals(String username) + Set<Principal> getGroupPrincipals(String username) { Set<Principal> principals = new HashSet<Principal>(); for (GroupProvider groupProvider : _groupProviders) @@ -167,13 +168,4 @@ public class SubjectCreator return Collections.unmodifiableSet(principals); } - public boolean isAnonymousAuthenticationAllowed() - { - return _authenticationManager instanceof AnonymousAuthenticationManager; - } - - public boolean isExternalAuthenticationAllowed() - { - return _authenticationManager instanceof ExternalAuthenticationManager; - } } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java index 09bf6cf3b1..3f0494cd6d 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/AuthenticationResult.java @@ -25,10 +25,9 @@ import java.util.Collections; import java.util.HashSet; import java.util.Set; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; /** - * Encapsulates the result of an attempt to authenticate using an {@link AuthenticationManager}. + * Encapsulates the result of an attempt to authenticate using an {@link org.apache.qpid.server.model.AuthenticationProvider}. * <p> * The authentication status describes the overall outcome. * <p> diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java index a11f11e3fb..2acf8af987 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/Base64MD5PasswordFilePrincipalDatabase.java @@ -21,7 +21,10 @@ package org.apache.qpid.server.security.auth.database; import java.security.Principal; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.security.auth.callback.CallbackHandler; @@ -30,10 +33,13 @@ import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.apache.log4j.Logger; + import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedInitialiser; import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HashedSaslServer; import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexInitialiser; import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexSaslServer; +import org.apache.qpid.server.security.auth.sasl.plain.PlainAdapterSaslServer; +import org.apache.qpid.server.security.auth.sasl.plain.PlainSaslServer; /** * Represents a user database where the account information is stored in a simple flat file. @@ -45,7 +51,9 @@ import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5HexSaslServer; public class Base64MD5PasswordFilePrincipalDatabase extends AbstractPasswordFilePrincipalDatabase<HashedUser> { private final Logger _logger = Logger.getLogger(Base64MD5PasswordFilePrincipalDatabase.class); - private String _mechanismsString; + private List<String> _mechanisms = Collections.unmodifiableList(Arrays.asList(CRAMMD5HashedSaslServer.MECHANISM, + CRAMMD5HexSaslServer.MECHANISM, + PlainSaslServer.MECHANISM)); private final Map<String, CallbackHandler> _callbackHandlerMap = new HashMap<String, CallbackHandler>(); public Base64MD5PasswordFilePrincipalDatabase() @@ -58,7 +66,6 @@ public class Base64MD5PasswordFilePrincipalDatabase extends AbstractPasswordFile crammd5HexInitialiser.initialise(this); _callbackHandlerMap.put(CRAMMD5HexSaslServer.MECHANISM, crammd5HexInitialiser.getCallbackHandler()); - _mechanismsString = CRAMMD5HashedSaslServer.MECHANISM + " " + CRAMMD5HexSaslServer.MECHANISM; } @@ -127,9 +134,9 @@ public class Base64MD5PasswordFilePrincipalDatabase extends AbstractPasswordFile } @Override - public String getMechanisms() + public List<String> getMechanisms() { - return _mechanismsString; + return _mechanisms; } @Override @@ -150,6 +157,24 @@ public class Base64MD5PasswordFilePrincipalDatabase extends AbstractPasswordFile { return new CRAMMD5HexSaslServer(mechanism, "AMQP", localFQDN, null, callbackHandler); } + else if(PlainSaslServer.MECHANISM.equals(mechanism)) + { + return new PlainAdapterSaslServer(new PlainAdapterSaslServer.PasswordValidator() + { + @Override + public boolean validatePassword(final String user, final String password) + { + try + { + return verifyPassword(user, password.toCharArray()); + } + catch (AccountNotFoundException e) + { + return false; + } + } + }); + } throw new SaslException("Unsupported mechanism: " + mechanism); } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java index d983fe6418..0a55f5d510 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PlainPasswordFilePrincipalDatabase.java @@ -21,7 +21,10 @@ package org.apache.qpid.server.security.auth.database; import java.security.Principal; +import java.util.Arrays; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.security.auth.callback.CallbackHandler; @@ -31,8 +34,7 @@ import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; import org.apache.log4j.Logger; -import org.apache.qpid.server.security.auth.sasl.amqplain.AmqPlainInitialiser; -import org.apache.qpid.server.security.auth.sasl.amqplain.AmqPlainSaslServer; + import org.apache.qpid.server.security.auth.sasl.crammd5.CRAMMD5Initialiser; import org.apache.qpid.server.security.auth.sasl.plain.PlainInitialiser; import org.apache.qpid.server.security.auth.sasl.plain.PlainSaslServer; @@ -49,14 +51,11 @@ public class PlainPasswordFilePrincipalDatabase extends AbstractPasswordFilePrin private final Logger _logger = Logger.getLogger(PlainPasswordFilePrincipalDatabase.class); private final Map<String, CallbackHandler> _callbackHandlerMap = new HashMap<String, CallbackHandler>(); - private String _mechanismsString; + private final List<String> _mechanisms = Collections.unmodifiableList(Arrays.asList(PlainSaslServer.MECHANISM, + CRAMMD5Initialiser.MECHANISM)); public PlainPasswordFilePrincipalDatabase() { - AmqPlainInitialiser amqPlainInitialiser = new AmqPlainInitialiser(); - amqPlainInitialiser.initialise(this); - _callbackHandlerMap.put(AmqPlainSaslServer.MECHANISM, amqPlainInitialiser.getCallbackHandler()); - PlainInitialiser plainInitialiser = new PlainInitialiser(); plainInitialiser.initialise(this); _callbackHandlerMap.put(PlainSaslServer.MECHANISM, plainInitialiser.getCallbackHandler()); @@ -65,7 +64,6 @@ public class PlainPasswordFilePrincipalDatabase extends AbstractPasswordFilePrin crammd5Initialiser.initialise(this); _callbackHandlerMap.put(CRAMMD5Initialiser.MECHANISM, crammd5Initialiser.getCallbackHandler()); - _mechanismsString = AmqPlainSaslServer.MECHANISM + " " + PlainSaslServer.MECHANISM + " " + CRAMMD5Initialiser.MECHANISM; } @@ -113,9 +111,9 @@ public class PlainPasswordFilePrincipalDatabase extends AbstractPasswordFilePrin @Override - public String getMechanisms() + public List<String> getMechanisms() { - return _mechanismsString; + return _mechanisms; } @Override @@ -136,10 +134,6 @@ public class PlainPasswordFilePrincipalDatabase extends AbstractPasswordFilePrin { return new PlainSaslServer(callbackHandler); } - else if(AmqPlainSaslServer.MECHANISM.equals(mechanism)) - { - return new AmqPlainSaslServer(callbackHandler); - } throw new SaslException("Unsupported mechanism: " + mechanism); } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java index 7e3e28e4f8..284190840e 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/database/PrincipalDatabase.java @@ -20,19 +20,16 @@ */ package org.apache.qpid.server.security.auth.database; -import org.apache.qpid.server.security.auth.sasl.AuthenticationProviderInitialiser; +import java.io.File; +import java.io.IOException; +import java.security.Principal; +import java.util.List; import javax.security.auth.callback.PasswordCallback; import javax.security.auth.login.AccountNotFoundException; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; -import java.io.File; -import java.io.IOException; -import java.security.Principal; -import java.util.List; -import java.util.Map; - /** Represents a "user database" which is really a way of storing principals (i.e. usernames) and passwords. */ public interface PrincipalDatabase { @@ -108,7 +105,7 @@ public interface PrincipalDatabase * Get the list of mechanisms supported for use with the PrincipalDatabase * @return space separated list of supported Sasl mechanisms */ - public String getMechanisms(); + public List<String> getMechanisms(); public SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException; } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticator.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticator.java index ae080ff779..5b07ac9932 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticator.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticator.java @@ -25,14 +25,14 @@ import java.rmi.server.RemoteServer; import java.rmi.server.ServerNotActiveException; import java.security.PrivilegedAction; +import javax.management.remote.JMXAuthenticator; +import javax.security.auth.Subject; + import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; -import javax.management.remote.JMXAuthenticator; -import javax.security.auth.Subject; - public class JMXPasswordAuthenticator implements JMXAuthenticator { static final String UNABLE_TO_LOOKUP = "The broker was unable to lookup the user details"; @@ -45,11 +45,13 @@ public class JMXPasswordAuthenticator implements JMXAuthenticator private final Broker _broker; private final SocketAddress _address; + private final boolean _secure; - public JMXPasswordAuthenticator(Broker broker, SocketAddress address) + public JMXPasswordAuthenticator(Broker broker, SocketAddress address, final boolean secure) { _broker = broker; _address = address; + _secure = secure; } public Subject authenticate(Object credentials) throws SecurityException @@ -95,7 +97,7 @@ public class JMXPasswordAuthenticator implements JMXAuthenticator throw new SecurityException(SHOULD_BE_NON_NULL); } - SubjectCreator subjectCreator = _broker.getSubjectCreator(_address); + SubjectCreator subjectCreator = _broker.getSubjectCreator(_address, _secure); if (subjectCreator == null) { throw new SecurityException("Can't get subject creator for " + _address); @@ -149,4 +151,4 @@ public class JMXPasswordAuthenticator implements JMXAuthenticator } -}
\ No newline at end of file +} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java index a2bb5cb91a..6fa93ed51a 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractAuthenticationManager.java @@ -24,6 +24,7 @@ import java.security.AccessControlException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.concurrent.atomic.AtomicReference; @@ -36,6 +37,7 @@ import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.ConfiguredObject; import org.apache.qpid.server.model.IntegrityViolationException; +import org.apache.qpid.server.model.ManagedAttributeField; import org.apache.qpid.server.model.Port; import org.apache.qpid.server.model.PreferencesProvider; import org.apache.qpid.server.model.State; @@ -48,7 +50,7 @@ import org.apache.qpid.server.security.access.Operation; public abstract class AbstractAuthenticationManager<T extends AbstractAuthenticationManager<T>> extends AbstractConfiguredObject<T> - implements AuthenticationProvider<T>, AuthenticationManager + implements AuthenticationProvider<T> { private static final Logger LOGGER = Logger.getLogger(AbstractAuthenticationManager.class); @@ -56,6 +58,9 @@ public abstract class AbstractAuthenticationManager<T extends AbstractAuthentica private PreferencesProvider _preferencesProvider; private AtomicReference<State> _state = new AtomicReference<State>(State.UNINITIALIZED); + @ManagedAttributeField + private List<String> _secureOnlyMechanisms; + protected AbstractAuthenticationManager(final Map<String, Object> attributes, final Broker broker) { super(parentsMap(broker), attributes); @@ -111,9 +116,9 @@ public abstract class AbstractAuthenticationManager<T extends AbstractAuthentica } @Override - public SubjectCreator getSubjectCreator() + public SubjectCreator getSubjectCreator(final boolean secure) { - return new SubjectCreator(this, _broker.getGroupProviders()); + return new SubjectCreator(this, _broker.getGroupProviders(), secure); } @Override @@ -248,4 +253,10 @@ public abstract class AbstractAuthenticationManager<T extends AbstractAuthentica } return super.getAttribute(name); } + + @Override + public final List<String> getSecureOnlyMechanisms() + { + return _secureOnlyMechanisms; + } } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java index 76afad2f12..d95824d94c 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AbstractScramAuthenticationManager.java @@ -29,6 +29,7 @@ import java.security.SecureRandom; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.UUID; import java.util.concurrent.ConcurrentHashMap; @@ -49,6 +50,7 @@ import org.apache.qpid.server.model.User; import org.apache.qpid.server.security.access.Operation; import org.apache.qpid.server.security.auth.AuthenticationResult; import org.apache.qpid.server.security.auth.UsernamePrincipal; +import org.apache.qpid.server.security.auth.sasl.plain.PlainAdapterSaslServer; import org.apache.qpid.server.security.auth.sasl.scram.ScramSaslServer; public abstract class AbstractScramAuthenticationManager<X extends AbstractScramAuthenticationManager<X>> @@ -57,6 +59,7 @@ public abstract class AbstractScramAuthenticationManager<X extends AbstractScram { static final Charset ASCII = Charset.forName("ASCII"); + public static final String PLAIN = "PLAIN"; private final SecureRandom _random = new SecureRandom(); private int _iterationCount = 4096; @@ -70,15 +73,9 @@ public abstract class AbstractScramAuthenticationManager<X extends AbstractScram } @Override - public void initialise() + public List<String> getMechanisms() { - - } - - @Override - public String getMechanisms() - { - return getMechanismName(); + return Collections.unmodifiableList(Arrays.asList(getMechanismName(), PLAIN)); } protected abstract String getMechanismName(); @@ -89,7 +86,18 @@ public abstract class AbstractScramAuthenticationManager<X extends AbstractScram final Principal externalPrincipal) throws SaslException { - return new ScramSaslServer(this, getMechanismName(), getHmacName(), getDigestName()); + if(getMechanismName().equals(mechanism)) + { + return new ScramSaslServer(this, getMechanismName(), getHmacName(), getDigestName()); + } + else if(PLAIN.equals(mechanism)) + { + return new PlainAdapterSaslServer(this); + } + else + { + throw new SaslException("Unknown mechanism: " + mechanism); + } } protected abstract String getDigestName(); diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java index 96e3e7f792..292eae9e41 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManager.java @@ -21,6 +21,8 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; +import java.util.Collections; +import java.util.List; import java.util.Map; import javax.security.auth.Subject; @@ -59,15 +61,9 @@ public class AnonymousAuthenticationManager extends AbstractAuthenticationManage } @Override - public void initialise() + public List<String> getMechanisms() { - - } - - @Override - public String getMechanisms() - { - return ANONYMOUS; + return Collections.singletonList(ANONYMOUS); } @Override diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java deleted file mode 100644 index 3ded20a920..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/AuthenticationManager.java +++ /dev/null @@ -1,87 +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.auth.manager; - -import java.security.Principal; - -import javax.security.sasl.SaslException; -import javax.security.sasl.SaslServer; - -import org.apache.qpid.server.security.auth.AuthenticationResult; - -/** - * Implementations of the AuthenticationManager are responsible for determining - * the authenticity of a user's credentials. - * <p> - * If the authentication is successful, the manager is responsible for producing an - * {@link AuthenticationResult} containing the user's main {@link Principal} and zero or - * more other implementation-specific principals. - * </p> - */ -public interface AuthenticationManager -{ - /** - * Initialise the authentication plugin. - * - */ - void initialise(); - - /** - * Gets the SASL mechanisms known to this manager. - * - * @return SASL mechanism names, space separated. - */ - String getMechanisms(); - - /** - * Creates a SASL server for the specified mechanism name for the given - * fully qualified domain name. - * - * @param mechanism mechanism name - * @param localFQDN domain name - * @param externalPrincipal externally authenticated Principal - * @return SASL server - * @throws SaslException - */ - SaslServer createSaslServer(String mechanism, String localFQDN, Principal externalPrincipal) throws SaslException; - - /** - * Authenticates a user using SASL negotiation. - * - * @param server SASL server - * @param response SASL response to process - * - * @return authentication result - */ - AuthenticationResult authenticate(SaslServer server, byte[] response); - - /** - * Authenticates a user using their username and password. - * - * @param username username - * @param password password - * - * @return authentication result - */ - AuthenticationResult authenticate(String username, String password); - - -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerImpl.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerImpl.java index 8e1f8cf0ec..0b1211402f 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerImpl.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerImpl.java @@ -19,6 +19,8 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; +import java.util.Collections; +import java.util.List; import java.util.Map; import javax.security.sasl.SaslException; @@ -45,13 +47,6 @@ public class ExternalAuthenticationManagerImpl extends AbstractAuthenticationMan super(attributes, broker); } - - @Override - public void initialise() - { - - } - @Override public boolean getUseFullDN() { @@ -59,9 +54,9 @@ public class ExternalAuthenticationManagerImpl extends AbstractAuthenticationMan } @Override - public String getMechanisms() + public List<String> getMechanisms() { - return EXTERNAL; + return Collections.singletonList(EXTERNAL); } @Override diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java index 10d7787356..c6728d6375 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/KerberosAuthenticationManager.java @@ -20,7 +20,9 @@ package org.apache.qpid.server.security.auth.manager; import java.io.IOException; import java.security.Principal; +import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.security.auth.callback.Callback; @@ -50,17 +52,10 @@ public class KerberosAuthenticationManager extends AbstractAuthenticationManager super(attributes, broker); } - - @Override - public void initialise() - { - - } - @Override - public String getMechanisms() + public List<String> getMechanisms() { - return GSSAPI_MECHANISM; + return Collections.singletonList(GSSAPI_MECHANISM); } @Override diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java index bbee5e2210..3197d78c2a 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManager.java @@ -147,7 +147,7 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal } } - public String getMechanisms() + public List<String> getMechanisms() { return _principalDatabase.getMechanisms(); } @@ -158,7 +158,7 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal } /** - * @see org.apache.qpid.server.security.auth.manager.AuthenticationManager#authenticate(SaslServer, byte[]) + * @see org.apache.qpid.server.model.AuthenticationProvider#authenticate(SaslServer, byte[]) */ public AuthenticationResult authenticate(SaslServer server, byte[] response) { @@ -184,7 +184,7 @@ public abstract class PrincipalDatabaseAuthenticationManager<T extends Principal } /** - * @see org.apache.qpid.server.security.auth.manager.AuthenticationManager#authenticate(String, String) + * @see org.apache.qpid.server.model.AuthenticationProvider#authenticate(String, String) */ public AuthenticationResult authenticate(final String username, final String password) { diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java index 5c50af82b0..5b62f7cffd 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManager.java @@ -21,8 +21,10 @@ package org.apache.qpid.server.security.auth.manager; import java.io.IOException; import java.security.Principal; +import java.util.Arrays; import java.util.Collections; import java.util.HashMap; +import java.util.List; import java.util.Map; import javax.security.auth.callback.Callback; @@ -66,14 +68,9 @@ public class SimpleAuthenticationManager extends AbstractAuthenticationManager<S } @Override - public void initialise() + public List<String> getMechanisms() { - } - - @Override - public String getMechanisms() - { - return PLAIN_MECHANISM + " " + CRAM_MD5_MECHANISM; + return Collections.unmodifiableList(Arrays.asList(PLAIN_MECHANISM, CRAM_MD5_MECHANISM)); } @Override diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java index c4109b4682..a0ba4518c8 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/manager/SimpleLDAPAuthenticationManagerImpl.java @@ -24,7 +24,9 @@ import java.security.GeneralSecurityException; import java.security.KeyManagementException; import java.security.NoSuchAlgorithmException; import java.security.Principal; +import java.util.Collections; import java.util.Hashtable; +import java.util.List; import java.util.Map; import javax.naming.AuthenticationException; @@ -111,11 +113,13 @@ public class SimpleLDAPAuthenticationManagerImpl extends AbstractAuthenticationM @Override - public void initialise() + protected void onOpen() { + super.onOpen(); + _sslSocketFactoryOverrideClass = createSslSocketFactoryOverrideClass(); - validateInitialDirContext(); + // validateInitialDirContext(); } @Override @@ -168,9 +172,9 @@ public class SimpleLDAPAuthenticationManagerImpl extends AbstractAuthenticationM @Override - public String getMechanisms() + public List<String> getMechanisms() { - return PlainSaslServer.MECHANISM; + return Collections.singletonList(PlainSaslServer.MECHANISM); } @Override diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java deleted file mode 100644 index 8f8686db88..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainInitialiser.java +++ /dev/null @@ -1,31 +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.auth.sasl.amqplain; - -import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; - -public class AmqPlainInitialiser extends UsernamePasswordInitialiser -{ - public String getMechanismName() - { - return "AMQPLAIN"; - } -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java deleted file mode 100644 index a4c4fff42f..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServer.java +++ /dev/null @@ -1,132 +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.auth.sasl.amqplain; - -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; -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.ByteArrayInputStream; -import java.io.DataInputStream; -import java.io.IOException; - -public class AmqPlainSaslServer implements SaslServer -{ - public static final String MECHANISM = "AMQPLAIN"; - - private CallbackHandler _cbh; - - private String _authorizationId; - - private boolean _complete = false; - - public AmqPlainSaslServer(CallbackHandler cbh) - { - _cbh = cbh; - } - - public String getMechanismName() - { - return MECHANISM; - } - - public byte[] evaluateResponse(byte[] response) throws SaslException - { - try - { - final FieldTable ft = FieldTableFactory.newFieldTable(new DataInputStream(new ByteArrayInputStream(response)), response.length); - String username = ft.getString("LOGIN"); - // we do not care about the prompt but it throws if null - NameCallback nameCb = new NameCallback("prompt", username); - // we do not care about the prompt but it throws if null - PasswordCallback passwordCb = new PasswordCallback("prompt", false); - // TODO: should not get pwd as a String but as a char array... - String pwd = ft.getString("PASSWORD"); - AuthorizeCallback authzCb = new AuthorizeCallback(username, username); - Callback[] callbacks = new Callback[]{nameCb, passwordCb, authzCb}; - _cbh.handle(callbacks); - String storedPwd = new String(passwordCb.getPassword()); - if (storedPwd.equals(pwd)) - { - _complete = true; - } - if (authzCb.isAuthorized() && _complete) - { - _authorizationId = authzCb.getAuthenticationID(); - return null; - } - else - { - throw new SaslException("Authentication failed"); - } - } - catch (AMQFrameDecodingException e) - { - throw new SaslException("Unable to decode response: " + e, e); - } - catch (IOException e) - { - throw new SaslException("Error processing data: " + e, e); - } - catch (UnsupportedCallbackException e) - { - throw new SaslException("Unable to obtain data from callback handler: " + e, e); - } - } - - public boolean isComplete() - { - return _complete; - } - - public String getAuthorizationID() - { - return _authorizationId; - } - - public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException - { - throw new SaslException("Unsupported operation"); - } - - public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException - { - throw new SaslException("Unsupported operation"); - } - - public Object getNegotiatedProperty(String propName) - { - return null; - } - - public void dispose() throws SaslException - { - _cbh = null; - } -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java deleted file mode 100644 index 3a73f577fe..0000000000 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/amqplain/AmqPlainSaslServerFactory.java +++ /dev/null @@ -1,60 +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.auth.sasl.amqplain; - -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 -{ - public SaslServer createSaslServer(String mechanism, String protocol, String serverName, Map props, - CallbackHandler cbh) throws SaslException - { - if (AmqPlainSaslServer.MECHANISM.equals(mechanism)) - { - return new AmqPlainSaslServer(cbh); - } - else - { - return null; - } - } - - public String[] getMechanismNames(Map props) - { - if (props != null && - (props.containsKey(Sasl.POLICY_NOPLAINTEXT) || - props.containsKey(Sasl.POLICY_NODICTIONARY) || - props.containsKey(Sasl.POLICY_NOACTIVE))) - { - // returned array must be non null according to interface documentation - return new String[0]; - } - else - { - return new String[]{AmqPlainSaslServer.MECHANISM}; - } - } -} diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java index 7d41ed44cc..4afce85c99 100644 --- a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/crammd5/CRAMMD5HexInitialiser.java @@ -133,7 +133,7 @@ public class CRAMMD5HexInitialiser extends UsernamePasswordInitialiser } @Override - public String getMechanisms() + public List<String> getMechanisms() { return _realPrincipalDatabase.getMechanisms(); } diff --git a/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainAdapterSaslServer.java b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainAdapterSaslServer.java new file mode 100644 index 0000000000..74363e738e --- /dev/null +++ b/java/broker-core/src/main/java/org/apache/qpid/server/security/auth/sasl/plain/PlainAdapterSaslServer.java @@ -0,0 +1,167 @@ +/* + * + * Licensed to the Apache Software Foundation (ASF) under one + * or more contributor license agreements. See the NOTICE file + * distributed with this work for additional information + * regarding copyright ownership. The ASF licenses this file + * to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance + * with the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, + * software distributed under the License is distributed on an + * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY + * KIND, either express or implied. See the License for the + * specific language governing permissions and limitations + * under the License. + * + */ +package org.apache.qpid.server.security.auth.sasl.plain; + +import java.io.IOException; + +import javax.security.sasl.AuthorizeCallback; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; + +import org.apache.qpid.server.model.AuthenticationProvider; +import org.apache.qpid.server.security.auth.AuthenticationResult; + +public class PlainAdapterSaslServer implements SaslServer +{ + public static interface PasswordValidator + { + boolean validatePassword(String user, String password); + } + + + + public static final String MECHANISM = "PLAIN"; + private final PasswordValidator _passwordValidator; + + private String _authorizationId; + + private boolean _complete = false; + + public PlainAdapterSaslServer(final PasswordValidator passwordValidator) + { + _passwordValidator = passwordValidator; + } + + public PlainAdapterSaslServer(final AuthenticationProvider authProvider) + { + this(new PasswordValidator() + { + @Override + public boolean validatePassword(final String user, final String password) + { + AuthenticationResult authenticationResult = authProvider.authenticate(user, password); + return authenticationResult != null && authenticationResult.getStatus() == AuthenticationResult.AuthenticationStatus.SUCCESS; + } + }); + } + + public String getMechanismName() + { + return MECHANISM; + } + + public byte[] evaluateResponse(byte[] response) throws SaslException + { + 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"); + } + + PlainPasswordCallback passwordCb; + AuthorizeCallback authzCb; + + try + { + // we do not currently support authcid in any meaningful way + 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"); + + + if(_passwordValidator.validatePassword(authzid, pwd)) + { + _authorizationId = authzid; + _complete = true; + } + else + { + throw new SaslException("Authentication failed"); + } + + return null; + + } + catch (IOException e) + { + if(e instanceof SaslException) + { + throw (SaslException) e; + } + throw new SaslException("Error processing data: " + e, e); + } + + + } + + + + private int findNullPosition(byte[] response, int startPosition) + { + int position = startPosition; + while (position < response.length) + { + if (response[position] == (byte) 0) + { + return position; + } + position++; + } + return -1; + } + + public boolean isComplete() + { + return _complete; + } + + public String getAuthorizationID() + { + return _authorizationId; + } + + public byte[] unwrap(byte[] incoming, int offset, int len) throws SaslException + { + throw new SaslException("Unsupported operation"); + } + + public byte[] wrap(byte[] outgoing, int offset, int len) throws SaslException + { + throw new SaslException("Unsupported operation"); + } + + public Object getNegotiatedProperty(String propName) + { + return null; + } + + public void dispose() throws SaslException + { + } + +} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java index 9edd345360..5366e6d8bf 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/SubjectCreatorTest.java @@ -32,19 +32,19 @@ import javax.security.sasl.SaslServer; import junit.framework.TestCase; +import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.GroupProvider; import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; import org.apache.qpid.server.security.auth.AuthenticationResult; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; -import org.apache.qpid.server.security.auth.manager.AuthenticationManager; public class SubjectCreatorTest extends TestCase { private static final String USERNAME = "username"; private static final String PASSWORD = "password"; - private AuthenticationManager _authenticationManager = mock(AuthenticationManager.class); + private AuthenticationProvider _authenticationProvider = mock(AuthenticationProvider.class); private GroupProvider _groupManager1 = mock(GroupProvider.class); private GroupProvider _groupManager2 = mock(GroupProvider.class); @@ -64,9 +64,10 @@ public class SubjectCreatorTest extends TestCase when(_groupManager1.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group1)); when(_groupManager2.getGroupPrincipalsForUser(USERNAME)).thenReturn(Collections.singleton(_group2)); - _subjectCreator = new SubjectCreator(_authenticationManager, new HashSet<GroupProvider>(Arrays.asList(_groupManager1, _groupManager2))); + _subjectCreator = new SubjectCreator(_authenticationProvider, new HashSet<GroupProvider>(Arrays.asList(_groupManager1, _groupManager2)), + false); _authenticationResult = new AuthenticationResult(_userPrincipal); - when(_authenticationManager.authenticate(USERNAME, PASSWORD)).thenReturn(_authenticationResult); + when(_authenticationProvider.authenticate(USERNAME, PASSWORD)).thenReturn(_authenticationResult); } public void testAuthenticateUsernameAndPasswordReturnsSubjectWithUserAndGroupPrincipals() @@ -88,7 +89,7 @@ public class SubjectCreatorTest extends TestCase public void testSaslAuthenticationSuccessReturnsSubjectWithUserAndGroupPrincipals() throws Exception { - when(_authenticationManager.authenticate(_testSaslServer, _saslResponseBytes)).thenReturn(_authenticationResult); + when(_authenticationProvider.authenticate(_testSaslServer, _saslResponseBytes)).thenReturn(_authenticationResult); when(_testSaslServer.isComplete()).thenReturn(true); when(_testSaslServer.getAuthorizationID()).thenReturn(USERNAME); @@ -114,7 +115,7 @@ public class SubjectCreatorTest extends TestCase { AuthenticationResult failedAuthenticationResult = new AuthenticationResult(expectedStatus); - when(_authenticationManager.authenticate(USERNAME, PASSWORD)).thenReturn(failedAuthenticationResult); + when(_authenticationProvider.authenticate(USERNAME, PASSWORD)).thenReturn(failedAuthenticationResult); SubjectAuthenticationResult subjectAuthenticationResult = _subjectCreator.authenticate(USERNAME, PASSWORD); @@ -132,7 +133,8 @@ public class SubjectCreatorTest extends TestCase { AuthenticationResult failedAuthenticationResult = new AuthenticationResult(expectedStatus); - when(_authenticationManager.authenticate(_testSaslServer, _saslResponseBytes)).thenReturn(failedAuthenticationResult); + when(_authenticationProvider.authenticate(_testSaslServer, _saslResponseBytes)).thenReturn( + failedAuthenticationResult); when(_testSaslServer.isComplete()).thenReturn(false); SubjectAuthenticationResult subjectAuthenticationResult = _subjectCreator.authenticate(_testSaslServer, _saslResponseBytes); diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticatorTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticatorTest.java index 99fa07e5b9..bb02070748 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticatorTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/jmx/JMXPasswordAuthenticatorTest.java @@ -20,6 +20,7 @@ */ package org.apache.qpid.server.security.auth.jmx; +import static org.mockito.Matchers.anyBoolean; import static org.mockito.Matchers.anyString; import static org.mockito.Matchers.any; import static org.mockito.Mockito.doThrow; @@ -66,7 +67,7 @@ public class JMXPasswordAuthenticatorTest extends TestCase protected void setUp() throws Exception { when(_broker.getSecurityManager()).thenReturn(_securityManager); - _rmipa = new JMXPasswordAuthenticator(_broker, new InetSocketAddress(8999)); + _rmipa = new JMXPasswordAuthenticator(_broker, new InetSocketAddress(8999), false); } /** @@ -74,7 +75,7 @@ public class JMXPasswordAuthenticatorTest extends TestCase */ public void testAuthenticationSuccess() { - when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(_usernamePasswordOkaySubjectCreator); + when(_broker.getSubjectCreator(any(SocketAddress.class), anyBoolean())).thenReturn(_usernamePasswordOkaySubjectCreator); Subject newSubject = _rmipa.authenticate(_credentials); assertSame("Subject must be unchanged", _loginSubject, newSubject); @@ -85,7 +86,7 @@ public class JMXPasswordAuthenticatorTest extends TestCase */ public void testUsernameOrPasswordInvalid() { - when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(_badPasswordSubjectCreator); + when(_broker.getSubjectCreator(any(SocketAddress.class), anyBoolean())).thenReturn(_badPasswordSubjectCreator); try { @@ -101,7 +102,7 @@ public class JMXPasswordAuthenticatorTest extends TestCase public void testAuthorisationFailure() { - when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(_usernamePasswordOkaySubjectCreator); + when(_broker.getSubjectCreator(any(SocketAddress.class), anyBoolean())).thenReturn(_usernamePasswordOkaySubjectCreator); doThrow(new AccessControlException(USER_NOT_AUTHORISED_FOR_MANAGEMENT)).when(_securityManager).accessManagement(); try @@ -120,7 +121,7 @@ public class JMXPasswordAuthenticatorTest extends TestCase { final Exception mockAuthException = new Exception("Mock Auth system failure"); SubjectCreator subjectCreator = createMockSubjectCreator(false, mockAuthException); - when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(subjectCreator); + when(_broker.getSubjectCreator(any(SocketAddress.class), anyBoolean())).thenReturn(subjectCreator); try { @@ -138,7 +139,7 @@ public class JMXPasswordAuthenticatorTest extends TestCase */ public void testNullSubjectCreator() throws Exception { - when(_broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(null); + when(_broker.getSubjectCreator(any(SocketAddress.class), anyBoolean())).thenReturn(null); try { diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java index 9a6c641314..26c06788fa 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/AnonymousAuthenticationManagerTest.java @@ -22,6 +22,7 @@ package org.apache.qpid.server.security.auth.manager; import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -36,7 +37,7 @@ import org.apache.qpid.test.utils.QpidTestCase; public class AnonymousAuthenticationManagerTest extends QpidTestCase { - private AuthenticationManager _manager; + private AuthenticationProvider _manager; @Override public void setUp() throws Exception @@ -59,7 +60,7 @@ public class AnonymousAuthenticationManagerTest extends QpidTestCase public void testGetMechanisms() throws Exception { - assertEquals("ANONYMOUS", _manager.getMechanisms()); + assertEquals(Collections.singletonList("ANONYMOUS"), _manager.getMechanisms()); } public void testCreateSaslServer() throws Exception diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java index f10d001da9..91bbec7766 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ExternalAuthenticationManagerTest.java @@ -20,6 +20,7 @@ package org.apache.qpid.server.security.auth.manager; import static org.apache.qpid.server.security.auth.AuthenticatedPrincipalTestHelper.assertOnlyContainsWrapped; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -60,7 +61,7 @@ public class ExternalAuthenticationManagerTest extends QpidTestCase public void testGetMechanisms() throws Exception { - assertEquals("EXTERNAL", _manager.getMechanisms()); + assertEquals(Collections.singletonList("EXTERNAL"), _manager.getMechanisms()); } public void testCreateSaslServer() throws Exception diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java index 90a3785a3b..703a8d43c9 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/PrincipalDatabaseAuthenticationManagerTest.java @@ -28,6 +28,7 @@ import java.io.File; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.security.Principal; +import java.util.Collections; import java.util.HashMap; import java.util.List; import java.util.Map; @@ -91,7 +92,7 @@ public class PrincipalDatabaseAuthenticationManagerTest extends QpidTestCase { _principalDatabase = mock(PrincipalDatabase.class); - when(_principalDatabase.getMechanisms()).thenReturn(MOCK_MECH_NAME); + when(_principalDatabase.getMechanisms()).thenReturn(Collections.singletonList(MOCK_MECH_NAME)); when(_principalDatabase.createSaslServer(MOCK_MECH_NAME, LOCALHOST, null)).thenReturn(new MySaslServer(false, true)); setupManager(false); diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManagerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManagerTest.java index 481c52c501..455b5b5ec2 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManagerTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/ScramSHA1AuthenticationManagerTest.java @@ -29,6 +29,8 @@ import java.util.Map; import java.util.UUID; import javax.security.auth.login.AccountNotFoundException; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; import org.apache.qpid.server.configuration.updater.CurrentThreadTaskExecutor; import org.apache.qpid.server.configuration.updater.TaskExecutor; @@ -36,6 +38,7 @@ import org.apache.qpid.server.model.AuthenticationProvider; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.model.User; import org.apache.qpid.server.security.SecurityManager; +import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticationResult; import org.apache.qpid.server.util.BrokerTestHelper; import org.apache.qpid.test.utils.QpidTestCase; @@ -61,6 +64,7 @@ public class ScramSHA1AuthenticationManagerTest extends QpidTestCase attributesMap.put(AuthenticationProvider.NAME, getTestName()); attributesMap.put(AuthenticationProvider.ID, UUID.randomUUID()); _authManager = new ScramSHA1AuthenticationManager(attributesMap, _broker); + _authManager.open(); } @Override @@ -70,6 +74,35 @@ public class ScramSHA1AuthenticationManagerTest extends QpidTestCase super.tearDown(); } + public void testMechanisms() + { + SubjectCreator insecureCreator = _authManager.getSubjectCreator(false); + assertFalse("PLAIN authentication should not be available on an insecure connection", insecureCreator.getMechanisms().contains("PLAIN")); + SubjectCreator secureCreator = _authManager.getSubjectCreator(true); + assertTrue("PLAIN authentication should be available on a secure connection", secureCreator.getMechanisms().contains("PLAIN")); + + try + { + SaslServer saslServer = secureCreator.createSaslServer("PLAIN", "127.0.0.1", null); + assertNotNull(saslServer); + } + catch (SaslException e) + { + fail("Unable to create a SaslServer for PLAIN authentication on a secure connection" + e.getMessage()); + } + + try + { + SaslServer saslServer = insecureCreator.createSaslServer("PLAIN", "127.0.0.1", null); + fail("Erroneously created a SaslServer for PLAIN authentication on an insecure connection"); + } + catch (SaslException e) + { + // Pass + } + + } + public void testAddChildAndThenDelete() { // No children should be present before the test starts diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManagerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManagerTest.java index 85247af755..7f6ed2c487 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManagerTest.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/manager/SimpleAuthenticationManagerTest.java @@ -22,6 +22,7 @@ package org.apache.qpid.server.security.auth.manager; import java.security.Principal; import java.util.HashMap; +import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; @@ -41,7 +42,7 @@ public class SimpleAuthenticationManagerTest extends QpidTestCase { private static final String TEST_USER = "testUser"; private static final String TEST_PASSWORD = "testPassword"; - private AuthenticationManager _authenticationManager; + private AuthenticationProvider _authenticationManager; public void setUp() throws Exception { @@ -58,7 +59,10 @@ public class SimpleAuthenticationManagerTest extends QpidTestCase public void testGetMechanisms() { - assertEquals("Unexpected mechanisms", "PLAIN CRAM-MD5", _authenticationManager.getMechanisms()); + List<String> mechanisms = _authenticationManager.getMechanisms(); + assertEquals("Unexpected number of mechanisms", 2, mechanisms.size()); + assertTrue("PLAIN was not present", mechanisms.contains("PLAIN")); + assertTrue("CRAM-MD5 was not present", mechanisms.contains("CRAM-MD5")); } public void testCreateSaslServerForUnsupportedMechanisms() throws Exception diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java index 17c63d738c..8fc6f4f0fe 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/TestPrincipalDatabase.java @@ -90,7 +90,7 @@ public class TestPrincipalDatabase implements PrincipalDatabase } @Override - public String getMechanisms() + public List<String> getMechanisms() { // TODO Auto-generated method stub return null; diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/amqplain/AMQPlainSaslServerTest.java b/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/amqplain/AMQPlainSaslServerTest.java deleted file mode 100644 index 37580e69a2..0000000000 --- a/java/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/amqplain/AMQPlainSaslServerTest.java +++ /dev/null @@ -1,43 +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.auth.sasl.amqplain; - -import org.apache.qpid.framing.FieldTable; -import org.apache.qpid.framing.FieldTableFactory; -import org.apache.qpid.server.security.auth.sasl.SaslServerTestCase; -import org.apache.qpid.server.security.auth.sasl.UsernamePasswordInitialiser; - -public class AMQPlainSaslServerTest extends SaslServerTestCase -{ - protected void setUp() throws Exception - { - UsernamePasswordInitialiser handler = new AmqPlainInitialiser(); - handler.initialise(db); - this.server = new AmqPlainSaslServer(handler.getCallbackHandler()); - FieldTable table = FieldTableFactory.newFieldTable(); - table.setString("LOGIN", username); - table.setString("PASSWORD", password); - correctResponse = table.getDataAsBytes(); - table.setString("PASSWORD", notPassword); - wrongResponse = table.getDataAsBytes(); - } -} diff --git a/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java b/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java index e151391142..4272b89abb 100644 --- a/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java +++ b/java/broker-core/src/test/java/org/apache/qpid/server/util/BrokerTestHelper.java @@ -21,11 +21,13 @@ package org.apache.qpid.server.util; import static org.mockito.Matchers.any; +import static org.mockito.Matchers.anyBoolean; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; import java.net.SocketAddress; import java.security.PrivilegedAction; +import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.UUID; @@ -78,13 +80,13 @@ public class BrokerTestHelper when(systemContext.getCategoryClass()).thenReturn(SystemContext.class); SubjectCreator subjectCreator = mock(SubjectCreator.class); - when(subjectCreator.getMechanisms()).thenReturn(""); + when(subjectCreator.getMechanisms()).thenReturn(Collections.<String>emptyList()); Broker broker = mock(Broker.class); when(broker.getConnection_sessionCountLimit()).thenReturn(1); when(broker.getConnection_closeWhenNoRoute()).thenReturn(false); when(broker.getId()).thenReturn(UUID.randomUUID()); - when(broker.getSubjectCreator(any(SocketAddress.class))).thenReturn(subjectCreator); + when(broker.getSubjectCreator(any(SocketAddress.class), anyBoolean())).thenReturn(subjectCreator); when(broker.getSecurityManager()).thenReturn(new SecurityManager(broker, false)); when(broker.getObjectFactory()).thenReturn(objectFactory); when(broker.getModel()).thenReturn(objectFactory.getModel()); diff --git a/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ProtocolEngineCreator_0_10.java b/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ProtocolEngineCreator_0_10.java index b1d9fbf676..40c94075a1 100644 --- a/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ProtocolEngineCreator_0_10.java +++ b/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ProtocolEngineCreator_0_10.java @@ -77,7 +77,8 @@ public class ProtocolEngineCreator_0_10 implements ProtocolEngineCreator fqdn = ((InetSocketAddress) address).getHostName(); } final ConnectionDelegate connDelegate = new ServerConnectionDelegate(broker, - fqdn, broker.getSubjectCreator(address)); + fqdn, broker.getSubjectCreator(address, transport.isSecure()) + ); ServerConnection conn = new ServerConnection(id,broker); diff --git a/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java b/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java index 793150f9bb..390d7a8c46 100644 --- a/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java +++ b/java/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java @@ -31,7 +31,6 @@ import java.util.HashMap; import java.util.Iterator; import java.util.List; import java.util.Map; -import java.util.StringTokenizer; import javax.security.sasl.SaslException; import javax.security.sasl.SaslServer; @@ -84,12 +83,12 @@ public class ServerConnectionDelegate extends ServerDelegate } private ServerConnectionDelegate(Map<String, Object> properties, - List<Object> locales, - Broker broker, - String localFQDN, - SubjectCreator subjectCreator) + List<Object> locales, + Broker broker, + String localFQDN, + SubjectCreator subjectCreator) { - super(properties, parseToList(subjectCreator.getMechanisms()), locales); + super(properties, (List) subjectCreator.getMechanisms(), locales); _broker = broker; _localFQDN = localFQDN; @@ -128,17 +127,6 @@ public class ServerConnectionDelegate extends ServerDelegate return map; } - private static List<Object> parseToList(String mechanisms) - { - List<Object> list = new ArrayList<Object>(); - StringTokenizer tokenizer = new StringTokenizer(mechanisms, " "); - while(tokenizer.hasMoreTokens()) - { - list.add(tokenizer.nextToken()); - } - return list; - } - public ServerSession getSession(Connection conn, SessionAttach atc) { SessionDelegate serverSessionDelegate = new ServerSessionDelegate(); diff --git a/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java b/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java index b28e9bc23c..0db0f9339c 100644 --- a/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java +++ b/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQProtocolEngine.java @@ -496,7 +496,16 @@ public class AMQProtocolEngine implements ServerProtocolEngine, AMQProtocolSessi // This sets the protocol version (and hence framing classes) for this session. setProtocolVersion(pv); - String mechanisms = _broker.getSubjectCreator(getLocalAddress()).getMechanisms(); + StringBuilder mechanismBuilder = new StringBuilder(); + for(String mechanismName : _broker.getSubjectCreator(getLocalAddress(), _transport.isSecure()).getMechanisms()) + { + if(mechanismBuilder.length() != 0) + { + mechanismBuilder.append(' '); + } + mechanismBuilder.append(mechanismName); + } + String mechanisms = mechanismBuilder.toString(); String locales = "en_US"; diff --git a/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/state/AMQStateManager.java b/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/state/AMQStateManager.java index af2ceeca7f..328064b6dc 100644 --- a/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/state/AMQStateManager.java +++ b/java/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/state/AMQStateManager.java @@ -20,6 +20,11 @@ */ package org.apache.qpid.server.protocol.v0_8.state; +import java.security.PrivilegedActionException; +import java.security.PrivilegedExceptionAction; + +import javax.security.auth.Subject; + import org.apache.log4j.Logger; import org.apache.qpid.AMQException; @@ -37,11 +42,6 @@ import org.apache.qpid.server.protocol.v0_8.AMQProtocolSession; import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.util.ServerScopedRuntimeException; -import javax.security.auth.Subject; - -import java.security.PrivilegedActionException; -import java.security.PrivilegedExceptionAction; - /** * The state manager is responsible for managing the state of the protocol session. <p/> For each AMQProtocolHandler * there is a separate state manager. @@ -147,6 +147,6 @@ public class AMQStateManager implements AMQMethodListener public SubjectCreator getSubjectCreator() { - return _broker.getSubjectCreator(getProtocolSession().getLocalAddress()); + return _broker.getSubjectCreator(getProtocolSession().getLocalAddress(), getProtocolSession().getTransport().isSecure()); } } diff --git a/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngine_1_0_0_SASL.java b/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngine_1_0_0_SASL.java index 0d6861d80c..550355216e 100644 --- a/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngine_1_0_0_SASL.java +++ b/java/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngine_1_0_0_SASL.java @@ -27,6 +27,7 @@ import java.nio.ByteBuffer; import java.security.Principal; import java.security.PrivilegedAction; import java.util.LinkedHashMap; +import java.util.List; import java.util.Map; import javax.security.auth.Subject; @@ -184,7 +185,7 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut Container container = new Container(_broker.getId().toString()); - SubjectCreator subjectCreator = _broker.getSubjectCreator(getLocalAddress()); + SubjectCreator subjectCreator = _broker.getSubjectCreator(getLocalAddress(), _transport.isSecure()); _endpoint = new ConnectionEndpoint(container, asSaslServerProvider(subjectCreator)); _endpoint.setLogger(new ConnectionEndpoint.FrameReceiptLogger() { @@ -236,7 +237,8 @@ public class ProtocolEngine_1_0_0_SASL implements ServerProtocolEngine, FrameOut _sender.send(HEADER.duplicate()); _sender.flush(); - _endpoint.initiateSASL(subjectCreator.getMechanisms().split(" ")); + List<String> mechanisms = subjectCreator.getMechanisms(); + _endpoint.initiateSASL(mechanisms.toArray(new String[mechanisms.size()])); } diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java index 1937ee8744..ef0a68a42b 100644 --- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java +++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/HttpManagementUtil.java @@ -45,6 +45,7 @@ import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; import org.apache.qpid.server.security.auth.AuthenticationResult.AuthenticationStatus; import org.apache.qpid.server.security.auth.SubjectAuthenticationResult; import org.apache.qpid.server.security.auth.UsernamePrincipal; +import org.apache.qpid.server.security.auth.manager.AnonymousAuthenticationManager; import org.apache.qpid.server.security.auth.manager.ExternalAuthenticationManager; import org.apache.qpid.transport.network.security.ssl.SSLUtil; @@ -146,14 +147,14 @@ public class HttpManagementUtil Subject subject = null; SocketAddress localAddress = getSocketAddress(request); final AuthenticationProvider authenticationProvider = managementConfig.getAuthenticationProvider(localAddress); - SubjectCreator subjectCreator = authenticationProvider.getSubjectCreator(); + SubjectCreator subjectCreator = authenticationProvider.getSubjectCreator(request.isSecure()); String remoteUser = request.getRemoteUser(); - if (remoteUser != null || subjectCreator.isAnonymousAuthenticationAllowed()) + if (remoteUser != null || authenticationProvider instanceof AnonymousAuthenticationManager) { subject = authenticateUser(subjectCreator, remoteUser, null); } - else if(subjectCreator.isExternalAuthenticationAllowed() + else if(authenticationProvider instanceof ExternalAuthenticationManager && Collections.list(request.getAttributeNames()).contains("javax.servlet.request.X509Certificate")) { Principal principal = null; diff --git a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java index af3973c7b3..81d67caf96 100644 --- a/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java +++ b/java/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java @@ -20,34 +20,36 @@ */ package org.apache.qpid.server.management.plugin.servlet.rest; +import java.io.IOException; +import java.io.PrintWriter; +import java.net.SocketAddress; +import java.security.Principal; +import java.security.SecureRandom; +import java.util.LinkedHashMap; +import java.util.List; +import java.util.Map; +import java.util.Random; + +import javax.security.auth.Subject; +import javax.security.sasl.SaslException; +import javax.security.sasl.SaslServer; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletRequest; +import javax.servlet.http.HttpServletResponse; +import javax.servlet.http.HttpSession; + import org.apache.commons.codec.binary.Base64; -import org.apache.qpid.server.management.plugin.servlet.ServletConnectionPrincipal; -import org.apache.qpid.server.util.ConnectionScopedRuntimeException; +import org.apache.log4j.Logger; import org.codehaus.jackson.map.ObjectMapper; import org.codehaus.jackson.map.SerializationConfig; -import org.apache.log4j.Logger; import org.apache.qpid.server.management.plugin.HttpManagementConfiguration; import org.apache.qpid.server.management.plugin.HttpManagementUtil; +import org.apache.qpid.server.management.plugin.servlet.ServletConnectionPrincipal; import org.apache.qpid.server.model.Broker; import org.apache.qpid.server.security.SubjectCreator; import org.apache.qpid.server.security.auth.AuthenticatedPrincipal; - -import javax.security.auth.Subject; -import javax.security.sasl.SaslException; -import javax.security.sasl.SaslServer; -import javax.servlet.ServletException; -import javax.servlet.http.HttpServletRequest; -import javax.servlet.http.HttpServletResponse; -import javax.servlet.http.HttpSession; -import java.io.IOException; -import java.io.PrintWriter; -import java.net.SocketAddress; -import java.security.Principal; -import java.security.SecureRandom; -import java.util.LinkedHashMap; -import java.util.Map; -import java.util.Random; +import org.apache.qpid.server.util.ConnectionScopedRuntimeException; public class SaslServlet extends AbstractServlet { @@ -81,7 +83,8 @@ public class SaslServlet extends AbstractServlet getRandom(session); SubjectCreator subjectCreator = getSubjectCreator(request); - String[] mechanisms = subjectCreator.getMechanisms().split(" "); + List<String> mechanismsList = subjectCreator.getMechanisms(); + String[] mechanisms = mechanismsList.toArray(new String[mechanismsList.size()]); Map<String, Object> outputObject = new LinkedHashMap<String, Object>(); final Subject subject = getAuthorisedSubject(request); @@ -237,7 +240,7 @@ public class SaslServlet extends AbstractServlet if(saslServer.isComplete()) { - Subject originalSubject = subjectCreator.createSubjectWithGroups(saslServer.getAuthorizationID()); + Subject originalSubject = subjectCreator.createSubjectWithGroups(new AuthenticatedPrincipal(saslServer.getAuthorizationID())); Subject subject = new Subject(false, originalSubject.getPrincipals(), originalSubject.getPublicCredentials(), @@ -298,7 +301,8 @@ public class SaslServlet extends AbstractServlet private SubjectCreator getSubjectCreator(HttpServletRequest request) { SocketAddress localAddress = HttpManagementUtil.getSocketAddress(request); - return HttpManagementUtil.getManagementConfiguration(getServletContext()).getAuthenticationProvider(localAddress).getSubjectCreator(); + return HttpManagementUtil.getManagementConfiguration(getServletContext()).getAuthenticationProvider(localAddress).getSubjectCreator( + request.isSecure()); } @Override diff --git a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java index f27a9126ea..78eba66158 100644 --- a/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java +++ b/java/broker-plugins/management-jmx/src/main/java/org/apache/qpid/server/jmx/JMXManagedObjectRegistry.java @@ -20,28 +20,6 @@ */ package org.apache.qpid.server.jmx; -import org.apache.log4j.Logger; -import org.apache.qpid.server.configuration.BrokerProperties; -import org.apache.qpid.server.logging.EventLogger; -import org.apache.qpid.server.logging.messages.ManagementConsoleMessages; -import org.apache.qpid.server.model.Broker; -import org.apache.qpid.server.model.KeyStore; -import org.apache.qpid.server.model.Port; -import org.apache.qpid.server.model.Transport; - -import org.apache.qpid.server.security.auth.jmx.JMXPasswordAuthenticator; -import org.apache.qpid.server.util.ServerScopedRuntimeException; - -import javax.management.JMException; -import javax.management.MBeanServer; -import javax.management.MBeanServerFactory; -import javax.management.ObjectName; -import javax.management.remote.JMXConnectorServer; -import javax.management.remote.JMXServiceURL; -import javax.management.remote.MBeanServerForwarder; -import javax.management.remote.rmi.RMIConnectorServer; -import javax.net.ssl.SSLContext; -import javax.rmi.ssl.SslRMIClientSocketFactory; import java.io.IOException; import java.lang.management.ManagementFactory; import java.net.InetAddress; @@ -59,6 +37,29 @@ import java.rmi.server.UnicastRemoteObject; import java.security.GeneralSecurityException; import java.util.HashMap; +import javax.management.JMException; +import javax.management.MBeanServer; +import javax.management.MBeanServerFactory; +import javax.management.ObjectName; +import javax.management.remote.JMXConnectorServer; +import javax.management.remote.JMXServiceURL; +import javax.management.remote.MBeanServerForwarder; +import javax.management.remote.rmi.RMIConnectorServer; +import javax.net.ssl.SSLContext; +import javax.rmi.ssl.SslRMIClientSocketFactory; + +import org.apache.log4j.Logger; + +import org.apache.qpid.server.configuration.BrokerProperties; +import org.apache.qpid.server.logging.EventLogger; +import org.apache.qpid.server.logging.messages.ManagementConsoleMessages; +import org.apache.qpid.server.model.Broker; +import org.apache.qpid.server.model.KeyStore; +import org.apache.qpid.server.model.Port; +import org.apache.qpid.server.model.Transport; +import org.apache.qpid.server.security.auth.jmx.JMXPasswordAuthenticator; +import org.apache.qpid.server.util.ServerScopedRuntimeException; + /** * This class starts up an MBeanserver. If out of the box agent has been enabled then there are no * security features implemented like user authentication and authorisation. @@ -157,7 +158,7 @@ public class JMXManagedObjectRegistry implements ManagedObjectRegistry int jmxPortConnectorServer = _connectorPort.getPort(); //add a JMXAuthenticator implementation the env map to authenticate the RMI based JMX connector server - JMXPasswordAuthenticator rmipa = new JMXPasswordAuthenticator(_broker, new InetSocketAddress(jmxPortConnectorServer)); + JMXPasswordAuthenticator rmipa = new JMXPasswordAuthenticator(_broker, new InetSocketAddress(jmxPortConnectorServer), connectorSslEnabled); HashMap<String,Object> connectorEnv = new HashMap<String,Object>(); connectorEnv.put(JMXConnectorServer.AUTHENTICATOR, rmipa); diff --git a/java/systests/src/main/java/org/apache/qpid/ra/QpidRAConnectionTest.java b/java/systests/src/main/java/org/apache/qpid/ra/QpidRAConnectionTest.java index b274edf164..daee2842fa 100644 --- a/java/systests/src/main/java/org/apache/qpid/ra/QpidRAConnectionTest.java +++ b/java/systests/src/main/java/org/apache/qpid/ra/QpidRAConnectionTest.java @@ -20,17 +20,14 @@ */ package org.apache.qpid.ra; -import org.apache.log4j.Logger; -import org.apache.qpid.test.utils.QpidBrokerTestCase; - import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Message; import javax.jms.Session; -import org.apache.qpid.ra.QpidRAConnectionFactoryImpl; -import org.apache.qpid.ra.QpidRAManagedConnectionFactory; -import org.apache.qpid.ra.QpidResourceAdapter; +import org.apache.log4j.Logger; + +import org.apache.qpid.test.utils.QpidBrokerTestCase; public class QpidRAConnectionTest extends QpidBrokerTestCase { @@ -38,7 +35,7 @@ public class QpidRAConnectionTest extends QpidBrokerTestCase private static final String BROKER_PORT = "15672"; - private static final String URL = "amqp://guest:guest@client/test?brokerlist='tcp://localhost:" + BROKER_PORT + "?sasl_mechs='PLAIN''"; + private static final String URL = "amqp://guest:guest@client/test?brokerlist='tcp://localhost:" + BROKER_PORT + "?sasl_mechs='PLAIN%25252520CRAM-MD5''"; public void testSessionCommitOnClosedConnectionThrowsException() throws Exception { diff --git a/java/systests/src/main/java/org/apache/qpid/ra/QpidRAXAResourceTest.java b/java/systests/src/main/java/org/apache/qpid/ra/QpidRAXAResourceTest.java index c8116d8cef..8f20a59b60 100644 --- a/java/systests/src/main/java/org/apache/qpid/ra/QpidRAXAResourceTest.java +++ b/java/systests/src/main/java/org/apache/qpid/ra/QpidRAXAResourceTest.java @@ -20,30 +20,18 @@ */ package org.apache.qpid.ra; -import org.apache.qpid.test.utils.QpidBrokerTestCase; - -import javax.jms.Connection; -import javax.jms.ConnectionFactory; -import javax.jms.Message; -import javax.jms.Session; - import javax.jms.XAConnection; import javax.jms.XAConnectionFactory; import javax.jms.XASession; -import javax.transaction.xa.XAException; -import javax.transaction.xa.XAResource; import org.apache.qpid.client.AMQXAResource; - -import org.apache.qpid.ra.QpidRAConnectionFactoryImpl; -import org.apache.qpid.ra.QpidRAManagedConnectionFactory; -import org.apache.qpid.ra.QpidResourceAdapter; +import org.apache.qpid.test.utils.QpidBrokerTestCase; public class QpidRAXAResourceTest extends QpidBrokerTestCase { private static final String FACTORY_NAME = "default"; private static final String BROKER_PORT = "15672"; - private static final String URL = "amqp://guest:guest@client/test?brokerlist='tcp://localhost:" + BROKER_PORT + "?sasl_mechs='PLAIN''"; + private static final String URL = "amqp://guest:guest@client/test?brokerlist='tcp://localhost:" + BROKER_PORT + "?sasl_mechs='PLAIN%2520CRAM-MD5''"; public void testXAResourceIsSameRM() throws Exception { diff --git a/java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.java b/java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.java index 80001099a8..7161cf1652 100644 --- a/java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.java +++ b/java/systests/src/main/java/org/apache/qpid/ra/admin/QpidConnectionFactoryProxyTest.java @@ -22,25 +22,18 @@ package org.apache.qpid.ra.admin; import javax.jms.Connection; import javax.jms.ConnectionFactory; -import javax.jms.JMSException; -import javax.naming.NamingException; import javax.jms.QueueConnection; import javax.jms.QueueConnectionFactory; -import javax.naming.Reference; -import javax.naming.Referenceable; -import javax.naming.spi.ObjectFactory; import javax.jms.TopicConnection; import javax.jms.TopicConnectionFactory; -import junit.framework.TestCase; - import org.apache.qpid.test.utils.QpidBrokerTestCase; public class QpidConnectionFactoryProxyTest extends QpidBrokerTestCase { private static final String BROKER_PORT = "15672"; - private static final String URL = "amqp://guest:guest@client/test?brokerlist='tcp://localhost:" + BROKER_PORT + "?sasl_mechs='PLAIN''"; + private static final String URL = "amqp://guest:guest@client/test?brokerlist='tcp://localhost:" + BROKER_PORT + "?sasl_mechs='PLAIN%2520CRAM-MD5''"; public void testQueueConnectionFactory() throws Exception { diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java index 3eba4fad21..2da4a21b2d 100644 --- a/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java +++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/QpidRestTestCase.java @@ -93,6 +93,11 @@ public class QpidRestTestCase extends QpidBrokerTestCase anonymousProviderAttributes.put(AuthenticationProvider.NAME, ANONYMOUS_AUTHENTICATION_PROVIDER); config.addObjectConfiguration(AuthenticationProvider.class, anonymousProviderAttributes); + config.setObjectAttribute(AuthenticationProvider.class, TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER, + "secureOnlyMechanisms", + "{}"); + + // set password authentication provider on http port for the tests config.setObjectAttribute(Port.class, TestBrokerConfiguration.ENTRY_NAME_HTTP_PORT, Port.AUTHENTICATION_PROVIDER, TestBrokerConfiguration.ENTRY_NAME_AUTHENTICATION_PROVIDER); diff --git a/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java b/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java index 163aa8dad9..547b7b1b00 100644 --- a/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java +++ b/java/systests/src/main/java/org/apache/qpid/systest/rest/SaslRestTest.java @@ -67,7 +67,7 @@ public class SaslRestTest extends QpidRestTestCase @SuppressWarnings("unchecked") List<String> mechanisms = (List<String>) saslData.get("mechanisms"); - String[] expectedMechanisms = { "AMQPLAIN", "PLAIN", "CRAM-MD5" }; + String[] expectedMechanisms = { "CRAM-MD5" }; for (String mechanism : expectedMechanisms) { assertTrue("Mechanism " + mechanism + " is not found", mechanisms.contains(mechanism)); diff --git a/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java b/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java index 963a23b0ba..ed03e83292 100644 --- a/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java +++ b/java/systests/src/main/java/org/apache/qpid/test/unit/client/connection/ConnectionTest.java @@ -20,6 +20,10 @@ */ package org.apache.qpid.test.unit.client.connection; +import javax.jms.Connection; +import javax.jms.QueueSession; +import javax.jms.TopicSession; + import org.apache.qpid.AMQConnectionFailureException; import org.apache.qpid.AMQException; import org.apache.qpid.AMQUnresolvedAddressException; @@ -36,10 +40,6 @@ import org.apache.qpid.jms.ConnectionURL; import org.apache.qpid.jms.Session; import org.apache.qpid.test.utils.QpidBrokerTestCase; -import javax.jms.Connection; -import javax.jms.QueueSession; -import javax.jms.TopicSession; - public class ConnectionTest extends QpidBrokerTestCase { @@ -358,7 +358,7 @@ public class ConnectionTest extends QpidBrokerTestCase try { BrokerDetails broker = getBroker(); - String url = "amqp:///test?brokerlist='" + broker + "?sasl_mechs='PLAIN''"; + String url = "amqp:///test?brokerlist='" + broker + "?sasl_mechs='PLAIN%2520CRAM-MD5''"; conn = new AMQConnection(url); conn.close(); fail("Exception should be thrown as user name and password is required"); |