SSL / BlockHound works out of the box with the default SSL provider (#9969)
Motivation: JDK is the default SSL provider and internally uses blocking IO operations. Modifications: Add allowBlockingCallsInside configuration for SslHandler runAllDelegate function. Result: When BlockHound is installed, SSL works out of the box with the default SSL provider. Co-authored-by: violetagg <milesg78@gmail.com>
This commit is contained in:
parent
b49bd5644f
commit
0671b18e24
@ -65,6 +65,16 @@ class Hidden {
|
|||||||
"confirmShutdown"
|
"confirmShutdown"
|
||||||
);
|
);
|
||||||
|
|
||||||
|
builder.allowBlockingCallsInside(
|
||||||
|
"io.netty.handler.ssl.SslHandler",
|
||||||
|
"handshake"
|
||||||
|
);
|
||||||
|
|
||||||
|
builder.allowBlockingCallsInside(
|
||||||
|
"io.netty.handler.ssl.SslHandler",
|
||||||
|
"runAllDelegatedTasks"
|
||||||
|
);
|
||||||
|
|
||||||
builder.nonBlockingThreadPredicate(new Function<Predicate<Thread>, Predicate<Thread>>() {
|
builder.nonBlockingThreadPredicate(new Function<Predicate<Thread>, Predicate<Thread>>() {
|
||||||
@Override
|
@Override
|
||||||
public Predicate<Thread> apply(final Predicate<Thread> p) {
|
public Predicate<Thread> apply(final Predicate<Thread> p) {
|
||||||
|
@ -934,7 +934,7 @@ public class SslHandlerTest {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testHandshakeWithExecutor(Executor executor) throws Exception {
|
private static void testHandshakeWithExecutor(Executor executor) throws Exception {
|
||||||
final SslContext sslClientCtx = SslContextBuilder.forClient()
|
final SslContext sslClientCtx = SslContextBuilder.forClient()
|
||||||
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
||||||
.sslProvider(SslProvider.JDK).build();
|
.sslProvider(SslProvider.JDK).build();
|
||||||
@ -991,7 +991,7 @@ public class SslHandlerTest {
|
|||||||
testHandshakeTimeoutBecauseExecutorNotExecute(false);
|
testHandshakeTimeoutBecauseExecutorNotExecute(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testHandshakeTimeoutBecauseExecutorNotExecute(final boolean client) throws Exception {
|
private static void testHandshakeTimeoutBecauseExecutorNotExecute(final boolean client) throws Exception {
|
||||||
final SslContext sslClientCtx = SslContextBuilder.forClient()
|
final SslContext sslClientCtx = SslContextBuilder.forClient()
|
||||||
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
||||||
.sslProvider(SslProvider.JDK).build();
|
.sslProvider(SslProvider.JDK).build();
|
||||||
|
@ -46,6 +46,8 @@
|
|||||||
<properties>
|
<properties>
|
||||||
<maven.compiler.source>1.8</maven.compiler.source>
|
<maven.compiler.source>1.8</maven.compiler.source>
|
||||||
<maven.compiler.target>1.8</maven.compiler.target>
|
<maven.compiler.target>1.8</maven.compiler.target>
|
||||||
|
<!-- Needed for SelfSignedCertificate -->
|
||||||
|
<argLine.java9.extras>--add-exports java.base/sun.security.x509=ALL-UNNAMED</argLine.java9.extras>
|
||||||
<skipJapicmp>true</skipJapicmp>
|
<skipJapicmp>true</skipJapicmp>
|
||||||
</properties>
|
</properties>
|
||||||
|
|
||||||
@ -55,7 +57,17 @@
|
|||||||
<artifactId>netty-transport</artifactId>
|
<artifactId>netty-transport</artifactId>
|
||||||
<version>${project.version}</version>
|
<version>${project.version}</version>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
<dependency>
|
||||||
|
<groupId>${project.groupId}</groupId>
|
||||||
|
<artifactId>netty-handler</artifactId>
|
||||||
|
<version>${project.version}</version>
|
||||||
|
</dependency>
|
||||||
|
|
||||||
|
<dependency>
|
||||||
|
<groupId>org.bouncycastle</groupId>
|
||||||
|
<artifactId>bcpkix-jdk15on</artifactId>
|
||||||
|
<optional>true</optional>
|
||||||
|
</dependency>
|
||||||
<dependency>
|
<dependency>
|
||||||
<groupId>io.projectreactor.tools</groupId>
|
<groupId>io.projectreactor.tools</groupId>
|
||||||
<artifactId>blockhound</artifactId>
|
<artifactId>blockhound</artifactId>
|
||||||
|
@ -15,15 +15,41 @@
|
|||||||
*/
|
*/
|
||||||
package io.netty.util.internal;
|
package io.netty.util.internal;
|
||||||
|
|
||||||
|
import io.netty.bootstrap.Bootstrap;
|
||||||
|
import io.netty.bootstrap.ServerBootstrap;
|
||||||
|
import io.netty.buffer.UnpooledByteBufAllocator;
|
||||||
|
import io.netty.channel.Channel;
|
||||||
|
import io.netty.channel.ChannelFuture;
|
||||||
|
import io.netty.channel.ChannelHandlerContext;
|
||||||
|
import io.netty.channel.ChannelInboundHandlerAdapter;
|
||||||
|
import io.netty.channel.ChannelInitializer;
|
||||||
|
import io.netty.channel.EventLoopGroup;
|
||||||
|
import io.netty.channel.nio.NioEventLoopGroup;
|
||||||
|
import io.netty.channel.socket.nio.NioServerSocketChannel;
|
||||||
|
import io.netty.channel.socket.nio.NioSocketChannel;
|
||||||
|
import io.netty.handler.ssl.SslContext;
|
||||||
|
import io.netty.handler.ssl.SslContextBuilder;
|
||||||
|
import io.netty.handler.ssl.SslHandler;
|
||||||
|
import io.netty.handler.ssl.SslHandshakeCompletionEvent;
|
||||||
|
import io.netty.handler.ssl.SslProvider;
|
||||||
|
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
|
||||||
|
import io.netty.handler.ssl.util.SelfSignedCertificate;
|
||||||
|
import io.netty.util.ReferenceCountUtil;
|
||||||
import io.netty.util.concurrent.GlobalEventExecutor;
|
import io.netty.util.concurrent.GlobalEventExecutor;
|
||||||
|
import io.netty.util.concurrent.ImmediateEventExecutor;
|
||||||
|
import io.netty.util.concurrent.ImmediateExecutor;
|
||||||
import io.netty.util.internal.Hidden.NettyBlockHoundIntegration;
|
import io.netty.util.internal.Hidden.NettyBlockHoundIntegration;
|
||||||
import org.junit.BeforeClass;
|
import org.junit.BeforeClass;
|
||||||
import org.junit.Test;
|
import org.junit.Test;
|
||||||
import reactor.blockhound.BlockHound;
|
import reactor.blockhound.BlockHound;
|
||||||
import reactor.blockhound.integration.BlockHoundIntegration;
|
import reactor.blockhound.integration.BlockHoundIntegration;
|
||||||
|
|
||||||
|
import java.net.InetSocketAddress;
|
||||||
import java.util.ServiceLoader;
|
import java.util.ServiceLoader;
|
||||||
import java.util.concurrent.ExecutionException;
|
import java.util.concurrent.ExecutionException;
|
||||||
|
import java.util.concurrent.Executor;
|
||||||
|
import java.util.concurrent.ExecutorService;
|
||||||
|
import java.util.concurrent.Executors;
|
||||||
import java.util.concurrent.FutureTask;
|
import java.util.concurrent.FutureTask;
|
||||||
import java.util.concurrent.TimeUnit;
|
import java.util.concurrent.TimeUnit;
|
||||||
|
|
||||||
@ -66,4 +92,89 @@ public class NettyBlockHoundIntegrationTest {
|
|||||||
assertTrue("Blocking call was reported", throwable.getMessage().contains("Blocking call"));
|
assertTrue("Blocking call was reported", throwable.getMessage().contains("Blocking call"));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Tests copied from io.netty.handler.ssl.SslHandlerTest
|
||||||
|
@Test
|
||||||
|
public void testHandshakeWithExecutorThatExecuteDirectory() throws Exception {
|
||||||
|
testHandshakeWithExecutor(Runnable::run);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHandshakeWithImmediateExecutor() throws Exception {
|
||||||
|
testHandshakeWithExecutor(ImmediateExecutor.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHandshakeWithImmediateEventExecutor() throws Exception {
|
||||||
|
testHandshakeWithExecutor(ImmediateEventExecutor.INSTANCE);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testHandshakeWithExecutor() throws Exception {
|
||||||
|
ExecutorService executorService = Executors.newCachedThreadPool();
|
||||||
|
try {
|
||||||
|
testHandshakeWithExecutor(executorService);
|
||||||
|
} finally {
|
||||||
|
executorService.shutdown();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static void testHandshakeWithExecutor(Executor executor) throws Exception {
|
||||||
|
final SslContext sslClientCtx = SslContextBuilder.forClient()
|
||||||
|
.trustManager(InsecureTrustManagerFactory.INSTANCE)
|
||||||
|
.sslProvider(SslProvider.JDK).build();
|
||||||
|
|
||||||
|
final SelfSignedCertificate cert = new SelfSignedCertificate();
|
||||||
|
final SslContext sslServerCtx = SslContextBuilder.forServer(cert.key(), cert.cert())
|
||||||
|
.sslProvider(SslProvider.JDK).build();
|
||||||
|
|
||||||
|
EventLoopGroup group = new NioEventLoopGroup();
|
||||||
|
Channel sc = null;
|
||||||
|
Channel cc = null;
|
||||||
|
final SslHandler clientSslHandler = sslClientCtx.newHandler(UnpooledByteBufAllocator.DEFAULT, executor);
|
||||||
|
final SslHandler serverSslHandler = sslServerCtx.newHandler(UnpooledByteBufAllocator.DEFAULT, executor);
|
||||||
|
|
||||||
|
try {
|
||||||
|
sc = new ServerBootstrap()
|
||||||
|
.group(group)
|
||||||
|
.channel(NioServerSocketChannel.class)
|
||||||
|
.childHandler(serverSslHandler)
|
||||||
|
.bind(new InetSocketAddress(0)).syncUninterruptibly().channel();
|
||||||
|
|
||||||
|
ChannelFuture future = new Bootstrap()
|
||||||
|
.group(group)
|
||||||
|
.channel(NioSocketChannel.class)
|
||||||
|
.handler(new ChannelInitializer<Channel>() {
|
||||||
|
@Override
|
||||||
|
protected void initChannel(Channel ch) {
|
||||||
|
ch.pipeline()
|
||||||
|
.addLast(clientSslHandler)
|
||||||
|
.addLast(new ChannelInboundHandlerAdapter() {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void userEventTriggered(ChannelHandlerContext ctx, Object evt) {
|
||||||
|
if (evt instanceof SslHandshakeCompletionEvent &&
|
||||||
|
((SslHandshakeCompletionEvent) evt).cause() != null) {
|
||||||
|
((SslHandshakeCompletionEvent) evt).cause().printStackTrace();
|
||||||
|
}
|
||||||
|
ctx.fireUserEventTriggered(evt);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}).connect(sc.localAddress());
|
||||||
|
cc = future.syncUninterruptibly().channel();
|
||||||
|
|
||||||
|
assertTrue(clientSslHandler.handshakeFuture().await().isSuccess());
|
||||||
|
assertTrue(serverSslHandler.handshakeFuture().await().isSuccess());
|
||||||
|
} finally {
|
||||||
|
if (cc != null) {
|
||||||
|
cc.close().syncUninterruptibly();
|
||||||
|
}
|
||||||
|
if (sc != null) {
|
||||||
|
sc.close().syncUninterruptibly();
|
||||||
|
}
|
||||||
|
group.shutdownGracefully();
|
||||||
|
ReferenceCountUtil.release(sslClientCtx);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user