Skip to content

Commit ae870c1

Browse files
committed
Fixed problem of disabled verification
1 parent ea14e4f commit ae870c1

3 files changed

Lines changed: 63 additions & 9 deletions

File tree

client-v2/src/main/java/com/clickhouse/client/api/Client.java

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1172,14 +1172,29 @@ public Client build() {
11721172
// A trust store and a CA certificate are not rejected here: for VERIFY_CA/STRICT the trust
11731173
// store takes precedence and the CA certificate is ignored with a warning (see createSSLContext).
11741174

1175-
// SSLMode.DISABLED does not turn encryption off - the endpoint scheme decides that. So it
1176-
// contradicts a secure (https) endpoint and must be rejected here, before the client is created.
1177-
if (SSLMode.DISABLED.name().equals(configuration.get(ClientConfigProperties.SSL_MODE.getKey()))) {
1178-
for (Endpoint endpoint : this.endpoints) {
1179-
if ("https".equalsIgnoreCase(endpoint.getURI().getScheme())) {
1180-
throw new ClientMisconfigurationException("SSL mode '" + SSLMode.DISABLED
1181-
+ "' cannot be used with a secure (https) endpoint. Use '" + SSLMode.TRUST
1182-
+ "' to trust all certificates or use plain HTTP.");
1175+
// Resolve ssl_mode case-insensitively and normalize it to the canonical enum name so that
1176+
// downstream parsing is consistent and an unknown value is reported as a misconfiguration
1177+
// here instead of failing later with a generic enum-parsing error.
1178+
String sslModeValue = configuration.get(ClientConfigProperties.SSL_MODE.getKey());
1179+
if (sslModeValue != null) {
1180+
SSLMode sslMode;
1181+
try {
1182+
sslMode = SSLMode.fromValue(sslModeValue);
1183+
} catch (IllegalArgumentException e) {
1184+
throw new ClientMisconfigurationException("Invalid value '" + sslModeValue + "' for '"
1185+
+ ClientConfigProperties.SSL_MODE.getKey() + "'", e);
1186+
}
1187+
configuration.put(ClientConfigProperties.SSL_MODE.getKey(), sslMode.name());
1188+
1189+
// SSLMode.DISABLED does not turn encryption off - the endpoint scheme decides that. So it
1190+
// contradicts a secure (https) endpoint and must be rejected here, before the client is created.
1191+
if (sslMode == SSLMode.DISABLED) {
1192+
for (Endpoint endpoint : this.endpoints) {
1193+
if ("https".equalsIgnoreCase(endpoint.getURI().getScheme())) {
1194+
throw new ClientMisconfigurationException("SSL mode '" + SSLMode.DISABLED
1195+
+ "' cannot be used with a secure (https) endpoint. Use '" + SSLMode.TRUST
1196+
+ "' to trust all certificates or use plain HTTP.");
1197+
}
11831198
}
11841199
}
11851200
}

client-v2/src/test/java/com/clickhouse/client/api/ClientBuilderTest.java

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.clickhouse.client.api;
22

3+
import com.clickhouse.client.api.enums.SSLMode;
34
import org.testng.Assert;
45
import org.testng.annotations.Test;
56

@@ -22,6 +23,44 @@ public void testAddEndpointToleratesUnderscoreHostname() throws Exception {
2223
}
2324
}
2425

26+
@Test
27+
public void testSslModeDisabledRejectedForHttpsRegardlessOfCase() {
28+
// Value supplied as a raw (non-canonical case) string via setOption must still be recognized
29+
// as DISABLED and rejected with ClientMisconfigurationException for an https endpoint.
30+
for (String value : new String[] { "DISABLED", "disabled", "Disabled" }) {
31+
Assert.expectThrows(ClientMisconfigurationException.class, () -> new Client.Builder()
32+
.addEndpoint("https://localhost:8443")
33+
.setUsername("default")
34+
.setPassword("")
35+
.setOption(ClientConfigProperties.SSL_MODE.getKey(), value)
36+
.build());
37+
}
38+
}
39+
40+
@Test
41+
public void testSslModeInvalidValueRejected() {
42+
Assert.expectThrows(ClientMisconfigurationException.class, () -> new Client.Builder()
43+
.addEndpoint("https://localhost:8443")
44+
.setUsername("default")
45+
.setPassword("")
46+
.setOption(ClientConfigProperties.SSL_MODE.getKey(), "insecure")
47+
.build());
48+
}
49+
50+
@Test
51+
public void testSslModeNormalizedToCanonicalName() throws Exception {
52+
// A non-canonical case value is accepted and normalized to the canonical enum name.
53+
try (Client client = new Client.Builder()
54+
.addEndpoint("http://localhost:8123")
55+
.setUsername("default")
56+
.setPassword("")
57+
.setOption(ClientConfigProperties.SSL_MODE.getKey(), "trust")
58+
.build()) {
59+
Assert.assertEquals(client.getConfiguration().get(ClientConfigProperties.SSL_MODE.getKey()),
60+
SSLMode.TRUST.name());
61+
}
62+
}
63+
2564
private static String extractFirstEndpointUri(Client client) throws Exception {
2665
Field endpointsField = Client.class.getDeclaredField("endpoints");
2766
endpointsField.setAccessible(true);

docs/features.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -42,7 +42,7 @@ Compatibility-sensitive traits:
4242
- `Geometry` handling is shape-sensitive: supported values are 1D through 4D Java arrays representing the nested geometry variants, and unsupported shapes or non-array values are rejected during serialization.
4343
- `Geometry` write inference is dimension-based rather than fully type-specific: point, ring/line string, polygon/multi-line string, and multi-polygon are selected from array depth, so writing `Geometry` cannot currently distinguish `Ring` from `LineString` or `Polygon` from `MultiLineString`.
4444
- Session precedence is part of the contract: client session defaults apply to each request, operation settings may override them, and only the client `session_id` is mutable at runtime while other client session properties remain fixed for the lifetime of the client.
45-
- SSL mode behavior is compatibility-sensitive: the default is `STRICT`. `ssl_mode` does not enable or disable encryption - the endpoint scheme decides that. `DISABLED` is only valid with a plain `http://` endpoint; combining it with an `https://` endpoint throws `ClientMisconfigurationException`. `TRUST` accepts any server certificate and skips hostname verification; a configured trust store or CA certificate has no effect in this mode and is ignored (a warning is logged), while a client certificate/key is still applied for mTLS. For `VERIFY_CA` and `STRICT`, a trust store and a CA certificate cannot both take effect: when both are configured the trust store is used and the CA certificate is ignored (a warning is logged). A trust store and a client certificate (`sslcert`) still cannot be configured together and throw `ClientMisconfigurationException`. When reading the `ssl_mode` value through the client configuration map, enum names are matched case-sensitively (`DISABLED`, `TRUST`, `VERIFY_CA`, `STRICT`).
45+
- SSL mode behavior is compatibility-sensitive: the default is `STRICT`. `ssl_mode` does not enable or disable encryption - the endpoint scheme decides that. `DISABLED` is only valid with a plain `http://` endpoint; combining it with an `https://` endpoint throws `ClientMisconfigurationException`. `TRUST` accepts any server certificate and skips hostname verification; a configured trust store or CA certificate has no effect in this mode and is ignored (a warning is logged), while a client certificate/key is still applied for mTLS. For `VERIFY_CA` and `STRICT`, a trust store and a CA certificate cannot both take effect: when both are configured the trust store is used and the CA certificate is ignored (a warning is logged). A trust store and a client certificate (`sslcert`) still cannot be configured together and throw `ClientMisconfigurationException`. `ssl_mode` values are matched case-insensitively and normalized to the canonical enum name (`DISABLED`, `TRUST`, `VERIFY_CA`, `STRICT`) when the client is built; an unrecognized value throws `ClientMisconfigurationException`.
4646
- Certificate-as-content support is compatibility-sensitive: any certificate or key value containing a PEM begin marker (`-----BEGIN`) is treated as inline PEM content, otherwise it is treated as a file path (also searched in the home directory and on the classpath).
4747

4848

0 commit comments

Comments
 (0)