diff --git a/src/main/java/net/snowflake/client/core/HttpUtil.java b/src/main/java/net/snowflake/client/core/HttpUtil.java index 23b83df09..582994191 100644 --- a/src/main/java/net/snowflake/client/core/HttpUtil.java +++ b/src/main/java/net/snowflake/client/core/HttpUtil.java @@ -345,9 +345,9 @@ public static CloseableHttpClient buildHttpClient( } TrustManager[] trustManagers = null; - if (key != null && key.getOcspMode() != OCSPMode.INSECURE) { - // A custom TrustManager is required only if insecureMode is disabled, - // which is by default in the production. insecureMode can be enabled + if (key != null && key.getOcspMode() != OCSPMode.DISABLE_OCSP_CHECKS) { + // A custom TrustManager is required only if disableOCSPMode is disabled, + // which is by default in the production. disableOCSPMode can be enabled // 1) OCSP service is down for reasons, 2) PowerMock test that doesn't // care OCSP checks. // OCSP FailOpen is ON by default @@ -742,7 +742,7 @@ public static String executeRequest( HttpClientSettingsKey ocspAndProxyKey, ExecTimeTelemetryData execTimeData) throws SnowflakeSQLException, IOException { - boolean ocspEnabled = !(ocspAndProxyKey.getOcspMode().equals(OCSPMode.INSECURE)); + boolean ocspEnabled = !(ocspAndProxyKey.getOcspMode().equals(OCSPMode.DISABLE_OCSP_CHECKS)); logger.debug("Executing request with OCSP enabled: {}", ocspEnabled); execTimeData.setOCSPStatus(ocspEnabled); return executeRequestInternal( diff --git a/src/main/java/net/snowflake/client/core/OCSPMode.java b/src/main/java/net/snowflake/client/core/OCSPMode.java index 1b9144a81..03c2a3bbb 100644 --- a/src/main/java/net/snowflake/client/core/OCSPMode.java +++ b/src/main/java/net/snowflake/client/core/OCSPMode.java @@ -15,8 +15,15 @@ public enum OCSPMode { */ FAIL_OPEN(1), - /** Insure mode. No OCSP check is made. */ - INSECURE(2); + /** + * @deprecated Use {@link #DISABLE_OCSP_CHECKS} for clarity. This configuration option is used to + * disable OCSP verification. Insure mode. No OCSP check is made. + */ + @Deprecated + INSECURE(2), + + /** Disable OCSP checks. It's used to disable OCSP verification. */ + DISABLE_OCSP_CHECKS(3); private final int value; diff --git a/src/main/java/net/snowflake/client/core/SFBaseSession.java b/src/main/java/net/snowflake/client/core/SFBaseSession.java index a7b374fde..28c7522be 100644 --- a/src/main/java/net/snowflake/client/core/SFBaseSession.java +++ b/src/main/java/net/snowflake/client/core/SFBaseSession.java @@ -714,10 +714,12 @@ public void unsetInvalidProxyHostAndPort() { public OCSPMode getOCSPMode() { OCSPMode ret; + Boolean disableOCSPMode = + (Boolean) connectionPropertiesMap.get(SFSessionProperty.DISABLE_OCSP_CHECKS); Boolean insecureMode = (Boolean) connectionPropertiesMap.get(SFSessionProperty.INSECURE_MODE); - if (insecureMode != null && insecureMode) { + if ((disableOCSPMode != null && disableOCSPMode) || (insecureMode != null && insecureMode)) { // skip OCSP checks - ret = OCSPMode.INSECURE; + ret = OCSPMode.DISABLE_OCSP_CHECKS; } else if (!connectionPropertiesMap.containsKey(SFSessionProperty.OCSP_FAIL_OPEN) || (boolean) connectionPropertiesMap.get(SFSessionProperty.OCSP_FAIL_OPEN)) { // fail open (by default, not set) diff --git a/src/main/java/net/snowflake/client/core/SFSessionProperty.java b/src/main/java/net/snowflake/client/core/SFSessionProperty.java index a5e7276c5..a2da9e393 100644 --- a/src/main/java/net/snowflake/client/core/SFSessionProperty.java +++ b/src/main/java/net/snowflake/client/core/SFSessionProperty.java @@ -37,7 +37,13 @@ public enum SFSessionProperty { APP_ID("appId", false, String.class), APP_VERSION("appVersion", false, String.class), OCSP_FAIL_OPEN("ocspFailOpen", false, Boolean.class), + /** + * @deprecated Use {@link #DISABLE_OCSP_CHECKS} for clarity. This configuration option is used to + * disable OCSP verification. + */ + @Deprecated INSECURE_MODE("insecureMode", false, Boolean.class), + DISABLE_OCSP_CHECKS("disableOCSPChecks", false, Boolean.class), QUERY_TIMEOUT("queryTimeout", false, Integer.class), STRINGS_QUOTED("stringsQuotedForColumnDef", false, Boolean.class), APPLICATION("application", false, String.class), diff --git a/src/main/java/net/snowflake/client/core/SFTrustManager.java b/src/main/java/net/snowflake/client/core/SFTrustManager.java index 6df3353e1..6bff0a8c5 100644 --- a/src/main/java/net/snowflake/client/core/SFTrustManager.java +++ b/src/main/java/net/snowflake/client/core/SFTrustManager.java @@ -1161,7 +1161,7 @@ private OCSPResp fetchOcspResponse( new DecorrelatedJitterBackoff(sleepTime, MAX_SLEEPING_TIME_IN_MILLISECONDS); boolean success = false; - final int maxRetryCounter = isOCSPFailOpen() ? 1 : 3; + final int maxRetryCounter = isOCSPFailOpen() ? 1 : 2; Exception savedEx = null; CloseableHttpClient httpClient = ocspCacheServerClient.computeIfAbsent( diff --git a/src/test/java/net/snowflake/client/jdbc/ConnectionIT.java b/src/test/java/net/snowflake/client/jdbc/ConnectionIT.java index 9d99e01a1..f62e52b56 100644 --- a/src/test/java/net/snowflake/client/jdbc/ConnectionIT.java +++ b/src/test/java/net/snowflake/client/jdbc/ConnectionIT.java @@ -1052,6 +1052,41 @@ public void testFailOverOrgAccount() throws SQLException { } } + /** Test production connectivity with disableOCSPChecksMode enabled. */ + @Test + public void testDisableOCSPChecksMode() throws SQLException { + String deploymentUrl = "jdbc:snowflake://sfcsupport.snowflakecomputing.com"; + + Properties properties = new Properties(); + + properties.put("user", "fakeuser"); + properties.put("password", "fakepwd"); + properties.put("account", "fakeaccount"); + properties.put("disableOCSPChecks", true); + try { + DriverManager.getConnection(deploymentUrl, properties); + fail(); + } catch (SQLException e) { + assertThat( + e.getErrorCode(), anyOf(is(INVALID_CONNECTION_INFO_CODE), is(BAD_REQUEST_GS_CODE))); + } + + deploymentUrl = "jdbc:snowflake://sfcsupport.snowflakecomputing.com?disableOCSPChecks=true"; + + properties = new Properties(); + + properties.put("user", "fakeuser"); + properties.put("password", "fakepwd"); + properties.put("account", "fakeaccount"); + try { + DriverManager.getConnection(deploymentUrl, properties); + fail(); + } catch (SQLException e) { + assertThat( + e.getErrorCode(), anyOf(is(INVALID_CONNECTION_INFO_CODE), is(BAD_REQUEST_GS_CODE))); + } + } + private class ConcurrentConnections implements Runnable { ConcurrentConnections() {}