[#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:
parent
58ad1e3106
commit
07ae838677
@ -32,6 +32,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;
|
||||||
@ -423,6 +424,10 @@ public class SslHandler extends ByteToMessageDecoder {
|
|||||||
|
|
||||||
@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);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -461,11 +466,6 @@ public class SslHandler extends ByteToMessageDecoder {
|
|||||||
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());
|
||||||
|
@ -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();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user