From 83b70b3742053898b86fb89f8e1085a7296923bc Mon Sep 17 00:00:00 2001 From: Clement Escoffier Date: Mon, 26 Feb 2024 11:52:26 +0100 Subject: [PATCH] Change TLS Hostname Verifier in Reactive SQL Client default value (do not break) The update to Vert.x 4.5.4 necessitates adjustments in extensions leveraging the Vert.x TCP client, notably impacting reactive SQL clients. TLS connections now require explicit configuration of hostname verification algorithms. Previously, in the absence of explicit specification by the protocol, the verification algorithm defaulted to "". Although this default remains unchanged in this commit, a MicroProfile Config limitation (https://github.com/eclipse/microprofile-config/issues/446) highlights that "" is not a valid value in the Quarkus configuration. Consequently, "NONE" has been adopted as an alternative. This enables users to explicitly set the hostname verification algorithm to "NONE" to bypass the verification process. --- docs/src/main/asciidoc/amqp-reference.adoc | 2 +- .../runtime/DataSourceReactiveRuntimeConfig.java | 6 ++++-- .../db2/client/runtime/DB2PoolRecorder.java | 8 +++++--- .../mssql/client/runtime/MSSQLPoolRecorder.java | 8 +++++--- .../mysql/client/runtime/MySQLPoolRecorder.java | 12 ++++++++---- .../reactive/pg/client/runtime/PgPoolRecorder.java | 13 ++++++++----- 6 files changed, 31 insertions(+), 18 deletions(-) diff --git a/docs/src/main/asciidoc/amqp-reference.adoc b/docs/src/main/asciidoc/amqp-reference.adoc index 85355b4b98e0d..10cdff6374bae 100644 --- a/docs/src/main/asciidoc/amqp-reference.adoc +++ b/docs/src/main/asciidoc/amqp-reference.adoc @@ -448,7 +448,7 @@ public AmqpClientOptions getNamedOptions() { .setPemKeyCertOptions(keycert) .setPemTrustOptions(trust) .addEnabledSaslMechanism("EXTERNAL") - .setHostnameVerificationAlgorithm("") + .setHostnameVerificationAlgorithm("") // Disables the hostname verification. Defaults is "HTTPS" .setConnectTimeout(30000) .setReconnectInterval(5000) .setContainerId("my-container"); diff --git a/extensions/reactive-datasource/runtime/src/main/java/io/quarkus/reactive/datasource/runtime/DataSourceReactiveRuntimeConfig.java b/extensions/reactive-datasource/runtime/src/main/java/io/quarkus/reactive/datasource/runtime/DataSourceReactiveRuntimeConfig.java index 6d336c2e0875e..555ecb3b82b77 100644 --- a/extensions/reactive-datasource/runtime/src/main/java/io/quarkus/reactive/datasource/runtime/DataSourceReactiveRuntimeConfig.java +++ b/extensions/reactive-datasource/runtime/src/main/java/io/quarkus/reactive/datasource/runtime/DataSourceReactiveRuntimeConfig.java @@ -111,9 +111,11 @@ public interface DataSourceReactiveRuntimeConfig { /** * The hostname verification algorithm to use in case the server's identity should be checked. - * Should be HTTPS, LDAPS or an empty string. + * Should be {@code HTTPS}, {@code LDAPS} or {@code NONE}. + * {@code NONE} is the default value and disables the verification. */ - Optional hostnameVerificationAlgorithm(); + @WithDefault("NONE") + String hostnameVerificationAlgorithm(); /** * The maximum time a connection remains unused in the pool before it is closed. diff --git a/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolRecorder.java b/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolRecorder.java index 85e16402885f6..134ccf43fa381 100644 --- a/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolRecorder.java +++ b/extensions/reactive-db2-client/runtime/src/main/java/io/quarkus/reactive/db2/client/runtime/DB2PoolRecorder.java @@ -217,9 +217,11 @@ private DB2ConnectOptions toConnectOptions(String dataSourceName, DataSourceRunt connectOptions.setReconnectInterval(dataSourceReactiveRuntimeConfig.reconnectInterval().toMillis()); - if (dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm().isPresent()) { - connectOptions.setHostnameVerificationAlgorithm( - dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm().get()); + var algo = dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm(); + if ("NONE".equalsIgnoreCase(algo)) { + connectOptions.setHostnameVerificationAlgorithm(""); + } else { + connectOptions.setHostnameVerificationAlgorithm(algo); } dataSourceReactiveRuntimeConfig.additionalProperties().forEach(connectOptions::addProperty); diff --git a/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/MSSQLPoolRecorder.java b/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/MSSQLPoolRecorder.java index b3c2c8cf1da72..bce9406f67eaf 100644 --- a/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/MSSQLPoolRecorder.java +++ b/extensions/reactive-mssql-client/runtime/src/main/java/io/quarkus/reactive/mssql/client/runtime/MSSQLPoolRecorder.java @@ -220,9 +220,11 @@ private MSSQLConnectOptions toMSSQLConnectOptions(String dataSourceName, DataSou configureJksKeyCertOptions(mssqlConnectOptions, dataSourceReactiveRuntimeConfig.keyCertificateJks()); configurePfxKeyCertOptions(mssqlConnectOptions, dataSourceReactiveRuntimeConfig.keyCertificatePfx()); - if (dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm().isPresent()) { - mssqlConnectOptions.setHostnameVerificationAlgorithm( - dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm().get()); + var algo = dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm(); + if ("NONE".equalsIgnoreCase(algo)) { + mssqlConnectOptions.setHostnameVerificationAlgorithm(""); + } else { + mssqlConnectOptions.setHostnameVerificationAlgorithm(algo); } dataSourceReactiveRuntimeConfig.additionalProperties().forEach(mssqlConnectOptions::addProperty); diff --git a/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/MySQLPoolRecorder.java b/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/MySQLPoolRecorder.java index fda8b5372f2a1..51c911af4836b 100644 --- a/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/MySQLPoolRecorder.java +++ b/extensions/reactive-mysql-client/runtime/src/main/java/io/quarkus/reactive/mysql/client/runtime/MySQLPoolRecorder.java @@ -215,8 +215,8 @@ private List toMySQLConnectOptions(String dataSourceName, mysqlConnectOptions.setSslMode(sslMode); // If sslMode is verify-identity, we also need a hostname verification algorithm - if (sslMode == SslMode.VERIFY_IDENTITY && (!dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm() - .isPresent() || "".equals(dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm().get()))) { + var algo = dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm(); + if ("NONE".equalsIgnoreCase(algo) && sslMode == SslMode.VERIFY_IDENTITY) { throw new IllegalArgumentException( "quarkus.datasource.reactive.hostname-verification-algorithm must be specified under verify-identity sslmode"); } @@ -236,8 +236,12 @@ private List toMySQLConnectOptions(String dataSourceName, mysqlConnectOptions.setReconnectInterval(dataSourceReactiveRuntimeConfig.reconnectInterval().toMillis()); - dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm().ifPresent( - mysqlConnectOptions::setHostnameVerificationAlgorithm); + var algo = dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm(); + if ("NONE".equalsIgnoreCase(algo)) { + mysqlConnectOptions.setHostnameVerificationAlgorithm(""); + } else { + mysqlConnectOptions.setHostnameVerificationAlgorithm(algo); + } dataSourceReactiveMySQLConfig.authenticationPlugin().ifPresent(mysqlConnectOptions::setAuthenticationPlugin); diff --git a/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/PgPoolRecorder.java b/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/PgPoolRecorder.java index 4afab742f0163..554614a412d1f 100644 --- a/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/PgPoolRecorder.java +++ b/extensions/reactive-pg-client/runtime/src/main/java/io/quarkus/reactive/pg/client/runtime/PgPoolRecorder.java @@ -202,10 +202,9 @@ private List toPgConnectOptions(String dataSourceName, DataSou final SslMode sslMode = dataSourceReactivePostgreSQLConfig.sslMode().get(); pgConnectOptions.setSslMode(sslMode); + var algo = dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm(); // If sslMode is verify-full, we also need a hostname verification algorithm - if (sslMode == SslMode.VERIFY_FULL - && (!dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm().isPresent() - || "".equals(dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm().get()))) { + if ("NONE".equalsIgnoreCase(algo) && sslMode == SslMode.VERIFY_FULL) { throw new IllegalArgumentException( "quarkus.datasource.reactive.hostname-verification-algorithm must be specified under verify-full sslmode"); } @@ -227,8 +226,12 @@ private List toPgConnectOptions(String dataSourceName, DataSou pgConnectOptions.setReconnectInterval(dataSourceReactiveRuntimeConfig.reconnectInterval().toMillis()); - dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm().ifPresent( - pgConnectOptions::setHostnameVerificationAlgorithm); + var algo = dataSourceReactiveRuntimeConfig.hostnameVerificationAlgorithm(); + if ("NONE".equalsIgnoreCase(algo)) { + pgConnectOptions.setHostnameVerificationAlgorithm(""); + } else { + pgConnectOptions.setHostnameVerificationAlgorithm(algo); + } dataSourceReactiveRuntimeConfig.additionalProperties().forEach(pgConnectOptions::addProperty);