r2dbc-postgresql
r2dbc-postgresql copied to clipboard
SSL SNI hostname with trailing dot unable to connect
trafficstars
Bug Report
Versions
- Driver: n/a
- Database: n/a
- Java: n/a
- OS: n/a
Current Behavior
SSL SNI hostname with trailing dot unable to connect. Throws a bit of a weird error.
Disabling SNI works fine. So this is a minor issue. But the same hostnames worked in the previous version using default settings and do not work in the current version with default settings.
Stack trace
java.lang.RuntimeException: java.lang.IllegalArgumentException: Server name value of host_name cannot have the trailing dot
at io.r2dbc.postgresql.client.ReactorNettyClient.registerSslHandler(ReactorNettyClient.java:422)
at io.r2dbc.postgresql.client.ReactorNettyClient.lambda$connect$11(ReactorNettyClient.java:402)
at reactor.netty.transport.TransportConfig$TransportChannelInitializer.initChannel(TransportConfig.java:418)
at io.netty.channel.ChannelInitializer.initChannel(ChannelInitializer.java:129)
at io.netty.channel.ChannelInitializer.handlerAdded(ChannelInitializer.java:112)
at io.netty.channel.AbstractChannelHandlerContext.callHandlerAdded(AbstractChannelHandlerContext.java:1130)
at io.netty.channel.DefaultChannelPipeline.callHandlerAdded0(DefaultChannelPipeline.java:609)
at io.netty.channel.DefaultChannelPipeline.access$100(DefaultChannelPipeline.java:46)
at io.netty.channel.DefaultChannelPipeline$PendingHandlerAddedTask.execute(DefaultChannelPipeline.java:1463)
at io.netty.channel.DefaultChannelPipeline.callHandlerAddedForAllHandlers(DefaultChannelPipeline.java:1115)
at io.netty.channel.DefaultChannelPipeline.invokeHandlerAddedIfNeeded(DefaultChannelPipeline.java:650)
at io.netty.channel.AbstractChannel$AbstractUnsafe.register0(AbstractChannel.java:514)
at io.netty.channel.AbstractChannel$AbstractUnsafe.access$200(AbstractChannel.java:429)
at io.netty.channel.AbstractChannel$AbstractUnsafe$1.run(AbstractChannel.java:486)
at io.netty.util.concurrent.AbstractEventExecutor.runTask$$$capture(AbstractEventExecutor.java:173)
at io.netty.util.concurrent.AbstractEventExecutor.runTask(AbstractEventExecutor.java)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute$$$capture(AbstractEventExecutor.java:166)
at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java)
at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:470)
at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:569)
at io.netty.util.concurrent.SingleThreadEventExecutor$4.run(SingleThreadEventExecutor.java:997)
at io.netty.util.internal.ThreadExecutorMap$2.run(ThreadExecutorMap.java:74)
at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
at java.base/java.lang.Thread.run(Thread.java:833)
Caused by: java.lang.IllegalArgumentException: Server name value of host_name cannot have the trailing dot
at java.base/javax.net.ssl.SNIHostName.checkHostName(SNIHostName.java:320)
at java.base/javax.net.ssl.SNIHostName.<init>(SNIHostName.java:108)
at io.r2dbc.postgresql.PostgresqlConnectionConfiguration$Builder.appendSniHost(PostgresqlConnectionConfiguration.java:1201)
at io.r2dbc.postgresql.PostgresqlConnectionConfiguration$Builder.lambda$getSslParametersFactory$3(PostgresqlConnectionConfiguration.java:1189)
at io.r2dbc.postgresql.client.AbstractPostgresSSLHandlerAdapter.<init>(AbstractPostgresSSLHandlerAdapter.java:50)
at io.r2dbc.postgresql.client.SSLSessionHandlerAdapter.<init>(SSLSessionHandlerAdapter.java:41)
at io.r2dbc.postgresql.client.ReactorNettyClient.registerSslHandler(ReactorNettyClient.java:416)
... 23 common frames omitted
io.r2dbc.postgresql.PostgresqlConnectionFactory$PostgresConnectionException: [08003] Cannot connect to database.internal./<unresolved>:5432
at io.r2dbc.postgresql.PostgresqlConnectionFactory.cannotConnect(PostgresqlConnectionFactory.java:188)
at io.r2dbc.postgresql.PostgresqlConnectionFactory.lambda$doCreateConnection$7(PostgresqlConnectionFactory.java:153)
at reactor.core.publisher.Mono.lambda$onErrorMap$28(Mono.java:3783)
at reactor.core.publisher.FluxOnErrorResume$ResumeSubscriber.onError(FluxOnErrorResume.java:94)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:180)
at reactor.core.publisher.MonoDelayUntil$DelayUntilCoordinator.onError(MonoDelayUntil.java:200)
at reactor.core.publisher.FluxMapFuseable$MapFuseableSubscriber.onError(FluxMapFuseable.java:142)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.onError(MonoFlatMap.java:180)
at reactor.core.publisher.MonoCreate$DefaultMonoSink.error(MonoCreate.java:201)
at reactor.netty.resources.NewConnectionProvider$DisposableConnect.onError(NewConnectionProvider.java:156)
at reactor.core.publisher.MonoFlatMap$FlatMapMain.secondError(MonoFlatMap.java:241)
Caused by: io.netty.channel.StacklessClosedChannelException
at io.netty.channel.AbstractChannel$AbstractUnsafe.ensureOpen(ChannelPromise)(Unknown Source)
Steps to reproduce
Use a hostname with a trailing .
Input Code
import io.r2dbc.postgresql.PostgresqlConnectionConfiguration
import io.r2dbc.postgresql.PostgresqlConnectionFactory
import io.r2dbc.postgresql.client.SSLMode
val config =
PostgresqlConnectionConfiguration.builder()
.host("database.internal.")
.port(5432)
.database("reporting")
.username("user")
.password("xxxx")
.sslMode(SSLMode.REQUIRE)
.build()
val factory = PostgresqlConnectionFactory(config)
factory.create().block()
Expected behavior/code
I expected the new 1.0.5 version to work like 1.0.4. But my hostnames conflicted with the new SNI feature.
Possible Solution
Configuring SNI to OFF works fine.
Extend SSLConfig.isValidSniHostname function to check for trailing . like SNIHostName does.