You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@qpid.apache.org by or...@apache.org on 2016/12/02 15:47:52 UTC
svn commit: r1772364 [4/4] - in /qpid/java/trunk:
broker-core/src/main/java/org/apache/qpid/server/model/
broker-core/src/main/java/org/apache/qpid/server/security/
broker-core/src/main/java/org/apache/qpid/server/security/auth/database/
broker-core/sr...
Added: qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/scram/ScramNegotiatorTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/scram/ScramNegotiatorTest.java?rev=1772364&view=auto
==============================================================================
--- qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/scram/ScramNegotiatorTest.java (added)
+++ qpid/java/trunk/broker-core/src/test/java/org/apache/qpid/server/security/auth/sasl/scram/ScramNegotiatorTest.java Fri Dec 2 15:47:52 2016
@@ -0,0 +1,442 @@
+/*
+ * 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.scram;
+
+
+import static org.mockito.Matchers.eq;
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.when;
+
+import java.nio.charset.Charset;
+import java.security.MessageDigest;
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.UUID;
+
+import javax.crypto.Mac;
+import javax.crypto.spec.SecretKeySpec;
+import javax.security.sasl.SaslException;
+import javax.xml.bind.DatatypeConverter;
+
+import org.apache.qpid.server.model.AuthenticationProvider;
+import org.apache.qpid.server.model.Broker;
+import org.apache.qpid.server.model.BrokerTestHelper;
+import org.apache.qpid.server.model.ConfiguredObject;
+import org.apache.qpid.server.model.ConfiguredObjectFactory;
+import org.apache.qpid.server.model.PasswordCredentialManagingAuthenticationProvider;
+import org.apache.qpid.server.model.State;
+import org.apache.qpid.server.security.auth.AuthenticationResult;
+import org.apache.qpid.server.security.auth.manager.ScramSHA1AuthenticationManager;
+import org.apache.qpid.server.security.auth.manager.ScramSHA256AuthenticationManager;
+import org.apache.qpid.server.security.auth.sasl.PasswordSource;
+import org.apache.qpid.test.utils.QpidTestCase;
+import org.apache.qpid.util.Strings;
+
+public class ScramNegotiatorTest extends QpidTestCase
+{
+ private static final String VALID_USER_NAME = "testUser";
+ private static final String VALID_USER_PASSWORD = "testPassword";
+ private static final String INVALID_USER_PASSWORD = VALID_USER_PASSWORD + "1";
+ private static final String INVALID_USER_NAME = VALID_USER_NAME + "1";
+ private static final String GS2_HEADER = "n,,";
+ private static final Charset ASCII = Charset.forName("ASCII");
+ private static final int ITERATION_COUNT = 4096;
+
+ private String _clientFirstMessageBare;
+ private String _clientNonce;
+ private byte[] _serverSignature;
+ private PasswordSource _passwordSource;
+ private AuthenticationProvider<?> _authenticationProvider;
+ private Broker<?> _broker;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ _clientNonce = UUID.randomUUID().toString();
+ _passwordSource = mock(PasswordSource.class);
+ when(_passwordSource.getPassword(eq(VALID_USER_NAME))).thenReturn(VALID_USER_PASSWORD.toCharArray());
+ _authenticationProvider = mock(AuthenticationProvider.class);
+ _broker = BrokerTestHelper.createBrokerMock();
+ }
+
+ @Override
+ public void tearDown() throws Exception
+ {
+ try
+ {
+ super.tearDown();
+ }
+ finally
+ {
+ _authenticationProvider.close();
+ }
+ }
+
+ public void testHandleResponseForScramSha256ValidCredentialsAdapterSource() throws Exception
+ {
+ final ScramSaslServerSource scramSaslServerSource =
+ new ScramSaslServerSourceAdapter(ITERATION_COUNT,
+ ScramSHA256AuthenticationManager.HMAC_NAME,
+ ScramSHA256AuthenticationManager.DIGEST_NAME,
+ _passwordSource);
+ doSaslNegotiationTestValidCredentials(ScramSHA256AuthenticationManager.MECHANISM,
+ _authenticationProvider,
+ scramSaslServerSource);
+ }
+
+ public void testHandleResponseForScramSha1ValidCredentialsAdapterSource() throws Exception
+ {
+ final ScramSaslServerSource scramSaslServerSource =
+ new ScramSaslServerSourceAdapter(ITERATION_COUNT,
+ ScramSHA1AuthenticationManager.HMAC_NAME,
+ ScramSHA1AuthenticationManager.DIGEST_NAME,
+ _passwordSource);
+ doSaslNegotiationTestValidCredentials(ScramSHA1AuthenticationManager.MECHANISM,
+ _authenticationProvider,
+ scramSaslServerSource);
+ }
+
+ public void testHandleResponseForScramSha256InvalidPasswordAdapterSource() throws Exception
+ {
+ final ScramSaslServerSource scramSaslServerSource =
+ new ScramSaslServerSourceAdapter(ITERATION_COUNT,
+ ScramSHA256AuthenticationManager.HMAC_NAME,
+ ScramSHA256AuthenticationManager.DIGEST_NAME,
+ _passwordSource);
+ doSaslNegotiationTestInvalidCredentials(VALID_USER_NAME,
+ INVALID_USER_PASSWORD,
+ ScramSHA256AuthenticationManager.MECHANISM,
+ _authenticationProvider,
+ scramSaslServerSource);
+ }
+
+ public void testHandleResponseForScramSha1InvalidPasswordAdapterSource() throws Exception
+ {
+ final ScramSaslServerSource scramSaslServerSource =
+ new ScramSaslServerSourceAdapter(ITERATION_COUNT,
+ ScramSHA1AuthenticationManager.HMAC_NAME,
+ ScramSHA1AuthenticationManager.DIGEST_NAME,
+ _passwordSource);
+ doSaslNegotiationTestInvalidCredentials(VALID_USER_NAME,
+ INVALID_USER_PASSWORD,
+ ScramSHA1AuthenticationManager.MECHANISM,
+ _authenticationProvider,
+ scramSaslServerSource);
+ }
+
+ public void testHandleResponseForScramSha256InvalidUsernameAdapterSource() throws Exception
+ {
+ final ScramSaslServerSource scramSaslServerSource =
+ new ScramSaslServerSourceAdapter(ITERATION_COUNT,
+ ScramSHA256AuthenticationManager.HMAC_NAME,
+ ScramSHA256AuthenticationManager.DIGEST_NAME,
+ _passwordSource);
+ doSaslNegotiationTestInvalidCredentials(INVALID_USER_NAME,
+ VALID_USER_PASSWORD,
+ ScramSHA256AuthenticationManager.MECHANISM,
+ _authenticationProvider,
+ scramSaslServerSource);
+ }
+
+ public void testHandleResponseForScramSha1InvalidUsernameAdapterSource() throws Exception
+ {
+ final ScramSaslServerSource scramSaslServerSource =
+ new ScramSaslServerSourceAdapter(ITERATION_COUNT,
+ ScramSHA1AuthenticationManager.HMAC_NAME,
+ ScramSHA1AuthenticationManager.DIGEST_NAME,
+ _passwordSource);
+ doSaslNegotiationTestInvalidCredentials(INVALID_USER_NAME,
+ VALID_USER_PASSWORD,
+ ScramSHA1AuthenticationManager.MECHANISM,
+ _authenticationProvider,
+ scramSaslServerSource);
+ }
+
+ public void testHandleResponseForScramSha256ValidCredentialsAuthenticationProvider() throws Exception
+ {
+ _authenticationProvider = createTestAuthenticationManager(ScramSHA256AuthenticationManager.PROVIDER_TYPE);
+ doSaslNegotiationTestValidCredentials(ScramSHA256AuthenticationManager.MECHANISM, _authenticationProvider,
+ (ScramSaslServerSource) _authenticationProvider);
+ }
+
+ public void testHandleResponseForScramSha1ValidCredentialsAuthenticationProvider() throws Exception
+ {
+ _authenticationProvider = createTestAuthenticationManager(ScramSHA1AuthenticationManager.PROVIDER_TYPE);
+ doSaslNegotiationTestValidCredentials(ScramSHA1AuthenticationManager.MECHANISM, _authenticationProvider,
+ (ScramSaslServerSource) _authenticationProvider);
+ }
+
+ public void testHandleResponseForScramSha256InvalidPasswordAuthenticationProvider() throws Exception
+ {
+ _authenticationProvider = createTestAuthenticationManager(ScramSHA256AuthenticationManager.PROVIDER_TYPE);
+ doSaslNegotiationTestInvalidCredentials(VALID_USER_NAME,
+ INVALID_USER_PASSWORD,
+ "SCRAM-SHA-256",
+ _authenticationProvider,
+ (ScramSaslServerSource) _authenticationProvider);
+ }
+
+ public void testHandleResponseForScramSha1InvalidPasswordAuthenticationProvider() throws Exception
+ {
+ _authenticationProvider = createTestAuthenticationManager(ScramSHA1AuthenticationManager.PROVIDER_TYPE);
+ doSaslNegotiationTestInvalidCredentials(VALID_USER_NAME,
+ INVALID_USER_PASSWORD,
+ "SCRAM-SHA-1",
+ _authenticationProvider,
+ (ScramSaslServerSource) _authenticationProvider);
+ }
+
+ public void testHandleResponseForScramSha256InvalidUsernameAuthenticationProvider() throws Exception
+ {
+ _authenticationProvider = createTestAuthenticationManager(ScramSHA256AuthenticationManager.PROVIDER_TYPE);
+ doSaslNegotiationTestInvalidCredentials(INVALID_USER_NAME,
+ VALID_USER_PASSWORD,
+ "SCRAM-SHA-256",
+ _authenticationProvider,
+ (ScramSaslServerSource) _authenticationProvider);
+ }
+
+ public void testHandleResponseForScramSha1InvalidUsernameAuthenticationProvider() throws Exception
+ {
+ _authenticationProvider = createTestAuthenticationManager(ScramSHA1AuthenticationManager.PROVIDER_TYPE);
+ doSaslNegotiationTestInvalidCredentials(INVALID_USER_NAME,
+ VALID_USER_PASSWORD,
+ "SCRAM-SHA-1",
+ _authenticationProvider,
+ (ScramSaslServerSource) _authenticationProvider);
+ }
+
+ private void doSaslNegotiationTestValidCredentials(final String mechanism,
+ final AuthenticationProvider<?> authenticationProvider,
+ final ScramSaslServerSource scramSaslServerSource)
+ throws Exception
+ {
+ ScramNegotiator scramNegotiator = new ScramNegotiator(authenticationProvider,
+ scramSaslServerSource,
+ mechanism);
+
+ byte[] initialResponse = createInitialResponse(VALID_USER_NAME);
+
+ AuthenticationResult firstResult = scramNegotiator.handleResponse(initialResponse);
+ assertEquals("Unexpected first result status",
+ AuthenticationResult.AuthenticationStatus.CONTINUE,
+ firstResult.getStatus());
+ assertNotNull("Unexpected first result challenge", firstResult.getChallenge());
+
+ byte[] response = calculateClientProof(firstResult.getChallenge(),
+ scramSaslServerSource.getHmacName(),
+ scramSaslServerSource.getDigestName(),
+ VALID_USER_PASSWORD);
+ AuthenticationResult secondResult = scramNegotiator.handleResponse(response);
+ assertEquals("Unexpected second result status",
+ AuthenticationResult.AuthenticationStatus.SUCCESS,
+ secondResult.getStatus());
+ assertNotNull("Unexpected second result challenge", secondResult.getChallenge());
+ assertEquals("Unexpected second result principal", VALID_USER_NAME, secondResult.getMainPrincipal().getName());
+
+ String serverFinalMessage = new String(secondResult.getChallenge(), ASCII);
+ String[] parts = serverFinalMessage.split(",");
+ if (!parts[0].startsWith("v="))
+ {
+ fail("Server final message did not contain verifier");
+ }
+ byte[] serverSignature = Strings.decodeBase64(parts[0].substring(2));
+ if (!Arrays.equals(_serverSignature, serverSignature))
+ {
+ fail("Server signature did not match");
+ }
+
+ AuthenticationResult thirdResult = scramNegotiator.handleResponse(initialResponse);
+ assertEquals("Unexpected result status after completion of negotiation",
+ AuthenticationResult.AuthenticationStatus.ERROR,
+ thirdResult.getStatus());
+ assertNull("Unexpected principal after completion of negotiation", thirdResult.getMainPrincipal());
+ }
+
+ private void doSaslNegotiationTestInvalidCredentials(final String userName,
+ final String userPassword,
+ final String mechanism,
+ final AuthenticationProvider<?> authenticationProvider,
+ final ScramSaslServerSource scramSaslServerSource)
+ throws Exception
+ {
+ ScramNegotiator scramNegotiator = new ScramNegotiator(authenticationProvider,
+ scramSaslServerSource,
+ mechanism);
+
+ byte[] initialResponse = createInitialResponse(userName);
+ AuthenticationResult firstResult = scramNegotiator.handleResponse(initialResponse);
+ assertEquals("Unexpected first result status",
+ AuthenticationResult.AuthenticationStatus.CONTINUE,
+ firstResult.getStatus());
+ assertNotNull("Unexpected first result challenge", firstResult.getChallenge());
+
+ byte[] response = calculateClientProof(firstResult.getChallenge(),
+ scramSaslServerSource.getHmacName(),
+ scramSaslServerSource.getDigestName(),
+ userPassword);
+ AuthenticationResult secondResult = scramNegotiator.handleResponse(response);
+ assertEquals("Unexpected second result status",
+ AuthenticationResult.AuthenticationStatus.ERROR,
+ secondResult.getStatus());
+ assertNull("Unexpected second result challenge", secondResult.getChallenge());
+ assertNull("Unexpected second result principal", secondResult.getMainPrincipal());
+ }
+
+
+ private byte[] calculateClientProof(final byte[] challenge,
+ String hmacName,
+ String digestName,
+ String userPassword) throws Exception
+ {
+
+ String serverFirstMessage = new String(challenge, ASCII);
+ String[] parts = serverFirstMessage.split(",");
+ if (parts.length < 3)
+ {
+ fail("Server challenge '" + serverFirstMessage + "' cannot be parsed");
+ }
+ else if (parts[0].startsWith("m="))
+ {
+ fail("Server requires mandatory extension which is not supported: " + parts[0]);
+ }
+ else if (!parts[0].startsWith("r="))
+ {
+ fail("Server challenge '" + serverFirstMessage + "' cannot be parsed, cannot find nonce");
+ }
+ String nonce = parts[0].substring(2);
+ if (!nonce.startsWith(_clientNonce))
+ {
+ fail("Server challenge did not use correct client nonce");
+ }
+ if (!parts[1].startsWith("s="))
+ {
+ fail("Server challenge '" + serverFirstMessage + "' cannot be parsed, cannot find salt");
+ }
+ byte[] salt = Strings.decodeBase64(parts[1].substring(2));
+ if (!parts[2].startsWith("i="))
+ {
+ fail("Server challenge '" + serverFirstMessage + "' cannot be parsed, cannot find iteration count");
+ }
+ int _iterationCount = Integer.parseInt(parts[2].substring(2));
+ if (_iterationCount <= 0)
+ {
+ fail("Iteration count " + _iterationCount + " is not a positive integer");
+ }
+ byte[] passwordBytes = saslPrep(userPassword).getBytes("UTF-8");
+ byte[] saltedPassword = generateSaltedPassword(passwordBytes, hmacName, _iterationCount, salt);
+
+ String clientFinalMessageWithoutProof =
+ "c=" + DatatypeConverter.printBase64Binary(GS2_HEADER.getBytes(ASCII))
+ + ",r=" + nonce;
+
+ String authMessage = _clientFirstMessageBare + "," + serverFirstMessage + "," + clientFinalMessageWithoutProof;
+ byte[] clientKey = computeHmac(saltedPassword, "Client Key", hmacName);
+ byte[] storedKey = MessageDigest.getInstance(digestName).digest(clientKey);
+ byte[] clientSignature = computeHmac(storedKey, authMessage, hmacName);
+ byte[] clientProof = clientKey.clone();
+ for (int i = 0; i < clientProof.length; i++)
+ {
+ clientProof[i] ^= clientSignature[i];
+ }
+ byte[] serverKey = computeHmac(saltedPassword, "Server Key", hmacName);
+ _serverSignature = computeHmac(serverKey, authMessage, hmacName);
+ String finalMessageWithProof = clientFinalMessageWithoutProof
+ + ",p=" + DatatypeConverter.printBase64Binary(clientProof);
+ return finalMessageWithProof.getBytes();
+ }
+
+ private byte[] computeHmac(final byte[] key, final String string, String hmacName)
+ throws Exception
+ {
+ Mac mac = createHmac(key, hmacName);
+ mac.update(string.getBytes(ASCII));
+ return mac.doFinal();
+ }
+
+ private byte[] generateSaltedPassword(final byte[] passwordBytes,
+ String hmacName,
+ final int iterationCount,
+ final byte[] salt) throws Exception
+ {
+ Mac mac = createHmac(passwordBytes, hmacName);
+ mac.update(salt);
+ mac.update(new byte[]{0, 0, 0, 1});
+ byte[] result = mac.doFinal();
+
+ byte[] previous = null;
+ for (int i = 1; i < iterationCount; i++)
+ {
+ mac.update(previous != null ? previous : result);
+ previous = mac.doFinal();
+ for (int x = 0; x < result.length; x++)
+ {
+ result[x] ^= previous[x];
+ }
+ }
+
+ return result;
+ }
+
+ private Mac createHmac(final byte[] keyBytes, String hmacName) throws Exception
+ {
+ SecretKeySpec key = new SecretKeySpec(keyBytes, hmacName);
+ Mac mac = Mac.getInstance(hmacName);
+ mac.init(key);
+ return mac;
+ }
+
+ private String saslPrep(String name) throws SaslException
+ {
+ name = name.replace("=", "=3D");
+ name = name.replace(",", "=2C");
+ return name;
+ }
+
+ private byte[] createInitialResponse(final String userName) throws SaslException
+ {
+ _clientFirstMessageBare = "n=" + saslPrep(userName) + ",r=" + _clientNonce;
+ return (GS2_HEADER + _clientFirstMessageBare).getBytes(ASCII);
+ }
+
+ private AuthenticationProvider createTestAuthenticationManager(String type)
+ {
+ Map<String, Object> attributes = new HashMap<>();
+ attributes.put(ConfiguredObject.NAME, getTestName());
+ attributes.put(ConfiguredObject.ID, UUID.randomUUID());
+ attributes.put(ConfiguredObject.TYPE, type);
+ ConfiguredObjectFactory objectFactory = _broker.getObjectFactory();
+ @SuppressWarnings("unchecked")
+ AuthenticationProvider<?> configuredObject =
+ objectFactory.create(AuthenticationProvider.class, attributes, _broker);
+ assertEquals("Unexpected state", State.ACTIVE, configuredObject.getState());
+
+ PasswordCredentialManagingAuthenticationProvider<?> authenticationProvider =
+ (PasswordCredentialManagingAuthenticationProvider<?>) configuredObject;
+ authenticationProvider.createUser(VALID_USER_NAME,
+ VALID_USER_PASSWORD,
+ Collections.<String, String>emptyMap());
+ return configuredObject;
+ }
+}
\ No newline at end of file
Modified: qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/AMQPConnection_0_10.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/AMQPConnection_0_10.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/AMQPConnection_0_10.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/AMQPConnection_0_10.java Fri Dec 2 15:47:52 2016
@@ -20,8 +20,6 @@
*/
package org.apache.qpid.server.protocol.v0_10;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
import java.security.AccessController;
import java.security.PrivilegedAction;
import java.util.Collection;
@@ -84,15 +82,9 @@ public class AMQPConnection_0_10 extends
super(broker, network, port, transport, Protocol.AMQP_0_10, id, aggregateTicker);
_connection = new ServerConnection(id, broker, port, transport, this);
- SocketAddress address = network.getLocalAddress();
- String fqdn = null;
- if (address instanceof InetSocketAddress)
- {
- fqdn = ((InetSocketAddress) address).getHostName();
- }
SubjectCreator subjectCreator = port.getAuthenticationProvider().getSubjectCreator(transport.isSecure());
- ConnectionDelegate connDelegate = new ServerConnectionDelegate(broker, fqdn, subjectCreator);
+ ConnectionDelegate connDelegate = new ServerConnectionDelegate(broker, subjectCreator);
_connection.setConnectionDelegate(connDelegate);
_connection.setRemoteAddress(network.getRemoteAddress());
Modified: qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnection.java Fri Dec 2 15:47:52 2016
@@ -30,6 +30,8 @@ import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.Collections;
import java.util.Iterator;
+import java.util.List;
+import java.util.Map;
import java.util.NoSuchElementException;
import java.util.Queue;
import java.util.Set;
@@ -37,6 +39,7 @@ import java.util.concurrent.ConcurrentLi
import java.util.concurrent.atomic.AtomicLong;
import javax.security.auth.Subject;
+import javax.security.sasl.SaslServer;
import org.apache.qpid.protocol.ErrorCodes;
import org.apache.qpid.server.logging.EventLogger;
@@ -610,4 +613,44 @@ public class ServerConnection extends Co
{
return super.isConnectionLost();
}
+
+ @Override
+ protected void setLocale(String locale)
+ {
+ super.setLocale(locale);
+ }
+
+ @Override
+ protected void sendConnectionSecure(byte[] challenge, Option ... options)
+ {
+ super.sendConnectionSecure(challenge, options);
+ }
+
+ @Override
+ protected void sendConnectionTune(int channelMax, int maxFrameSize, int heartbeatMin, int heartbeatMax, Option ... options)
+ {
+ super.sendConnectionTune(channelMax, maxFrameSize, heartbeatMin, heartbeatMax, options);
+ }
+
+ @Override
+ protected void setChannelMax(int max)
+ {
+ super.setChannelMax(max);
+ }
+
+ @Override
+ protected void map(Session ssn, int channel)
+ {
+ super.map(ssn, channel);
+ }
+
+ @Override
+ protected void sendConnectionStart(final Map<String, Object> clientProperties,
+ final List<Object> mechanisms,
+ final List<Object> locales,
+ final Option... options)
+ {
+ super.sendConnectionStart(clientProperties, mechanisms, locales, options);
+ }
+
}
Modified: qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerConnectionDelegate.java Fri Dec 2 15:47:52 2016
@@ -32,9 +32,6 @@ import java.util.Iterator;
import java.util.List;
import java.util.Map;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -47,23 +44,45 @@ import org.apache.qpid.server.model.port
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 org.apache.qpid.server.security.auth.sasl.SaslNegotiator;
import org.apache.qpid.server.transport.AMQPConnection;
import org.apache.qpid.server.util.ConnectionScopedRuntimeException;
import org.apache.qpid.server.virtualhost.VirtualHostUnavailableException;
-import org.apache.qpid.transport.*;
+import org.apache.qpid.transport.Binary;
+import org.apache.qpid.transport.Connection;
+import org.apache.qpid.transport.ConnectionClose;
+import org.apache.qpid.transport.ConnectionCloseCode;
+import org.apache.qpid.transport.ConnectionDelegate;
+import org.apache.qpid.transport.ConnectionOpen;
+import org.apache.qpid.transport.ConnectionOpenOk;
+import org.apache.qpid.transport.ConnectionRedirect;
+import org.apache.qpid.transport.ConnectionSecureOk;
+import org.apache.qpid.transport.ConnectionStartOk;
+import org.apache.qpid.transport.ConnectionTuneOk;
+import org.apache.qpid.transport.Constant;
+import org.apache.qpid.transport.ProtocolHeader;
+import org.apache.qpid.transport.Session;
+import org.apache.qpid.transport.SessionAttach;
+import org.apache.qpid.transport.SessionDelegate;
+import org.apache.qpid.transport.SessionDetach;
+import org.apache.qpid.transport.SessionDetachCode;
+import org.apache.qpid.transport.SessionDetached;
-public class ServerConnectionDelegate extends ServerDelegate
+public class ServerConnectionDelegate extends ConnectionDelegate
{
private static final Logger LOGGER = LoggerFactory.getLogger(ServerConnectionDelegate.class);
+ private List<Object> _locales;
+ private List<Object> _mechanisms;
+
private final Broker _broker;
- private final String _localFQDN;
private int _maxNoOfChannels;
private Map<String,Object> _clientProperties;
private final SubjectCreator _subjectCreator;
private int _maximumFrameSize;
private boolean _compressionSupported;
+ private volatile SaslNegotiator _saslNegotiator;
enum ConnectionState
{
@@ -79,21 +98,21 @@ public class ServerConnectionDelegate ex
private volatile SubjectAuthenticationResult _successfulAuthenticationResult;
- public ServerConnectionDelegate(Broker<?> broker, String localFQDN, SubjectCreator subjectCreator)
+ public ServerConnectionDelegate(Broker<?> broker, SubjectCreator subjectCreator)
{
- this(createConnectionProperties(broker), Collections.singletonList((Object)"en_US"), broker, localFQDN, subjectCreator);
+ this(createConnectionProperties(broker), Collections.singletonList((Object)"en_US"), broker, subjectCreator);
}
private ServerConnectionDelegate(Map<String, Object> properties,
List<Object> locales,
Broker<?> broker,
- String localFQDN,
SubjectCreator subjectCreator)
{
- super(properties, (List) subjectCreator.getMechanisms(), locales);
+ _clientProperties = properties;
+ _mechanisms = (List) subjectCreator.getMechanisms();
+ _locales = locales;
_broker = broker;
- _localFQDN = localFQDN;
_maxNoOfChannels = broker.getConnection_sessionCountLimit();
_subjectCreator = subjectCreator;
_maximumFrameSize = Math.min(0xffff, broker.getNetworkBufferSize());
@@ -120,8 +139,10 @@ public class ServerConnectionDelegate ex
@Override
public void init(final Connection conn, final ProtocolHeader hdr)
{
- assertState((ServerConnection)conn, ConnectionState.INIT);
- super.init(conn, hdr);
+ ServerConnection serverConnection = (ServerConnection) conn;
+ assertState(serverConnection, ConnectionState.INIT);
+ serverConnection.send(new ProtocolHeader(1, 0, 10));
+ serverConnection.sendConnectionStart(_clientProperties, _mechanisms, _locales);
_state = ConnectionState.AWAIT_START_OK;
}
@@ -168,27 +189,21 @@ public class ServerConnectionDelegate ex
return ssn;
}
- protected SaslServer createSaslServer(Connection conn, String mechanism) throws SaslException
- {
- return _subjectCreator.createSaslServer(mechanism, _localFQDN, ((ServerConnection) conn).getPeerPrincipal());
-
- }
-
@Override
public void connectionSecureOk(final Connection conn, final ConnectionSecureOk ok)
{
- assertState((ServerConnection)conn, ConnectionState.AWAIT_SECURE_OK);
- super.connectionSecureOk(conn, ok);
+ ServerConnection serverConnection = (ServerConnection) conn;
+ assertState(serverConnection, ConnectionState.AWAIT_SECURE_OK);
+ secure(serverConnection, ok.getResponse());
}
- protected void secure(final SaslServer ss, final Connection conn, final byte[] response)
+ protected void secure(final ServerConnection sconn, final byte[] response)
{
- final ServerConnection sconn = (ServerConnection) conn;
SubjectAuthenticationResult authResult = _successfulAuthenticationResult;
byte[] challenge = null;
if (authResult == null)
{
- authResult = _subjectCreator.authenticate(ss, response);
+ authResult = _subjectCreator.authenticate(_saslNegotiator, response);
challenge = authResult.getChallenge();
}
@@ -197,19 +212,20 @@ public class ServerConnectionDelegate ex
_successfulAuthenticationResult = authResult;
if (challenge == null || challenge.length == 0)
{
- tuneAuthorizedConnection(sconn);
+ sconn.sendConnectionTune(getChannelMax(), getFrameMax(), 0, getHeartbeatMax());
sconn.setAuthorizedSubject(authResult.getSubject());
_state = ConnectionState.AWAIT_TUNE_OK;
+ disposeSaslNegotiator();
}
else
{
- connectionAuthContinue(sconn, authResult.getChallenge());
+ sconn.sendConnectionSecure(authResult.getChallenge());
_state = ConnectionState.AWAIT_SECURE_OK;
}
}
else if (AuthenticationStatus.CONTINUE.equals(authResult.getStatus()))
{
- connectionAuthContinue(sconn, authResult.getChallenge());
+ sconn.sendConnectionSecure(authResult.getChallenge());
_state = ConnectionState.AWAIT_SECURE_OK;
}
else
@@ -348,24 +364,19 @@ public class ServerConnectionDelegate ex
sconn.getAmqpConnection().initialiseHeartbeating(writerIdle, readerIdle);
}
- setConnectionTuneOkChannelMax(sconn, okChannelMax);
- conn.setMaxFrameSize(okMaxFrameSize);
+ //0 means no implied limit, except available server resources
+ //(or that forced by protocol limitations [0xFFFF])
+ sconn.setChannelMax(okChannelMax == 0 ? getChannelMax() : okChannelMax);
+ sconn.setMaxFrameSize(okMaxFrameSize);
_state = ConnectionState.AWAIT_OPEN;
}
- @Override
- public int getChannelMax()
+ private int getChannelMax()
{
return _maxNoOfChannels;
}
- protected void setChannelMax(int channelMax)
- {
- _maxNoOfChannels = channelMax;
- }
-
- @Override
- protected int getFrameMax()
+ private int getFrameMax()
{
return _maximumFrameSize;
}
@@ -395,17 +406,21 @@ public class ServerConnectionDelegate ex
@Override
public void sessionAttach(final Connection conn, final SessionAttach atc)
{
- assertState((ServerConnection)conn, ConnectionState.OPEN);
+ ServerConnection serverConnection = (ServerConnection) conn;
+ assertState(serverConnection, ConnectionState.OPEN);
- final Session ssn;
+ final ServerSession ssn = getSession(conn, atc);
if(isSessionNameUnique(atc.getName(), conn))
{
- super.sessionAttach(conn, atc);
+
+ serverConnection.map(ssn, atc.getChannel());
+ serverConnection.registerSession(ssn);
+ ssn.sendSessionAttached(atc.getName());
+ ssn.setState(Session.State.OPEN);
}
else
{
- ssn = getSession(conn, atc);
ssn.invoke(new SessionDetached(atc.getName(), SessionDetachCode.SESSION_BUSY));
ssn.closed();
}
@@ -437,7 +452,8 @@ public class ServerConnectionDelegate ex
@Override
public void connectionStartOk(Connection conn, ConnectionStartOk ok)
{
- assertState((ServerConnection)conn, ConnectionState.AWAIT_START_OK);
+ ServerConnection serverConnection = (ServerConnection)conn;
+ assertState(serverConnection, ConnectionState.AWAIT_START_OK);
_clientProperties = ok.getClientProperties();
if(_clientProperties != null)
{
@@ -448,13 +464,34 @@ public class ServerConnectionDelegate ex
_compressionSupported = Boolean.parseBoolean(String.valueOf(compressionSupported));
}
- final AMQPConnection_0_10 protocolEngine = ((ServerConnection) conn).getAmqpConnection();
+ final AMQPConnection_0_10 protocolEngine = serverConnection.getAmqpConnection();
protocolEngine.setClientId(getStringClientProperty(ConnectionStartProperties.CLIENT_ID_0_10));
protocolEngine.setClientProduct(getStringClientProperty(ConnectionStartProperties.PRODUCT));
protocolEngine.setClientVersion(getStringClientProperty(ConnectionStartProperties.VERSION_0_10));
protocolEngine.setRemoteProcessPid(getStringClientProperty(ConnectionStartProperties.PID));
}
- super.connectionStartOk(conn, ok);
+
+
+ serverConnection.setLocale(ok.getLocale());
+ String mechanism = ok.getMechanism();
+
+ if (mechanism == null || mechanism.length() == 0)
+ {
+ serverConnection.sendConnectionClose(ConnectionCloseCode.CONNECTION_FORCED,
+ "No Sasl mechanism was specified");
+ return;
+ }
+
+ _saslNegotiator = _subjectCreator.createSaslNegotiator(mechanism, serverConnection.getAmqpConnection());
+ if (_saslNegotiator == null)
+ {
+ serverConnection.sendConnectionClose(ConnectionCloseCode.CONNECTION_FORCED,
+ "No SaslServer could be created for mechanism: " + mechanism);
+ }
+ else
+ {
+ secure(serverConnection, ok.getResponse());
+ }
}
private String getStringClientProperty(final String name)
@@ -487,15 +524,31 @@ public class ServerConnectionDelegate ex
return (_clientProperties == null || _clientProperties.get(ConnectionStartProperties.PID) == null) ? null : String.valueOf(_clientProperties.get(ConnectionStartProperties.PID));
}
- @Override
protected int getHeartbeatMax()
{
int delay = (Integer)_broker.getAttribute(Broker.CONNECTION_HEART_BEAT_DELAY);
- return delay == 0 ? super.getHeartbeatMax() : delay;
+ return delay == 0 ? 0xFFFF : delay;
}
public boolean isCompressionSupported()
{
return _compressionSupported && _broker.isMessageCompressionEnabled();
}
+
+ private void connectionAuthFailed(final Connection conn, Exception e)
+ {
+ ServerConnection serverConnection = (ServerConnection)conn;
+ if (e != null)
+ {
+ serverConnection.exception(e);
+ }
+ serverConnection.sendConnectionClose(ConnectionCloseCode.CONNECTION_FORCED, e == null ? "Authentication failed" : e.getMessage());
+ disposeSaslNegotiator();
+ }
+
+ private void disposeSaslNegotiator()
+ {
+ _saslNegotiator.dispose();
+ _saslNegotiator = null;
+ }
}
Modified: qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSession.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSession.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSession.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-0-10-protocol/src/main/java/org/apache/qpid/server/protocol/v0_10/ServerSession.java Fri Dec 2 15:47:52 2016
@@ -107,6 +107,7 @@ import org.apache.qpid.transport.Message
import org.apache.qpid.transport.MessageStop;
import org.apache.qpid.transport.MessageTransfer;
import org.apache.qpid.transport.Method;
+import org.apache.qpid.transport.Option;
import org.apache.qpid.transport.Range;
import org.apache.qpid.transport.RangeSet;
import org.apache.qpid.transport.RangeSetFactory;
@@ -1257,6 +1258,12 @@ public class ServerSession extends Sessi
return getId().compareTo(o.getId());
}
+ @Override
+ protected void sendSessionAttached(final byte[] name, final Option... options)
+ {
+ super.sendSessionAttached(name, options);
+ }
+
private class CheckCapacityAction implements Action<MessageInstance>
{
@Override
Modified: qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Impl.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Impl.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Impl.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/main/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Impl.java Fri Dec 2 15:47:52 2016
@@ -24,11 +24,8 @@ import java.io.IOException;
import java.lang.reflect.InvocationHandler;
import java.lang.reflect.Method;
import java.lang.reflect.Proxy;
-import java.net.InetSocketAddress;
-import java.net.SocketAddress;
import java.security.AccessControlException;
import java.security.AccessController;
-import java.security.Principal;
import java.security.PrivilegedAction;
import java.util.Collection;
import java.util.Collections;
@@ -44,9 +41,6 @@ import java.util.concurrent.atomic.Atomi
import java.util.concurrent.atomic.AtomicReference;
import java.util.regex.Pattern;
-import javax.security.sasl.SaslException;
-import javax.security.sasl.SaslServer;
-
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -73,6 +67,7 @@ import org.apache.qpid.server.protocol.A
import org.apache.qpid.server.protocol.ConnectionClosingTicker;
import org.apache.qpid.server.security.SubjectCreator;
import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
+import org.apache.qpid.server.security.auth.sasl.SaslNegotiator;
import org.apache.qpid.server.store.StoreException;
import org.apache.qpid.server.transport.AbstractAMQPConnection;
import org.apache.qpid.server.transport.AggregateTicker;
@@ -122,7 +117,7 @@ public class AMQPConnection_0_8Impl
private final ServerDecoder _decoder;
- private volatile SaslServer _saslServer;
+ private volatile SaslNegotiator _saslNegotiator;
private volatile long _maxNoOfChannels;
@@ -583,29 +578,6 @@ public class AMQPConnection_0_8Impl
getNetwork().close();
}
- private String getLocalFQDN()
- {
- SocketAddress address = getNetwork().getLocalAddress();
- if (address instanceof InetSocketAddress)
- {
- return ((InetSocketAddress) address).getHostName();
- }
- else
- {
- throw new IllegalArgumentException("Unsupported socket address class: " + address);
- }
- }
-
- private SaslServer getSaslServer()
- {
- return _saslServer;
- }
-
- private void setSaslServer(SaslServer saslServer)
- {
- _saslServer = saslServer;
- }
-
public boolean isSendQueueDeleteOkRegardless()
{
return _sendQueueDeleteOkRegardless;
@@ -691,11 +663,6 @@ public class AMQPConnection_0_8Impl
return _protocolOutputConverter;
}
- public Principal getPeerPrincipal()
- {
- return getNetwork().getPeerPrincipal();
- }
-
public MethodRegistry getMethodRegistry()
{
return _methodRegistry;
@@ -1080,33 +1047,14 @@ public class AMQPConnection_0_8Impl
assertState(ConnectionState.AWAIT_SECURE_OK);
- SubjectCreator subjectCreator = getSubjectCreator();
-
- SaslServer ss = getSaslServer();
- if (ss == null)
- {
- sendConnectionClose(ErrorCodes.INTERNAL_ERROR, "No SASL context set up in connection", 0);
- }
-
- processSaslResponse(response, subjectCreator, ss);
+ processSaslResponse(response, getSubjectCreator());
}
- private void disposeSaslServer()
+ private void disposeSaslNegotiator()
{
- SaslServer ss = getSaslServer();
- if (ss != null)
- {
- setSaslServer(null);
- try
- {
- ss.dispose();
- }
- catch (SaslException e)
- {
- _logger.error("Error disposing of Sasl server: " + e);
- }
- }
+ _saslNegotiator.dispose();
+ _saslNegotiator = null;
}
@Override
@@ -1132,46 +1080,33 @@ public class AMQPConnection_0_8Impl
_logger.debug("SASL Mechanism selected: {} Locale : {}", mechanism, locale);
- SubjectCreator subjectCreator = getSubjectCreator();
- SaslServer ss;
- try
+ if (mechanism == null || mechanism.length() == 0)
{
- ss = subjectCreator.createSaslServer(String.valueOf(mechanism),
- getLocalFQDN(),
- getPeerPrincipal());
-
- if (ss == null)
- {
- sendConnectionClose(ErrorCodes.RESOURCE_ERROR, "Unable to create SASL Server:" + mechanism, 0);
-
- }
- else
- {
- //save clientProperties
- setClientProperties(clientProperties);
-
- setSaslServer(ss);
+ sendConnectionClose(ErrorCodes.CONNECTION_FORCED, "No Sasl mechanism was specified", 0);
+ return;
+ }
- processSaslResponse(response, subjectCreator, ss);
- }
+ SubjectCreator subjectCreator = getSubjectCreator();
+ _saslNegotiator = subjectCreator.createSaslNegotiator(String.valueOf(mechanism), this);
+ if (_saslNegotiator == null)
+ {
+ sendConnectionClose(ErrorCodes.CONNECTION_FORCED, "No SaslServer could be created for mechanism: " + mechanism, 0);
}
- catch (SaslException e)
+ else
{
- disposeSaslServer();
- sendConnectionClose(ErrorCodes.INTERNAL_ERROR, "SASL error: " + e, 0);
+ setClientProperties(clientProperties);
+ processSaslResponse(response, subjectCreator);
}
}
- private void processSaslResponse(final byte[] response,
- final SubjectCreator subjectCreator,
- final SaslServer ss)
+ private void processSaslResponse(final byte[] response, final SubjectCreator subjectCreator)
{
MethodRegistry methodRegistry = getMethodRegistry();
SubjectAuthenticationResult authResult = _successfulAuthenticationResult;
byte[] challenge = null;
if (authResult == null)
{
- authResult = subjectCreator.authenticate(ss, response);
+ authResult = subjectCreator.authenticate(_saslNegotiator, response);
challenge = authResult.getChallenge();
}
@@ -1184,7 +1119,7 @@ public class AMQPConnection_0_8Impl
sendConnectionClose(ErrorCodes.NOT_ALLOWED, "Authentication failed", 0);
- disposeSaslServer();
+ disposeSaslNegotiator();
break;
case SUCCESS:
@@ -1209,7 +1144,7 @@ public class AMQPConnection_0_8Impl
broker.getConnection_heartBeatDelay());
writeFrame(tuneBody.generateFrame(0));
_state = ConnectionState.AWAIT_TUNE_OK;
- disposeSaslServer();
+ disposeSaslNegotiator();
}
else
{
Modified: qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Test.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Test.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Test.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-0-8-protocol/src/test/java/org/apache/qpid/server/protocol/v0_8/AMQPConnection_0_8Test.java Fri Dec 2 15:47:52 2016
@@ -29,7 +29,6 @@ import java.net.InetSocketAddress;
import java.util.Collections;
import javax.security.auth.Subject;
-import javax.security.sasl.SaslServer;
import org.apache.qpid.framing.AMQShortString;
import org.apache.qpid.framing.FieldTable;
@@ -56,6 +55,8 @@ import org.apache.qpid.server.security.a
import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
import org.apache.qpid.server.security.auth.UsernamePrincipal;
+import org.apache.qpid.server.security.auth.sasl.SaslNegotiator;
+import org.apache.qpid.server.security.auth.sasl.SaslSettings;
import org.apache.qpid.server.transport.AMQPConnection;
import org.apache.qpid.server.transport.AggregateTicker;
import org.apache.qpid.server.transport.ServerNetworkConnection;
@@ -131,11 +132,10 @@ public class AMQPConnection_0_8Test exte
SubjectCreator subjectCreator = mock(SubjectCreator.class);
when(subjectCreator.getMechanisms()).thenReturn(Collections.singletonList(SASL_MECH.toString()));
- SaslServer saslServer = mock(SaslServer.class);
- when(subjectCreator.createSaslServer(SASL_MECH.toString(),
- "localhost",
- null)).thenReturn(saslServer);
- when(subjectCreator.authenticate(saslServer, SASL_RESPONSE)).thenReturn(new SubjectAuthenticationResult(
+
+ SaslNegotiator saslNegotiator = mock(SaslNegotiator.class);
+ when(subjectCreator.createSaslNegotiator(eq(SASL_MECH.toString()), any(SaslSettings.class))).thenReturn(saslNegotiator);
+ when(subjectCreator.authenticate(saslNegotiator, SASL_RESPONSE)).thenReturn(new SubjectAuthenticationResult(
new AuthenticationResult(new AuthenticatedPrincipal(new UsernamePrincipal("username", null))), new Subject()));
AuthenticationProvider authenticationProvider = mock(AuthenticationProvider.class);
Modified: qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/AMQPConnection_1_0.java Fri Dec 2 15:47:52 2016
@@ -103,6 +103,7 @@ import org.apache.qpid.server.security.a
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.ExternalAuthenticationManagerImpl;
+import org.apache.qpid.server.security.auth.sasl.SaslNegotiator;
import org.apache.qpid.server.store.StoreException;
import org.apache.qpid.server.transport.AbstractAMQPConnection;
import org.apache.qpid.server.transport.AggregateTicker;
@@ -211,10 +212,9 @@ public class AMQPConnection_1_0 extends
private Map _properties;
- private SaslServerProvider _saslServerProvider;
private boolean _saslComplete;
- private SaslServer _saslServer;
+ private SaslNegotiator _saslNegotiator;
private String _localHostname;
private long _desiredIdleTimeout;
@@ -244,14 +244,12 @@ public class AMQPConnection_1_0 extends
AmqpPort<?> port,
Transport transport,
long id,
- final AggregateTicker aggregateTicker,
- final boolean useSASL)
+ final AggregateTicker aggregateTicker)
{
super(broker, network, port, transport, Protocol.AMQP_1_0, id, aggregateTicker);
_subjectCreator = port.getAuthenticationProvider().getSubjectCreator(transport.isSecure());
- _saslServerProvider = useSASL ? asSaslServerProvider(_subjectCreator, network) : null;
_port = port;
Map<Symbol, Object> serverProperties = new LinkedHashMap<>();
@@ -322,11 +320,18 @@ public class AMQPConnection_1_0 extends
private void closeSaslWithFailure()
{
_saslComplete = true;
+ disposeSaslNegotiator();
_frameReceivingState = FrameReceivingState.CLOSED;
setClosedForInput(true);
addCloseTicker();
}
+ private void disposeSaslNegotiator()
+ {
+ _saslNegotiator.dispose();
+ _saslNegotiator = null;
+ }
+
public void receiveSaslChallenge(final SaslChallenge saslChallenge)
{
LOGGER.info("{} : Unexpected frame sasl-challenge", getLogSubject());
@@ -905,16 +910,8 @@ public class AMQPConnection_1_0 extends
final Binary initialResponse = saslInit.getInitialResponse();
byte[] response = initialResponse == null ? new byte[0] : initialResponse.getArray();
-
- try
- {
- _saslServer = _saslServerProvider.getSaslServer(mechanism, "localhost");
- processSaslResponse(response);
- }
- catch (SaslException e)
- {
- handleSaslError();
- }
+ _saslNegotiator = _subjectCreator.createSaslNegotiator(mechanism, this);
+ processSaslResponse(response);
}
private void processSaslResponse(final byte[] response)
@@ -923,7 +920,7 @@ public class AMQPConnection_1_0 extends
SubjectAuthenticationResult authenticationResult = _successfulAuthenticationResult;
if (authenticationResult == null)
{
- authenticationResult = _subjectCreator.authenticate(_saslServer, response != null ? response : new byte[0]);
+ authenticationResult = _subjectCreator.authenticate(_saslNegotiator, response != null ? response : new byte[0]);
challenge = authenticationResult.getChallenge();
}
@@ -938,6 +935,7 @@ public class AMQPConnection_1_0 extends
send(new SASLFrame(outcome), null);
_saslComplete = true;
_frameReceivingState = FrameReceivingState.AMQP_HEADER;
+ disposeSaslNegotiator();
}
else
{
@@ -1110,19 +1108,6 @@ public class AMQPConnection_1_0 extends
{
}
- private static SaslServerProvider asSaslServerProvider(final SubjectCreator subjectCreator,
- final ServerNetworkConnection network)
- {
- return new SaslServerProvider()
- {
- @Override
- public SaslServer getSaslServer(String mechanism, String fqdn) throws SaslException
- {
- return subjectCreator.createSaslServer(mechanism, fqdn, network.getPeerPrincipal());
- }
- };
- }
-
public String getAddress()
{
return getNetwork().getRemoteAddress().toString();
Modified: qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngineCreator_1_0_0.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngineCreator_1_0_0.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngineCreator_1_0_0.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngineCreator_1_0_0.java Fri Dec 2 15:47:52 2016
@@ -90,7 +90,7 @@ public class ProtocolEngineCreator_1_0_0
|| (supportedMechanisms.contains(ExternalAuthenticationManagerImpl.MECHANISM_NAME) && network.getPeerPrincipal() != null))
{
final AMQPConnection_1_0 amqpConnection_1_0 =
- new AMQPConnection_1_0(broker, network, port, transport, id, aggregateTicker, false);
+ new AMQPConnection_1_0(broker, network, port, transport, id, aggregateTicker);
amqpConnection_1_0.create();
return amqpConnection_1_0;
}
Modified: qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngineCreator_1_0_0_SASL.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngineCreator_1_0_0_SASL.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngineCreator_1_0_0_SASL.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/main/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngineCreator_1_0_0_SASL.java Fri Dec 2 15:47:52 2016
@@ -66,7 +66,7 @@ public class ProtocolEngineCreator_1_0_0
long id, final AggregateTicker aggregateTicker)
{
final AMQPConnection_1_0 amqpConnection_1_0 =
- new AMQPConnection_1_0(broker, network, port, transport, id, aggregateTicker, true);
+ new AMQPConnection_1_0(broker, network, port, transport, id, aggregateTicker);
amqpConnection_1_0.create();
return amqpConnection_1_0;
}
Modified: qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngine_1_0_0Test.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngine_1_0_0Test.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngine_1_0_0Test.java (original)
+++ qpid/java/trunk/broker-plugins/amqp-1-0-protocol/src/test/java/org/apache/qpid/server/protocol/v1_0/ProtocolEngine_1_0_0Test.java Fri Dec 2 15:47:52 2016
@@ -29,6 +29,8 @@ import static org.mockito.Mockito.never;
import static org.mockito.Mockito.verify;
import static org.mockito.Mockito.when;
+import java.net.InetSocketAddress;
+import java.net.SocketAddress;
import java.nio.ByteBuffer;
import java.security.Principal;
import java.util.ArrayList;
@@ -94,6 +96,7 @@ public class ProtocolEngine_1_0_0Test ex
{
super.setUp();
_networkConnection = mock(ServerNetworkConnection.class);
+ when(_networkConnection.getLocalAddress()).thenReturn(new InetSocketAddress(0));
_broker = mock(Broker.class);
when(_broker.getModel()).thenReturn(BrokerModel.getInstance());
final TaskExecutor taskExecutor = new TaskExecutorImpl();
@@ -199,9 +202,8 @@ public class ProtocolEngine_1_0_0Test ex
(new AnonymousAuthenticationManagerFactory()).create(null, attrs, _broker);
when(_port.getAuthenticationProvider()).thenReturn(anonymousAuthenticationManager);
allowMechanisms(AnonymousAuthenticationManager.MECHANISM_NAME);
- final boolean useSASL = false;
- createEngine(useSASL, Transport.TCP);
+ createEngine(Transport.TCP);
_protocolEngine_1_0_0.received(QpidByteBuffer.wrap(ProtocolEngineCreator_1_0_0.getInstance()
.getHeaderIdentifier()));
@@ -219,9 +221,8 @@ public class ProtocolEngine_1_0_0Test ex
public void testProtocolEngineWithNoSaslNonTLSandNoAnon() throws Exception
{
allowMechanisms("foo");
- final boolean useSASL = false;
- createEngine(useSASL, Transport.TCP);
+ createEngine(Transport.TCP);
_protocolEngine_1_0_0.received(QpidByteBuffer.wrap(ProtocolEngineCreator_1_0_0.getInstance().getHeaderIdentifier()));
@@ -246,9 +247,8 @@ public class ProtocolEngine_1_0_0Test ex
when(_networkConnection.getPeerPrincipal()).thenReturn(principal);
allowMechanisms(ExternalAuthenticationManagerImpl.MECHANISM_NAME);
- final boolean useSASL = false;
- createEngine(useSASL, Transport.SSL);
+ createEngine(Transport.SSL);
_protocolEngine_1_0_0.received(QpidByteBuffer.wrap(ProtocolEngineCreator_1_0_0.getInstance().getHeaderIdentifier()));
Open open = new Open();
@@ -267,9 +267,8 @@ public class ProtocolEngine_1_0_0Test ex
(new AnonymousAuthenticationManagerFactory()).create(null, attrs, _broker);
when(_port.getAuthenticationProvider()).thenReturn(anonymousAuthenticationManager);
allowMechanisms(AnonymousAuthenticationManager.MECHANISM_NAME);
- final boolean useSASL = true;
- createEngine(useSASL, Transport.TCP);
+ createEngine(Transport.TCP);
_protocolEngine_1_0_0.received(QpidByteBuffer.wrap(ProtocolEngineCreator_1_0_0_SASL.getInstance()
.getHeaderIdentifier()));
@@ -291,43 +290,14 @@ public class ProtocolEngine_1_0_0Test ex
}
- private void createEngine(final boolean useSASL, Transport transport)
+ private void createEngine(Transport transport)
{
- _protocolEngine_1_0_0 = new AMQPConnection_1_0(_broker, _networkConnection,
- _port, transport, 1, new AggregateTicker(),
- useSASL);
+ _protocolEngine_1_0_0 =
+ new AMQPConnection_1_0(_broker, _networkConnection, _port, transport, 1, new AggregateTicker());
}
private void allowMechanisms(String... mechanisms)
{
when(_subjectCreator.getMechanisms()).thenReturn(Arrays.asList(mechanisms));
}
-
- private final ByteBufferSender _sender = new ByteBufferSender()
- {
-
- @Override
- public boolean isDirectBufferPreferred()
- {
- return false;
- }
-
- @Override
- public void send(final QpidByteBuffer msg)
- {
- _protocolEngine_1_0_0.received(msg);
- }
-
- @Override
- public void flush()
- {
-
- }
-
- @Override
- public void close()
- {
-
- }
- };
}
Modified: qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java (original)
+++ qpid/java/trunk/broker-plugins/management-http/src/main/java/org/apache/qpid/server/management/plugin/servlet/rest/SaslServlet.java Fri Dec 2 15:47:52 2016
@@ -29,7 +29,6 @@ import java.util.Map;
import java.util.Random;
import javax.security.auth.Subject;
-import javax.security.sasl.SaslServer;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
@@ -46,6 +45,8 @@ import org.apache.qpid.server.security.S
import org.apache.qpid.server.security.auth.AuthenticatedPrincipal;
import org.apache.qpid.server.security.auth.AuthenticationResult;
import org.apache.qpid.server.security.auth.SubjectAuthenticationResult;
+import org.apache.qpid.server.security.auth.sasl.SaslNegotiator;
+import org.apache.qpid.server.security.auth.sasl.SaslSettings;
import org.apache.qpid.server.util.ConnectionScopedRuntimeException;
import org.apache.qpid.util.Strings;
@@ -58,7 +59,7 @@ public class SaslServlet extends Abstrac
private static final SecureRandom SECURE_RANDOM = new SecureRandom();
private static final String ATTR_RANDOM = "SaslServlet.Random";
private static final String ATTR_ID = "SaslServlet.ID";
- private static final String ATTR_SASL_SERVER = "SaslServlet.SaslServer";
+ private static final String ATTR_SASL_NEGOTIATOR = "SaslServlet.SaslNegotiator";
private static final String ATTR_EXPIRY = "SaslServlet.Expiry";
private static final long SASL_EXCHANGE_EXPIRY = 3000L;
@@ -132,16 +133,26 @@ public class SaslServlet extends Abstrac
{
LOGGER.debug("Creating SaslServer for mechanism: {}", mechanism);
- SaslServer saslServer = subjectCreator.createSaslServer(mechanism, request.getServerName(), null/*TODO*/);
- evaluateSaslResponse(request, response, session, saslResponse, saslServer, subjectCreator);
+ SaslNegotiator saslNegotiator = subjectCreator.createSaslNegotiator(mechanism, new SaslSettings()
+ {
+ @Override
+ public String getLocalFQDN()
+ {
+ return request.getServerName();
+ }
+
+ @Override
+ public Principal getExternalPrincipal()
+ {
+ return null/*TODO*/;
+ }
+ });
+ evaluateSaslResponse(request, response, session, saslResponse, saslNegotiator, subjectCreator);
}
else
{
+ cleanup(request, session);
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request));
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_SERVER,
- request));
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request));
}
}
else
@@ -152,28 +163,22 @@ public class SaslServlet extends Abstrac
request))) && System.currentTimeMillis() < (Long) session.getAttribute(
HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request)))
{
- SaslServer saslServer = (SaslServer) session.getAttribute(HttpManagementUtil.getRequestSpecificAttributeName(
- ATTR_SASL_SERVER,
- request));
- evaluateSaslResponse(request, response, session, saslResponse, saslServer, subjectCreator);
+ SaslNegotiator saslNegotiator =
+ (SaslNegotiator) session.getAttribute(HttpManagementUtil.getRequestSpecificAttributeName(
+ ATTR_SASL_NEGOTIATOR,
+ request));
+ evaluateSaslResponse(request, response, session, saslResponse, saslNegotiator, subjectCreator);
}
else
{
+ cleanup(request, session);
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request));
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_SERVER,
- request));
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY,
- request));
}
}
else
{
+ cleanup(request, session);
response.setStatus(HttpServletResponse.SC_EXPECTATION_FAILED);
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request));
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_SERVER,
- request));
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request));
}
}
}
@@ -186,6 +191,19 @@ public class SaslServlet extends Abstrac
}
}
+ private void cleanup(final HttpServletRequest request, final HttpSession session)
+ {
+ final SaslNegotiator negotiator =
+ (SaslNegotiator) session.getAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_NEGOTIATOR, request));
+ if (negotiator != null)
+ {
+ negotiator.dispose();
+ }
+ session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request));
+ session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_NEGOTIATOR, request));
+ session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request));
+ }
+
private void checkSaslAuthEnabled(HttpServletRequest request)
{
boolean saslAuthEnabled = false;
@@ -206,15 +224,18 @@ public class SaslServlet extends Abstrac
private void evaluateSaslResponse(final HttpServletRequest request,
final HttpServletResponse response,
- final HttpSession session, final String saslResponse, final SaslServer saslServer, SubjectCreator subjectCreator) throws IOException
+ final HttpSession session,
+ final String saslResponse,
+ final SaslNegotiator saslNegotiator,
+ SubjectCreator subjectCreator) throws IOException
{
byte[] saslResponseBytes = saslResponse == null
? new byte[0]
: Strings.decodeBase64(saslResponse);
- SubjectAuthenticationResult authenticationResult = subjectCreator.authenticate(saslServer, saslResponseBytes);
+ SubjectAuthenticationResult authenticationResult = subjectCreator.authenticate(saslNegotiator, saslResponseBytes);
byte[] challenge = authenticationResult.getChallenge();
Map<String, Object> outputObject = new LinkedHashMap<>();
- int responseStatus;
+ int responseStatus = HttpServletResponse.SC_INTERNAL_SERVER_ERROR;
if (authenticationResult.getStatus() == AuthenticationResult.AuthenticationStatus.SUCCESS)
{
@@ -226,9 +247,6 @@ public class SaslServlet extends Abstrac
Subject subject = HttpManagementUtil.createServletConnectionSubject(request, original);
HttpManagementUtil.saveAuthorisedSubject(request, subject);
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request));
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_SERVER, request));
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request));
if(challenge != null && challenge.length != 0)
{
outputObject.put("challenge", DatatypeConverter.printBase64Binary(challenge));
@@ -239,13 +257,17 @@ public class SaslServlet extends Abstrac
{
responseStatus = HttpServletResponse.SC_FORBIDDEN;
}
+ finally
+ {
+ cleanup(request, session);
+ }
}
else if (authenticationResult.getStatus() == AuthenticationResult.AuthenticationStatus.CONTINUE)
{
Random rand = getRandom(request);
String id = String.valueOf(rand.nextLong());
session.setAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request), id);
- session.setAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_SERVER, request), saslServer);
+ session.setAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_NEGOTIATOR, request), saslNegotiator);
session.setAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request), System.currentTimeMillis() + SASL_EXCHANGE_EXPIRY);
outputObject.put("id", id);
@@ -254,10 +276,8 @@ public class SaslServlet extends Abstrac
}
else
{
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_ID, request));
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_SASL_SERVER, request));
- session.removeAttribute(HttpManagementUtil.getRequestSpecificAttributeName(ATTR_EXPIRY, request));
responseStatus = HttpServletResponse.SC_UNAUTHORIZED;
+ cleanup(request, session);
}
sendJsonResponse(outputObject, request, response, responseStatus, false);
Modified: qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/Connection.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/Connection.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/Connection.java (original)
+++ qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/Connection.java Fri Dec 2 15:47:52 2016
@@ -166,7 +166,7 @@ public class Connection extends Connecti
}
}
- void setLocale(String locale)
+ protected void setLocale(String locale)
{
this.locale = locale;
}
@@ -466,7 +466,7 @@ public class Connection extends Connecti
return channelMax;
}
- void setChannelMax(int max)
+ protected void setChannelMax(int max)
{
channelMax = max;
}
@@ -489,7 +489,7 @@ public class Connection extends Connecti
}
}
- void map(Session ssn, int channel)
+ protected void map(Session ssn, int channel)
{
synchronized (lock)
{
@@ -875,4 +875,21 @@ public class Connection extends Connecti
}
}
+ protected void sendConnectionSecure(byte[] challenge, Option ... options)
+ {
+ super.connectionSecure(challenge, options);
+ }
+
+ protected void sendConnectionTune(int channelMax, int maxFrameSize, int heartbeatMin, int heartbeatMax, Option ... options)
+ {
+ super.connectionTune(channelMax, maxFrameSize, heartbeatMin, heartbeatMax, options);
+ }
+
+ protected void sendConnectionStart(final Map<String, Object> clientProperties,
+ final List<Object> mechanisms,
+ final List<Object> locales, final Option... options)
+ {
+ super.connectionStart(clientProperties, mechanisms, locales, options);
+ }
+
}
Modified: qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/Session.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/Session.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/Session.java (original)
+++ qpid/java/trunk/common/src/main/java/org/apache/qpid/transport/Session.java Fri Dec 2 15:47:52 2016
@@ -1198,4 +1198,9 @@ public class Session extends SessionInvo
{
return flowControl && credit.availablePermits() == 0;
}
+
+ protected void sendSessionAttached(final byte[] name, final Option... options)
+ {
+ super.sessionAttached(name, options);
+ }
}
Modified: qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/SaslRestTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/SaslRestTest.java?rev=1772364&r1=1772363&r2=1772364&view=diff
==============================================================================
--- qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/SaslRestTest.java (original)
+++ qpid/java/trunk/systests/src/test/java/org/apache/qpid/systest/rest/SaslRestTest.java Fri Dec 2 15:47:52 2016
@@ -21,6 +21,7 @@
package org.apache.qpid.systest.rest;
import static org.apache.qpid.server.security.auth.sasl.SaslUtil.generateCramMD5ClientResponse;
+import static org.apache.qpid.server.security.auth.sasl.SaslUtil.generateCramMD5HashedClientResponse;
import static org.apache.qpid.server.security.auth.sasl.SaslUtil.generateCramMD5HexClientResponse;
import static org.apache.qpid.server.security.auth.sasl.SaslUtil.generatePlainClientResponse;
@@ -291,6 +292,45 @@ public class SaslRestTest extends QpidRe
assertEquals("Unexpected response", HttpServletResponse.SC_EXPECTATION_FAILED, responseCode);
}
+ public void testCramMD5HashedSaslAuthenticationForValidCredentials() throws Exception
+ {
+ configureBase64MD5FilePrincipalDatabase();
+ startBrokerNow();
+
+ // request the challenge for CRAM-MD5-HASHED
+ HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5-HASHED");
+ List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
+
+ // authenticate user with correct credentials
+ int code = authenticateUser(connection, "admin", "admin", "CRAM-MD5-HASHED");
+ assertEquals("Unexpected response code", 200, code);
+
+ // request authenticated user details
+ connection = getRestTestHelper().openManagementConnection("/service/sasl", "GET");
+ applyCookiesToConnection(cookies, connection);
+ Map<String, Object> response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+ assertEquals("Unexpected user", "admin", response2.get("user"));
+ }
+
+ public void testCramMD5HashedSaslAuthenticationForInvalidPassword() throws Exception
+ {
+ configureBase64MD5FilePrincipalDatabase();
+ startBrokerNow();
+
+ HttpURLConnection connection = requestSasServerChallenge("CRAM-MD5-HASHED");
+ List<String> cookies = connection.getHeaderFields().get("Set-Cookie");
+
+ // try to authenticate user with incorrect passowrd
+ int code = authenticateUser(connection, "admin", "incorrect", "CRAM-MD5-HASHED");
+ assertEquals("Unexpected response code", 401, code);
+
+ // request authenticated user details
+ connection = getRestTestHelper().openManagementConnection("/service/sasl", "GET");
+ applyCookiesToConnection(cookies, connection);
+ Map<String, Object> response2 = getRestTestHelper().readJsonResponseAsMap(connection);
+ assertNull("Unexpected user", response2.get("user"));
+ }
+
private HttpURLConnection requestSasServerChallenge(String mechanism) throws IOException
{
HttpURLConnection connection = getRestTestHelper().openManagementConnection("/service/sasl", "POST");
@@ -339,6 +379,10 @@ public class SaslRestTest extends QpidRe
{
responseBytes = generateCramMD5ClientResponse(userName, userPassword, challengeBytes);
}
+ else if ("CRAM-MD5-HASHED".equalsIgnoreCase(mechanism))
+ {
+ responseBytes = generateCramMD5HashedClientResponse(userName, userPassword, challengeBytes);
+ }
else
{
throw new RuntimeException("Not implemented test mechanism " + mechanism);
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org