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 2017/07/14 12:51:25 UTC
qpid-jms-amqp-0-x git commit: QPID-7292: [AMQP 0.x] Qpid clients
should verify the server-final message when using SCRAM-* authentication
Repository: qpid-jms-amqp-0-x
Updated Branches:
refs/heads/master aeb7377c8 -> 8e652dd7a
QPID-7292: [AMQP 0.x] Qpid clients should verify the server-final message when using SCRAM-* authentication
Project: http://git-wip-us.apache.org/repos/asf/qpid-jms-amqp-0-x/repo
Commit: http://git-wip-us.apache.org/repos/asf/qpid-jms-amqp-0-x/commit/8e652dd7
Tree: http://git-wip-us.apache.org/repos/asf/qpid-jms-amqp-0-x/tree/8e652dd7
Diff: http://git-wip-us.apache.org/repos/asf/qpid-jms-amqp-0-x/diff/8e652dd7
Branch: refs/heads/master
Commit: 8e652dd7aa8aaa23e38f6364bff45feab4a5ee8f
Parents: aeb7377
Author: Alex Rudyy <or...@apache.org>
Authored: Fri Jul 14 13:50:15 2017 +0100
Committer: Alex Rudyy <or...@apache.org>
Committed: Fri Jul 14 13:50:15 2017 +0100
----------------------------------------------------------------------
.../handler/ConnectionTuneMethodHandler.java | 35 +++++-
.../apache/qpid/transport/ClientDelegate.java | 38 ++++++-
.../ConnectionTuneMethodHandlerTest.java | 106 +++++++++++++++++++
3 files changed, 177 insertions(+), 2 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/qpid-jms-amqp-0-x/blob/8e652dd7/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java b/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java
index 1f2df20..6094495 100644
--- a/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java
+++ b/client/src/main/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandler.java
@@ -20,9 +20,13 @@
*/
package org.apache.qpid.client.handler;
+import javax.security.sasl.SaslClient;
+import javax.security.sasl.SaslException;
+
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import org.apache.qpid.QpidException;
import org.apache.qpid.client.ConnectionTuneParameters;
import org.apache.qpid.client.protocol.AMQProtocolSession;
import org.apache.qpid.client.state.AMQState;
@@ -47,9 +51,12 @@ public class ConnectionTuneMethodHandler implements StateAwareMethodListener<Con
protected ConnectionTuneMethodHandler()
{ }
- public void methodReceived(AMQProtocolSession session, ConnectionTuneBody frame, int channelId)
+ public void methodReceived(AMQProtocolSession session, ConnectionTuneBody frame, int channelId) throws QpidException
{
_logger.debug("ConnectionTune frame received");
+
+ verifySaslNegotiationComplete(session);
+
final MethodRegistry methodRegistry = session.getMethodRegistry();
ConnectionTuneParameters params = session.getConnectionTuneParameters();
@@ -86,5 +93,31 @@ public class ConnectionTuneMethodHandler implements StateAwareMethodListener<Con
session.writeFrame(openBody.generateFrame(channelId));
}
+ private void verifySaslNegotiationComplete(final AMQProtocolSession session) throws QpidException
+ {
+ SaslClient client = session.getSaslClient();
+ if (client == null)
+ {
+ throw new QpidException("No SASL client set up - cannot proceed with connection open");
+ }
+
+ if (!client.isComplete())
+ {
+ throw new QpidException("SASL negotiation has not been completed - cannot proceed with connection open");
+ }
+ String mechanismName = client.getMechanismName();
+ try
+ {
+ client.dispose();
+ }
+ catch (SaslException e)
+ {
+ _logger.warn("Disposal of client sasl for mechanism '{}' has failed", mechanismName, e);
+ }
+ finally
+ {
+ session.setSaslClient(null);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/qpid-jms-amqp-0-x/blob/8e652dd7/client/src/main/java/org/apache/qpid/transport/ClientDelegate.java
----------------------------------------------------------------------
diff --git a/client/src/main/java/org/apache/qpid/transport/ClientDelegate.java b/client/src/main/java/org/apache/qpid/transport/ClientDelegate.java
index ea05408..b6852b1 100644
--- a/client/src/main/java/org/apache/qpid/transport/ClientDelegate.java
+++ b/client/src/main/java/org/apache/qpid/transport/ClientDelegate.java
@@ -30,11 +30,11 @@ import java.util.Map;
import javax.security.sasl.SaslClient;
import javax.security.sasl.SaslException;
-import org.apache.qpid.configuration.CommonProperties;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.qpid.configuration.ClientProperties;
+import org.apache.qpid.configuration.CommonProperties;
import org.apache.qpid.properties.ConnectionStartProperties;
@@ -134,6 +134,16 @@ public class ClientDelegate extends ConnectionDelegate
@Override
public void connectionTune(Connection conn, ConnectionTune tune)
{
+ try
+ {
+ verifySaslNegotiationComplete(conn);
+ }
+ catch (SaslException e)
+ {
+ conn.exception(e);
+ return;
+ }
+
int heartbeatInterval = _connectionSettings.getHeartbeatInterval010();
float heartbeatTimeoutFactor = _connectionSettings.getHeartbeatTimeoutFactor();
int actualHeartbeatInterval = calculateHeartbeatInterval(heartbeatInterval,
@@ -225,4 +235,30 @@ public class ClientDelegate extends ConnectionDelegate
{
return _connectionSettings;
}
+
+ private void verifySaslNegotiationComplete(Connection connection) throws SaslException
+ {
+ SaslClient client = connection.getSaslClient();
+ if (client != null)
+ {
+ if (!client.isComplete())
+ {
+ throw new SaslException("SASL negotiation has not been completed - cannot proceed with connection open");
+ }
+
+ String mechanismName = client.getMechanismName();
+ try
+ {
+ client.dispose();
+ }
+ catch (SaslException e)
+ {
+ LOGGER.warn("Disposal of client sasl for mechanism '{}' has failed", mechanismName, e);
+ }
+ finally
+ {
+ connection.setSaslClient(null);
+ }
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/qpid-jms-amqp-0-x/blob/8e652dd7/client/src/test/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandlerTest.java
----------------------------------------------------------------------
diff --git a/client/src/test/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandlerTest.java b/client/src/test/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandlerTest.java
new file mode 100644
index 0000000..f42a3e1
--- /dev/null
+++ b/client/src/test/java/org/apache/qpid/client/handler/ConnectionTuneMethodHandlerTest.java
@@ -0,0 +1,106 @@
+/*
+ *
+ * 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.client.handler;
+
+import static org.mockito.Mockito.mock;
+import static org.mockito.Mockito.times;
+import static org.mockito.Mockito.verify;
+import static org.mockito.Mockito.when;
+
+import javax.security.sasl.SaslClient;
+
+import org.apache.qpid.QpidException;
+import org.apache.qpid.client.AMQConnection;
+import org.apache.qpid.client.ConnectionTuneParameters;
+import org.apache.qpid.client.MockAMQConnection;
+import org.apache.qpid.client.protocol.AMQProtocolSession;
+import org.apache.qpid.client.state.AMQState;
+import org.apache.qpid.client.state.AMQStateManager;
+import org.apache.qpid.framing.ConnectionTuneBody;
+import org.apache.qpid.framing.MethodRegistry;
+import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.test.utils.QpidTestCase;
+
+public class ConnectionTuneMethodHandlerTest extends QpidTestCase
+{
+ private static final int CHANNEL_ID = 0;
+ private AMQProtocolSession _amqProtocolSession;
+ private ConnectionTuneBody _body;
+
+ @Override
+ public void setUp() throws Exception
+ {
+ super.setUp();
+ _amqProtocolSession = mock(AMQProtocolSession.class);
+ _body = mock(ConnectionTuneBody.class);
+ }
+
+ public void testMethodReceived_SaslClientIsNotFound() throws Exception
+ {
+ ConnectionTuneMethodHandler handler = ConnectionTuneMethodHandler.getInstance();
+ try
+ {
+ handler.methodReceived(_amqProtocolSession, _body, CHANNEL_ID);
+ fail("Exception is not thrown");
+ }
+ catch (QpidException e)
+ {
+ // pass
+ }
+ }
+
+ public void testMethodReceived_SaslNegotiationIsNotComplete() throws Exception
+ {
+ ConnectionTuneMethodHandler handler = ConnectionTuneMethodHandler.getInstance();
+ try
+ {
+ final SaslClient saslClient = mock(SaslClient.class);
+ when(saslClient.isComplete()).thenReturn(false);
+ when(_amqProtocolSession.getSaslClient()).thenReturn(saslClient);
+ handler.methodReceived(_amqProtocolSession, _body, CHANNEL_ID);
+ fail("Exception is not thrown");
+ }
+ catch (QpidException e)
+ {
+ // pass
+ }
+ }
+
+ public void testMethodReceived_SaslNegotiationIsComplete() throws Exception
+ {
+ ConnectionTuneMethodHandler handler = ConnectionTuneMethodHandler.getInstance();
+ final SaslClient saslClient = mock(SaslClient.class);
+ when(saslClient.isComplete()).thenReturn(true);
+ final AMQStateManager stateManager = mock(AMQStateManager.class);
+ ConnectionTuneParameters parameters = new ConnectionTuneParameters();
+ final AMQConnection connection = new MockAMQConnection("loaclhost", "test", "test", "client", "virtualhost");
+ final MethodRegistry methodRegistry = new MethodRegistry(ProtocolVersion.getLatestSupportedVersion());
+ when(_amqProtocolSession.getSaslClient()).thenReturn(saslClient);
+ when(_amqProtocolSession.getStateManager()).thenReturn(stateManager);
+ when(_amqProtocolSession.getMethodRegistry()).thenReturn(methodRegistry);
+ when(_amqProtocolSession.getConnectionTuneParameters()).thenReturn(parameters);
+ when(_amqProtocolSession.getAMQConnection()).thenReturn(connection);
+
+ handler.methodReceived(_amqProtocolSession, _body, CHANNEL_ID);
+ verify(stateManager, times(1)).changeState(AMQState.CONNECTION_NOT_OPENED);
+ verify(saslClient, times(1)).isComplete();
+ }
+}
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org