[#3968] Disallow pass-through of non ByteBufs in SslHandler

Motivation:

We pass-through non ByteBuf when SslHandler.write(...) is called which can lead to have unencrypted data to be send (like for example if a FileRegion is written).

Modifications:

- Fail ChannelPromise with UnsupportedMessageException if a non ByteBuf is written.

Result:

Only allow ByteBuf to be written when using SslHandler.
This commit is contained in:
Norman Maurer 2015-07-20 15:14:17 +02:00
parent a54124a220
commit 9db403d2df
2 changed files with 9 additions and 16 deletions

View File

@ -33,6 +33,7 @@ import io.netty.channel.ChannelPromise;
import io.netty.channel.ChannelPromiseNotifier; import io.netty.channel.ChannelPromiseNotifier;
import io.netty.channel.PendingWriteQueue; import io.netty.channel.PendingWriteQueue;
import io.netty.handler.codec.ByteToMessageDecoder; import io.netty.handler.codec.ByteToMessageDecoder;
import io.netty.handler.codec.UnsupportedMessageTypeException;
import io.netty.util.concurrent.DefaultPromise; import io.netty.util.concurrent.DefaultPromise;
import io.netty.util.concurrent.EventExecutor; import io.netty.util.concurrent.EventExecutor;
import io.netty.util.concurrent.Future; import io.netty.util.concurrent.Future;
@ -466,6 +467,10 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
@Override @Override
public void write(final ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception { public void write(final ChannelHandlerContext ctx, Object msg, ChannelPromise promise) throws Exception {
if (!(msg instanceof ByteBuf)) {
promise.setFailure(new UnsupportedMessageTypeException(msg, ByteBuf.class));
return;
}
pendingUnencryptedWrites.add(msg, promise); pendingUnencryptedWrites.add(msg, promise);
} }
@ -504,11 +509,6 @@ public class SslHandler extends ByteToMessageDecoder implements ChannelOutboundH
break; break;
} }
if (!(msg instanceof ByteBuf)) {
pendingUnencryptedWrites.removeAndWrite();
continue;
}
ByteBuf buf = (ByteBuf) msg; ByteBuf buf = (ByteBuf) msg;
if (out == null) { if (out == null) {
out = allocateOutNetBuf(ctx, buf.readableBytes()); out = allocateOutNetBuf(ctx, buf.readableBytes());

View File

@ -19,6 +19,7 @@ package io.netty.handler.ssl;
import io.netty.buffer.Unpooled; import io.netty.buffer.Unpooled;
import io.netty.channel.embedded.EmbeddedChannel; import io.netty.channel.embedded.EmbeddedChannel;
import io.netty.handler.codec.DecoderException; import io.netty.handler.codec.DecoderException;
import io.netty.handler.codec.UnsupportedMessageTypeException;
import org.junit.Test; import org.junit.Test;
import javax.net.ssl.SSLContext; import javax.net.ssl.SSLContext;
@ -53,21 +54,13 @@ public class SslHandlerTest {
} }
} }
@Test @Test(expected = UnsupportedMessageTypeException.class)
public void testNonByteBufPassthrough() throws Exception { public void testNonByteBufNotPassThrough() throws Exception {
SSLEngine engine = SSLContext.getDefault().createSSLEngine(); SSLEngine engine = SSLContext.getDefault().createSSLEngine();
engine.setUseClientMode(false); engine.setUseClientMode(false);
EmbeddedChannel ch = new EmbeddedChannel(new SslHandler(engine)); EmbeddedChannel ch = new EmbeddedChannel(new SslHandler(engine));
Object msg1 = new Object(); ch.writeOutbound(new Object());
ch.writeOutbound(msg1);
assertThat(ch.readOutbound(), is(sameInstance(msg1)));
Object msg2 = new Object();
ch.writeInbound(msg2);
assertThat(ch.readInbound(), is(sameInstance(msg2)));
ch.finish();
} }
} }