Skip to content

Commit 87cabe5

Browse files
committed
SNOW-2021533 Fix OCSP cache server URL when using proxy
1 parent 3ec16d3 commit 87cabe5

File tree

4 files changed

+104
-13
lines changed

4 files changed

+104
-13
lines changed

src/main/java/net/snowflake/client/core/SFTrustManager.java

Lines changed: 20 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -166,7 +166,6 @@ public class SFTrustManager extends X509ExtendedTrustManager {
166166
/** Default OCSP Cache server host name prefix */
167167
private static final String DEFAULT_OCSP_CACHE_HOST_PREFIX = "http://ocsp.snowflakecomputing.";
168168
/** Default OCSP Cache server host name */
169-
private static final String DEFAULT_OCSP_CACHE_HOST = DEFAULT_OCSP_CACHE_HOST_PREFIX + "com";
170169

171170
/** OCSP response file cache directory */
172171
private static final FileCacheManager fileCacheManager;
@@ -329,7 +328,7 @@ static void resetOCSPResponseCacherServerURL(String ocspCacheServerUrl) throws I
329328
}
330329
}
331330

332-
private static void setOCSPResponseCacheServerURL(String topLevelDomain) {
331+
static void setOCSPResponseCacheServerURL(String serverURL) {
333332
String ocspCacheUrl = systemGetProperty(SF_OCSP_RESPONSE_CACHE_SERVER_URL);
334333
if (ocspCacheUrl != null) {
335334
SF_OCSP_RESPONSE_CACHE_SERVER_URL_VALUE = ocspCacheUrl;
@@ -345,8 +344,16 @@ private static void setOCSPResponseCacheServerURL(String topLevelDomain) {
345344
true);
346345
}
347346
if (SF_OCSP_RESPONSE_CACHE_SERVER_URL_VALUE == null) {
348-
SF_OCSP_RESPONSE_CACHE_SERVER_URL_VALUE =
349-
String.format("%s%s/%s", DEFAULT_OCSP_CACHE_HOST_PREFIX, topLevelDomain, CACHE_FILE_NAME);
347+
String topLevelDomain = "com";
348+
try {
349+
URL url = new URL(serverURL);
350+
topLevelDomain = url.getHost().substring(url.getHost().lastIndexOf(".") + 1);
351+
SF_OCSP_RESPONSE_CACHE_SERVER_URL_VALUE =
352+
String.format(
353+
"%s%s/%s", DEFAULT_OCSP_CACHE_HOST_PREFIX, topLevelDomain, CACHE_FILE_NAME);
354+
} catch (Exception e) {
355+
logger.debug("Exception while setting top level domain (for OCSP)", e);
356+
}
350357
}
351358
logger.debug("Set OCSP response cache server to: {}", SF_OCSP_RESPONSE_CACHE_SERVER_URL_VALUE);
352359
}
@@ -772,8 +779,6 @@ void validateRevocationStatus(X509Certificate[] chain, String peerHost)
772779
ocspCacheServer.resetOCSPResponseCacheServer(peerHost);
773780
}
774781

