/* * JBoss, Home of Professional Open Source. * * Copyright 2013 Red Hat, Inc. and/or its affiliates, and individual * contributors as indicated by the @author tags. * * Licensed 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.xnio.ssl; import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertTrue; import java.io.IOException; import java.nio.ByteBuffer; import java.nio.channels.ClosedChannelException; import org.junit.After; import org.junit.Test; import org.xnio.ssl.mock.SSLEngineMock; /** * Test invalid scenarios involving the SSL connection. * * @author <a href="mailto:frainone@redhat.com">Flavia Rainone</a> * */ public class SslStreamConnectionValidationTestCase extends AbstractSslConnectionTest { @After @Override public void checkContext() { // do not check context... not all methods will be invoked on sessions created for invalid scenarios } @Test public void writeAfterShutdown() throws IOException { conduitMock.setReadData(SSLEngineMock.CLOSE_MSG); conduitMock.enableReads(true); sinkConduit.terminateWrites(); final ByteBuffer buffer = ByteBuffer.allocate(10); buffer.put("MSG!!!!!!!".getBytes("UTF-8")).flip(); boolean failed = false; try { sinkConduit.write(buffer); } catch (ClosedChannelException e) { failed = true; } assertTrue(failed); } @Test public void invalidWriteBufferArray() throws IOException { final ByteBuffer buffer = ByteBuffer.allocate(10); buffer.put("invalid".getBytes("UTF-8")).flip(); // the conduit should simply return 0 if length is 0 or a negative number assertEquals(0, sinkConduit.write(new ByteBuffer[]{buffer}, 0, 0)); assertEquals(0, sinkConduit.write(new ByteBuffer[]{buffer}, 0, -1)); // conduit should throw ArrayIndexOutOfBoundsException if position is < 0, or if length is larger than it should boolean failed = false; try { assertEquals(0, sinkConduit.write(new ByteBuffer[] { buffer }, -1, 1)); } catch (ArrayIndexOutOfBoundsException e) { failed = true; } assertTrue(failed); failed = false; try { assertEquals(0, sinkConduit.write(new ByteBuffer[] { buffer }, 0, 2)); } catch (ArrayIndexOutOfBoundsException e) { failed = true; } assertTrue(failed); } @Test public void writeNullBuffer() throws IOException { // null buffer boolean failed = false; try { sinkConduit.write((ByteBuffer) null); } catch (NullPointerException e) { failed = true; } assertTrue(failed); // null buffer array failed = false; try { sinkConduit.write((ByteBuffer[]) null, 4, 20); } catch (NullPointerException e) { failed = true; } assertTrue(failed); // null buffer in buffer array failed = false; try { sinkConduit.write(new ByteBuffer[] {null}, 0, 1); } catch (NullPointerException e) { failed = true; } assertTrue(failed); } @Test public void invalidReadBufferArray() throws IOException { conduitMock.setReadData("invalid read buffer array"); conduitMock.enableReads(true); final ByteBuffer buffer = ByteBuffer.allocate(10); // the conduit should simply return 0 if length is 0 assertEquals(0, sourceConduit.read(new ByteBuffer[]{buffer}, 0, 0)); // conduit should throw ArrayIndexOutOfBoundsException if offs or len is < 0, or if length is larger than it should boolean failed = false; try { assertEquals(0, sourceConduit.read(new ByteBuffer[]{buffer}, 0, -1)); } catch (ArrayIndexOutOfBoundsException e) { failed = true; } assertTrue(failed); failed = false; try { assertEquals(0, sourceConduit.read(new ByteBuffer[]{buffer}, -1, 1)); } catch (ArrayIndexOutOfBoundsException e) { failed = true; } assertTrue(failed); failed = false; try { sourceConduit.read(new ByteBuffer[]{buffer}, 0, 2); } catch (ArrayIndexOutOfBoundsException e) { failed = true; } assertTrue(failed); failed = false; try { sourceConduit.read(new ByteBuffer[0], 0, 50); } catch (ArrayIndexOutOfBoundsException e) { failed = true; } assertTrue(failed); } @Test public void readToNullBuffer() throws IOException { conduitMock.setReadData("null read buffer"); conduitMock.enableReads(true); // read to a null buffer boolean failed = false; try { sourceConduit.read((ByteBuffer) null); } catch (NullPointerException e) { failed = true; } assertTrue(failed); // read to a null buffer array failed = false; try { sourceConduit.read((ByteBuffer[]) null, 1, 3); } catch (NullPointerException e) { failed = true; } assertTrue(failed); // read to a null buffer in a buffer array failed = false; try { sourceConduit.read(new ByteBuffer[]{null}, 0, 1); } catch (NullPointerException e) { failed = true; } assertTrue(failed); } @Test public void terminateWritesCantFlush() throws IOException { conduitMock.enableFlush(false); ByteBuffer buffer = ByteBuffer.allocate(10); buffer.put("abc".getBytes("UTF-8")).flip(); sinkConduit.write(buffer); sinkConduit.terminateWrites(); assertWrittenMessage("abc", SSLEngineMock.CLOSE_MSG); } }