qpid-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From oru...@apache.org
Subject svn commit: r1747415 - in /qpid/java/trunk: systests/src/test/java/org/apache/qpid/transport/ test-profiles/
Date Wed, 08 Jun 2016 16:11:21 GMT
Author: orudyy
Date: Wed Jun  8 16:11:21 2016
New Revision: 1747415

URL: http://svn.apache.org/viewvc?rev=1747415&view=rev
Log:
NO-JIRA: Add system test for connection authentication bypass

Added:
    qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/ConnectionEstablishmentTest.java
    qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/TestSender.java
Modified:
    qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/MaxFrameSizeTest.java
    qpid/java/trunk/test-profiles/CPPExcludes

Added: qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/ConnectionEstablishmentTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/ConnectionEstablishmentTest.java?rev=1747415&view=auto
==============================================================================
--- qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/ConnectionEstablishmentTest.java
(added)
+++ qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/ConnectionEstablishmentTest.java
Wed Jun  8 16:11:21 2016
@@ -0,0 +1,322 @@
+/*
+ *
+ * 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.transport;
+
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.Socket;
+import java.net.SocketTimeoutException;
+import java.nio.ByteBuffer;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+import javax.jms.Connection;
+import javax.jms.Destination;
+import javax.jms.Message;
+import javax.jms.MessageConsumer;
+import javax.jms.Session;
+
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
+
+import org.apache.qpid.client.BrokerDetails;
+import org.apache.qpid.codec.ClientDecoder;
+import org.apache.qpid.configuration.ClientProperties;
+import org.apache.qpid.framing.AMQDataBlock;
+import org.apache.qpid.framing.AMQFrame;
+import org.apache.qpid.framing.AMQFrameDecodingException;
+import org.apache.qpid.framing.AMQMethodBodyImpl;
+import org.apache.qpid.framing.AMQShortString;
+import org.apache.qpid.framing.ChannelOpenBody;
+import org.apache.qpid.framing.ConnectionCloseBody;
+import org.apache.qpid.framing.ConnectionOpenBody;
+import org.apache.qpid.framing.ConnectionStartBody;
+import org.apache.qpid.framing.FrameCreatingMethodProcessor;
+import org.apache.qpid.framing.ProtocolVersion;
+import org.apache.qpid.framing.QueueDeleteBody;
+import org.apache.qpid.jms.ConnectionURL;
+import org.apache.qpid.server.model.Protocol;
+import org.apache.qpid.server.protocol.v0_8.ProtocolEngineCreator_0_8;
+import org.apache.qpid.server.protocol.v0_8.ProtocolEngineCreator_0_9;
+import org.apache.qpid.server.protocol.v0_8.ProtocolEngineCreator_0_9_1;
+import org.apache.qpid.test.utils.QpidBrokerTestCase;
+import org.apache.qpid.test.utils.TestBrokerConfiguration;
+import org.apache.qpid.transport.network.Assembler;
+import org.apache.qpid.transport.network.Disassembler;
+import org.apache.qpid.transport.network.InputHandler;
+
+public class ConnectionEstablishmentTest extends QpidBrokerTestCase
+{
+    private static final Logger LOGGER = LoggerFactory.getLogger(ConnectionEstablishmentTest.class);
+    private static final int NUMBER_OF_MESSAGES = 2;
+    private Connection _utilityConnection;
+    private Destination _testQueue;
+
+    @Override
+    protected void setUp() throws Exception
+    {
+        super.setUp();
+        _utilityConnection = getConnection();
+        Session session = _utilityConnection.createSession(false, Session.SESSION_TRANSACTED);
+        _testQueue = getTestQueue();
+        session.createConsumer(_testQueue).close();
+        sendMessage(session, _testQueue, NUMBER_OF_MESSAGES);
+        session.close();
+    }
+
+    public void testAuthenticationBypass() throws Exception
+    {
+        String virtualHost = TestBrokerConfiguration.ENTRY_NAME_VIRTUAL_HOST;
+        ConnectionURL connectionURL = getConnectionFactory().getConnectionURL();
+        BrokerDetails brokerDetails = connectionURL.getAllBrokerDetails().get(0);
+        try (Socket socket = new Socket(brokerDetails.getHost(), brokerDetails.getPort());
+             OutputStream os = socket.getOutputStream())
+        {
+            socket.setTcpNoDelay(true);
+            socket.setSoTimeout(5000);
+            openConnectionBypassingAuthenticationAndDeleteQueue(virtualHost, socket, os);
+        }
+
+        // verify that queue still exists
+        _utilityConnection.start();
+        setSystemProperty(ClientProperties.QPID_DECLARE_QUEUES_PROP_NAME, "false");
+        Session session = _utilityConnection.createSession(false, Session.AUTO_ACKNOWLEDGE);
+        MessageConsumer consumer = session.createConsumer(_testQueue);
+        Message message = consumer.receive(RECEIVE_TIMEOUT);
+        for (int i = 0; i < NUMBER_OF_MESSAGES; i++)
+        {
+            assertNotNull("Message [" + i + "] not received", message);
+        }
+    }
+
+    private void openConnectionBypassingAuthenticationAndDeleteQueue(final String virtualHost,
+                                                                     final Socket socket,
+                                                                     final OutputStream os)
+            throws Exception
+    {
+        if (isBroker010())
+        {
+            open010ConnectionBypassingAuthenticationAndDeleteQueue(socket, os, virtualHost);
+        }
+        else
+        {
+            openNon010ConnectionBypassingAuthenticationAndDeleteQueue(socket, os, virtualHost);
+        }
+    }
+
+    private void open010ConnectionBypassingAuthenticationAndDeleteQueue(Socket socket,
+                                                                        OutputStream os,
+                                                                        final String virtualHost)
+            throws IOException
+    {
+        TestSender sender = new TestSender(os);
+        Disassembler disassembler = new Disassembler(sender, Constant.MIN_MAX_FRAME_SIZE);
+        disassembler.send(new ProtocolHeader(1, 0, 10));
+        disassembler.send(new ConnectionOpen(virtualHost, null, Option.INSIST));
+        byte[] sessionName = "test".getBytes();
+        disassembler.send(new SessionAttach(sessionName));
+        disassembler.send(new SessionAttached(sessionName));
+        disassembler.send(new SessionRequestTimeout(0));
+        disassembler.send(new SessionCommandPoint(0, 0));
+        disassembler.send(new QueueDelete(getTestQueueName(), Option.SYNC));
+        disassembler.send(new SessionFlush());
+        disassembler.send(new ExecutionSync(Option.SYNC));
+        sender.flush();
+
+        TestEventReceiver receiver = new TestEventReceiver();
+        Assembler assembler = new Assembler(receiver);
+        InputHandler inputHandler = new InputHandler(assembler, false);
+        try (InputStream is = socket.getInputStream())
+        {
+            byte[] buffer = new byte[1024];
+            int size;
+            try
+            {
+                while ((size = is.read(buffer)) > 0)
+                {
+                    inputHandler.received(ByteBuffer.wrap(buffer, 0, size));
+                    if (receiver.isClosed() || receiver.getThrowable() != null || receiver.getEvents().size()
> 3)
+                    {
+                        // expected at most 3 events: Header, ConnectionStart, ConnectionClose
+                        break;
+                    }
+                }
+            }
+            catch (SocketTimeoutException e)
+            {
+                // ignore
+            }
+        }
+
+        boolean closeFound = receiver.isClosed() || receiver.getThrowable() != null;
+        for (ProtocolEvent event : receiver.getEvents())
+        {
+            if (event instanceof ConnectionClose)
+            {
+                closeFound = true;
+                break;
+            }
+        }
+
+        assertTrue("Unauthenticated connection was not closed", closeFound);
+    }
+
+    private void openNon010ConnectionBypassingAuthenticationAndDeleteQueue(final Socket socket,
+                                                                           final OutputStream
os,
+                                                                           final String virtualHost)
+            throws IOException, AMQFrameDecodingException
+    {
+
+        byte[] protocolHeader = getProtocolHeaderBytes();
+        String versionName = getBrokerProtocol().name().substring(5);
+        if (versionName.equals("0_9_1"))
+        {
+            versionName = "0-91";
+        }
+        ProtocolVersion protocolVersion = ProtocolVersion.parse(versionName.replace('_',
'-'));
+
+        os.write(protocolHeader);
+        try (InputStream is = socket.getInputStream())
+        {
+            receiveFrameOfType(protocolVersion, is, ConnectionStartBody.class, 1);
+            TestSender sender = new TestSender(os);
+
+            new AMQFrame(0, new ConnectionOpenBody(AMQShortString.valueOf(virtualHost),
+                                                   AMQShortString.EMPTY_STRING,
+                                                   true)).writePayload(sender);
+            new AMQFrame(1, new ChannelOpenBody()).writePayload(sender);
+            new AMQFrame(1, new QueueDeleteBody(2,
+                                                AMQShortString.valueOf(getTestQueueName()),
+                                                false,
+                                                false,
+                                                true)).writePayload(sender);
+            sender.flush();
+
+            receiveFrameOfType(protocolVersion, is, ConnectionCloseBody.class, 1);
+        }
+    }
+
+    private byte[] getProtocolHeaderBytes()
+    {
+        byte[] protocolHeader;
+        Protocol protocol = getBrokerProtocol();
+        switch (protocol)
+        {
+            case AMQP_0_8:
+                protocolHeader = (ProtocolEngineCreator_0_8.getInstance().getHeaderIdentifier());
+                break;
+            case AMQP_0_9:
+                protocolHeader = (ProtocolEngineCreator_0_9.getInstance().getHeaderIdentifier());
+                break;
+            case AMQP_0_9_1:
+                protocolHeader = (ProtocolEngineCreator_0_9_1.getInstance().getHeaderIdentifier());
+                break;
+            default:
+                throw new RuntimeException("Unexpected Protocol Version: " + protocol);
+        }
+        return protocolHeader;
+    }
+
+    private void receiveFrameOfType(ProtocolVersion protocolVersion, InputStream is,
+                                    Class<? extends AMQMethodBodyImpl> expectedFrameClass,
+                                    int maxNumberOfExpectedFrames) throws IOException, AMQFrameDecodingException
+    {
+        final FrameCreatingMethodProcessor methodProcessor = new FrameCreatingMethodProcessor(protocolVersion);
+        ClientDecoder decoder = new ClientDecoder(methodProcessor);
+        byte[] buffer = new byte[1024];
+        int size;
+        while ((size = is.read(buffer)) > 0)
+        {
+
+            decoder.decodeBuffer(ByteBuffer.wrap(buffer, 0, size));
+
+            List<AMQDataBlock> responseData = methodProcessor.getProcessedMethods();
+            LOGGER.info("RECV:" + responseData);
+            if (containsFrame(responseData, expectedFrameClass) || responseData.size() >
maxNumberOfExpectedFrames)
+            {
+                break;
+            }
+        }
+
+        List<AMQDataBlock> processedMethods = methodProcessor.getProcessedMethods();
+        assertTrue("Expected frame  of type " + expectedFrameClass.getSimpleName() + " is
not received",
+                   containsFrame(processedMethods, expectedFrameClass));
+    }
+
+    private boolean containsFrame(final List<AMQDataBlock> frames,
+                                  final Class<? extends AMQMethodBodyImpl> frameClass)
+    {
+        for (AMQDataBlock block : frames)
+        {
+            AMQFrame frame = (AMQFrame) block;
+            if (frameClass.isInstance(frame.getBodyFrame()))
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+
+    private class TestEventReceiver implements ProtocolEventReceiver
+    {
+        private volatile boolean _closed;
+        private volatile Throwable _throwable;
+        private final List<ProtocolEvent> _events = new ArrayList<>();
+
+        @Override
+        public void received(final ProtocolEvent msg)
+        {
+            LOGGER.info("RECV:" + msg);
+            _events.add(msg);
+        }
+
+        @Override
+        public void exception(final Throwable t)
+        {
+            _throwable = t;
+        }
+
+        @Override
+        public void closed()
+        {
+            _closed = true;
+        }
+
+        public boolean isClosed()
+        {
+            return _closed;
+        }
+
+        public Collection<ProtocolEvent> getEvents()
+        {
+            return Collections.unmodifiableCollection(_events);
+        }
+
+        public Throwable getThrowable()
+        {
+            return _throwable;
+        }
+    }
+}

Modified: qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/MaxFrameSizeTest.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/MaxFrameSizeTest.java?rev=1747415&r1=1747414&r2=1747415&view=diff
==============================================================================
--- qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/MaxFrameSizeTest.java
(original)
+++ qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/MaxFrameSizeTest.java
Wed Jun  8 16:11:21 2016
@@ -26,8 +26,6 @@ import java.io.OutputStream;
 import java.net.Socket;
 import java.nio.ByteBuffer;
 import java.nio.charset.StandardCharsets;
-import java.util.ArrayList;
-import java.util.Collection;
 import java.util.Collections;
 import java.util.List;
 
@@ -41,7 +39,6 @@ import javax.security.sasl.Sasl;
 import javax.security.sasl.SaslClient;
 import javax.security.sasl.SaslException;
 
-import org.apache.qpid.bytebuffer.QpidByteBuffer;
 import org.apache.qpid.client.BrokerDetails;
 import org.apache.qpid.codec.ClientDecoder;
 import org.apache.qpid.framing.AMQDataBlock;
@@ -383,69 +380,4 @@ public class MaxFrameSizeTest extends Qp
         }
 
     }
-
-    private static class TestSender implements ByteBufferSender
-    {
-        private final Collection<QpidByteBuffer> _sentBuffers = new ArrayList<>();
-        private final OutputStream _output;
-
-
-        private TestSender(final OutputStream output)
-        {
-            _output = output;
-        }
-
-        @Override
-        public boolean isDirectBufferPreferred()
-        {
-            return false;
-        }
-
-        @Override
-        public void send(final QpidByteBuffer msg)
-        {
-            _sentBuffers.add(msg.duplicate());
-            msg.position(msg.limit());
-        }
-
-        @Override
-        public void flush()
-        {
-            int size = 0;
-            for(QpidByteBuffer buf : _sentBuffers)
-            {
-                size += buf.remaining();
-            }
-            byte[] data = new byte[size];
-            int offset = 0;
-            for(QpidByteBuffer buf : _sentBuffers)
-            {
-                int bufSize = buf.remaining();
-                buf.get(data, offset, bufSize);
-                offset+=bufSize;
-                buf.dispose();
-            }
-            try
-            {
-                _output.write(data);
-            }
-            catch (IOException e)
-            {
-                throw new RuntimeException(e);
-            }
-            finally
-            {
-                _sentBuffers.clear();
-            }
-
-        }
-
-        @Override
-        public void close()
-        {
-
-        }
-
-    }
-
 }

Added: qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/TestSender.java
URL: http://svn.apache.org/viewvc/qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/TestSender.java?rev=1747415&view=auto
==============================================================================
--- qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/TestSender.java (added)
+++ qpid/java/trunk/systests/src/test/java/org/apache/qpid/transport/TestSender.java Wed Jun
 8 16:11:21 2016
@@ -0,0 +1,90 @@
+/*
+ *
+ * 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.transport;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collection;
+
+import org.apache.qpid.bytebuffer.QpidByteBuffer;
+
+class TestSender implements ByteBufferSender
+{
+    private final Collection<QpidByteBuffer> _sentBuffers = new ArrayList<>();
+    private final OutputStream _output;
+
+
+    TestSender(final OutputStream output)
+    {
+        _output = output;
+    }
+
+    @Override
+    public boolean isDirectBufferPreferred()
+    {
+        return false;
+    }
+
+    @Override
+    public void send(final QpidByteBuffer msg)
+    {
+        _sentBuffers.add(msg.duplicate());
+        msg.position(msg.limit());
+    }
+
+    @Override
+    public void flush()
+    {
+        int size = 0;
+        for (QpidByteBuffer buf : _sentBuffers)
+        {
+            size += buf.remaining();
+        }
+        byte[] data = new byte[size];
+        int offset = 0;
+        for (QpidByteBuffer buf : _sentBuffers)
+        {
+            int bufSize = buf.remaining();
+            buf.get(data, offset, bufSize);
+            offset += bufSize;
+            buf.dispose();
+        }
+        try
+        {
+            _output.write(data);
+        }
+        catch (IOException e)
+        {
+            throw new RuntimeException(e);
+        }
+        finally
+        {
+            _sentBuffers.clear();
+        }
+    }
+
+    @Override
+    public void close()
+    {
+
+    }
+}

Modified: qpid/java/trunk/test-profiles/CPPExcludes
URL: http://svn.apache.org/viewvc/qpid/java/trunk/test-profiles/CPPExcludes?rev=1747415&r1=1747414&r2=1747415&view=diff
==============================================================================
--- qpid/java/trunk/test-profiles/CPPExcludes (original)
+++ qpid/java/trunk/test-profiles/CPPExcludes Wed Jun  8 16:11:21 2016
@@ -238,3 +238,7 @@ org.apache.qpid.test.unit.client.tempora
 
 # QPID-7156: Test requires a Broker with a virtualhost
 org.apache.qpid.test.unit.client.connection.BrokerClosesClientConnectionTest#testClientCloseOnVirtualHostStop
+
+# cpp broker allows anonymous access by default
+# the following test requires running broker with authentication enabled
+org.apache.qpid.transport.ConnectionEstablishmentTest#testAuthenticationBypass



---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@qpid.apache.org
For additional commands, e-mail: commits-help@qpid.apache.org


Mime
View raw message