775-
String topLevelDomain = peerHost.substring(peerHost.lastIndexOf(".") + 1);
776-
setOCSPResponseCacheServerURL(topLevelDomain);
777782
boolean isCached = isCached(pairIssuerSubjectList);
778783
if (useOCSPResponseCacheServer() && !isCached) {
779784
if (!ocspCacheServer.new_endpoint_enabled) {
@@ -1528,17 +1533,19 @@ void resetOCSPResponseCacheServer(String host) {
15281533
String ocspCacheServerUrl;
15291534
if (host.toLowerCase().contains(".global.snowflakecomputing.")) {
15301535
ocspCacheServerUrl =
1531-
String.format("https://ocspssd%s/%s", host.substring(host.indexOf('-')), "ocsp");
1536+
java.lang.String.format(
1537+
"https://ocspssd%s/%s", host.substring(host.indexOf('-')), "ocsp");
15321538
} else if (host.toLowerCase().contains(".snowflakecomputing.")) {
15331539
ocspCacheServerUrl =
1534-
String.format("https://ocspssd%s/%s", host.substring(host.indexOf('.')), "ocsp");
1540+
java.lang.String.format(
1541+
"https://ocspssd%s/%s", host.substring(host.indexOf('.')), "ocsp");
15351542
} else {
15361543
String topLevelDomain = host.substring(host.lastIndexOf(".") + 1);
15371544
ocspCacheServerUrl =
1538-
String.format("https://ocspssd.snowflakecomputing.%s/ocsp", topLevelDomain);
1545+
java.lang.String.format("https://ocspssd.snowflakecomputing.%s/ocsp", topLevelDomain);
15391546
}
1540-
SF_OCSP_RESPONSE_CACHE_SERVER = String.format("%s/%s", ocspCacheServerUrl, "fetch");
1541-
SF_OCSP_RESPONSE_RETRY_URL = String.format("%s/%s", ocspCacheServerUrl, "retry");
1547+
SF_OCSP_RESPONSE_CACHE_SERVER = java.lang.String.format("%s/%s", ocspCacheServerUrl, "fetch");
1548+
SF_OCSP_RESPONSE_RETRY_URL = java.lang.String.format("%s/%s", ocspCacheServerUrl, "retry");
15421549
}
15431550
}
15441551

@@ -1586,7 +1593,7 @@ public boolean equals(Object obj) {
15861593
}
15871594

15881595
public String toString() {
1589-
return String.format(
1596+
return java.lang.String.format(
15901597
"OcspResponseCacheKey: NameHash: %s, KeyHash: %s, SerialNumber: %s",
15911598
HexUtil.byteToHexString(nameHash),
15921599
HexUtil.byteToHexString(keyHash),
@@ -1614,7 +1621,7 @@ public byte[] getDigest() {
16141621
return messageDigest.digest(bytes);
16151622
} catch (NoSuchAlgorithmException ex) {
16161623
String errMsg =
1617-
String.format(
1624+
java.lang.String.format(
16181625
"Failed to instantiate the algorithm: %s. err=%s",
16191626
ALGORITHM_SHA1_NAME, ex.getMessage());
16201627
logger.error(errMsg, false);

src/main/java/net/snowflake/client/core/SessionUtil.java

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package net.snowflake.client.core;
22

33
import static net.snowflake.client.core.SFTrustManager.resetOCSPResponseCacherServerURL;
4+
import static net.snowflake.client.core.SFTrustManager.setOCSPResponseCacheServerURL;
45
import static net.snowflake.client.jdbc.SnowflakeUtil.isNullOrEmpty;
56
import static net.snowflake.client.jdbc.SnowflakeUtil.systemGetEnv;
67
import static net.snowflake.client.jdbc.SnowflakeUtil.systemGetProperty;
@@ -1927,6 +1928,7 @@ enum TokenRequestType {
19271928
* @throws IOException If exception encountered
19281929
*/
19291930
public static void resetOCSPUrlIfNecessary(String serverUrl) throws IOException {
1931+
setOCSPResponseCacheServerURL(serverUrl);
19301932
if (PrivateLinkDetector.isPrivateLink(serverUrl)) {
19311933
// Privatelink uses special OCSP Cache server
19321934
URL url = new URL(serverUrl);
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
package net.snowflake.client;
2+
3+
public class SystemPropertyOverrider {
4+
private final String propertyName;
5+
private final String oldValue;
6+
7+
public SystemPropertyOverrider(String propertyName, String newValue) {
8+
this.propertyName = propertyName;
9+
this.oldValue = System.getProperty(propertyName);
10+
System.setProperty(propertyName, newValue);
11+
}
12+
13+
public void rollback() {
14+
if (oldValue != null) {
15+
System.setProperty(propertyName, oldValue);
16+
} else {
17+
System.clearProperty(propertyName);
18+
}
19+
}
20+
}

src/test/java/net/snowflake/client/core/SFTrustManagerIT.java

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,12 @@
11
package net.snowflake.client.core;
22

3+
import static net.snowflake.client.core.SFTrustManager.SF_OCSP_RESPONSE_CACHE_SERVER_URL_VALUE;
34
import static org.awaitility.Awaitility.await;
45
import static org.hamcrest.CoreMatchers.equalTo;
56
import static org.hamcrest.CoreMatchers.not;
67
import static org.hamcrest.MatcherAssert.assertThat;
78
import static org.hamcrest.core.AnyOf.anyOf;
9+
import static org.junit.jupiter.api.Assertions.assertEquals;
810

911
import java.io.File;
1012
import java.io.IOException;
@@ -15,12 +17,16 @@
1517
import java.security.cert.X509Certificate;
1618
import java.time.Duration;
1719
import java.util.ArrayList;
20+
import java.util.Arrays;
1821
import java.util.List;
22+
import java.util.Properties;
1923
import java.util.concurrent.TimeUnit;
2024
import java.util.stream.Stream;
2125
import javax.net.ssl.SSLHandshakeException;
26+
import net.snowflake.client.SystemPropertyOverrider;
2227
import net.snowflake.client.category.TestTags;
2328
import net.snowflake.client.jdbc.BaseJDBCTest;
29+
import net.snowflake.client.jdbc.SnowflakeConnectionV1;
2430
import net.snowflake.client.jdbc.telemetryOOB.TelemetryService;
2531
import net.snowflake.client.log.SFLogger;
2632
import net.snowflake.client.log.SFLoggerFactory;
@@ -36,6 +42,7 @@
3642
import org.junit.jupiter.params.provider.Arguments;
3743
import org.junit.jupiter.params.provider.ArgumentsProvider;
3844
import org.junit.jupiter.params.provider.ArgumentsSource;
45+
import org.junit.jupiter.params.provider.CsvSource;
3946

4047
@Tag(TestTags.CORE)
4148
public class SFTrustManagerIT extends BaseJDBCTest {
@@ -96,6 +103,8 @@ public void tearDown() throws InterruptedException {
96103
public void testOcsp(String host) throws Throwable {
97104
System.setProperty(
98105
SFTrustManager.SF_OCSP_RESPONSE_CACHE_SERVER_ENABLED, Boolean.TRUE.toString());
106+
// this initialization normally happens on first call
107+
SFTrustManager.setOCSPResponseCacheServerURL(String.format("http://%s", host));
99108
HttpClient client =
100109
HttpUtil.buildHttpClient(
101110
new HttpClientSettingsKey(OCSPMode.FAIL_CLOSED),
@@ -259,4 +268,57 @@ private InputStream getFile(String fileName) throws Throwable {
259268
URL url = classLoader.getResource(fileName);
260269
return url != null ? url.openStream() : null;
261270
}
271+
272+
@ParameterizedTest
273+
@CsvSource({
274+
"jdbc:snowflake://someaccount.snowflakecomputing.com:443,http://ocsp.snowflakecomputing.com/ocsp_response_cache.json",
275+
"jdbc:snowflake://someaccount.snowflakecomputing.cn:443,http://ocsp.snowflakecomputing.cn/ocsp_response_cache.json",
276+
})
277+
void testOCSPCacheServerUrlWithoutProxy(String sfHost, String ocspHost) throws Exception {
278+
Properties props = new Properties();
279+
props.setProperty(SFSessionProperty.USER.getPropertyKey(), "testUser");
280+
props.setProperty(SFSessionProperty.PASSWORD.getPropertyKey(), "testPassword");
281+
props.setProperty(SFSessionProperty.LOGIN_TIMEOUT.getPropertyKey(), "1");
282+
try {
283+
new SnowflakeConnectionV1(sfHost, props);
284+
} catch (Exception e) {
285+
// do nothing, we don't want to connect, just check the value below
286+
}
287+
assertEquals(SF_OCSP_RESPONSE_CACHE_SERVER_URL_VALUE, ocspHost);
288+
}
289+
290+
@ParameterizedTest
291+
@CsvSource({
292+
"jdbc:snowflake://someaccount.snowflakecomputing.com:443,http://ocsp.snowflakecomputing.com/ocsp_response_cache.json",
293+
"jdbc:snowflake://someaccount.snowflakecomputing.cn:443,http://ocsp.snowflakecomputing.cn/ocsp_response_cache.json",
294+
})
295+
void testOCSPCacheServerUrlWithProxy(String sfHost, String ocspHost) {
296+
SystemPropertyOverrider useProxyOverrider =
297+
new SystemPropertyOverrider("http.useProxy", "true");
298+
SystemPropertyOverrider proxyHostOverrider =
299+
new SystemPropertyOverrider("http.proxyHost", "localhost");
300+
SystemPropertyOverrider proxyPortOverrider =
301+
new SystemPropertyOverrider("http.proxyPort", "8080");
302+
try {
303+
Properties props = new Properties();
304+
props.setProperty(SFSessionProperty.USER.getPropertyKey(), "testUser");
305+
props.setProperty(SFSessionProperty.PASSWORD.getPropertyKey(), "testPassword");
306+
props.setProperty(SFSessionProperty.LOGIN_TIMEOUT.getPropertyKey(), "1");
307+
try {
308+
new SnowflakeConnectionV1(sfHost, props);
309+
} catch (Exception e) {
310+
// do nothing, we don't want to connect, just check the value below
311+
}
312+
assertEquals(SF_OCSP_RESPONSE_CACHE_SERVER_URL_VALUE, ocspHost);
313+
} finally {
314+
Arrays.asList(useProxyOverrider, proxyHostOverrider, proxyPortOverrider)
315+
.forEach(SystemPropertyOverrider::rollback);
316+
}
317+
}
318+
319+
@BeforeEach
320+
@AfterEach
321+
void cleanup() {
322+
SF_OCSP_RESPONSE_CACHE_SERVER_URL_VALUE = null;
323+
}
262324
}

0 commit comments

Comments
 (0)