Skip to content

Commit 36f35d4

Browse files
committed
SCANJLIB-236 Map JVM cacerts to the new ssl properties
1 parent 2bef3e4 commit 36f35d4

3 files changed

Lines changed: 66 additions & 10 deletions

File tree

lib/src/main/java/org/sonarsource/scanner/lib/ScannerEngineBootstrapper.java

Lines changed: 23 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -20,14 +20,14 @@
2020
package org.sonarsource.scanner.lib;
2121

2222
import java.net.InetSocketAddress;
23+
import java.nio.file.Files;
2324
import java.nio.file.Path;
2425
import java.nio.file.Paths;
2526
import java.time.temporal.ChronoUnit;
2627
import java.util.HashMap;
2728
import java.util.Locale;
2829
import java.util.Map;
2930
import java.util.Objects;
30-
import javax.annotation.Nonnull;
3131
import javax.annotation.Nullable;
3232
import org.apache.commons.io.FileUtils;
3333
import org.apache.commons.lang3.StringUtils;
@@ -121,20 +121,38 @@ public ScannerEngineFacade bootstrap() {
121121
return new SimulationScannerEngineFacade(properties, isSonarCloud, serverVersion);
122122
} else if (isSonarCloud || VersionUtils.isAtLeastIgnoringQualifier(serverVersion, SQ_VERSION_NEW_BOOTSTRAPPING)) {
123123
var launcher = scannerEngineLauncherFactory.createLauncher(scannerHttpClient, fileCache, properties);
124-
return new NewScannerEngineFacade(properties, launcher, isSonarCloud, serverVersion);
124+
var adaptedProperties = adaptDeprecatedPropertiesForForkedBootstrapping(properties, httpConfig);
125+
return new NewScannerEngineFacade(adaptedProperties, launcher, isSonarCloud, serverVersion);
125126
} else {
126127
var launcher = launcherFactory.createLauncher(scannerHttpClient, fileCache);
127-
var adaptedProperties = adaptDeprecatedProperties(properties, httpConfig);
128+
var adaptedProperties = adaptDeprecatedPropertiesForInProcessBootstrapping(properties, httpConfig);
128129
return new InProcessScannerEngineFacade(adaptedProperties, launcher, false, serverVersion);
129130
}
130131
}
131132

133+
/**
134+
* New versions of SonarQube/SonarCloud will run on a separate VM. For people who used to rely on configuring SSL
135+
* by inserting the trusted certificate in the Scanner JVM truststore,
136+
* we need to adapt the properties to read from the truststore of the scanner JVM.
137+
*/
138+
Map<String, String> adaptDeprecatedPropertiesForForkedBootstrapping(Map<String, String> properties, HttpConfig httpConfig) {
139+
var adaptedProperties = new HashMap<>(properties);
140+
if (system.getProperty("javax.net.ssl.trustStore") == null && httpConfig.getSslConfig().getTrustStore() == null) {
141+
var defaultJvmTrustStoreLocation = Paths.get(System.getProperty("java.home"), "lib", "security", "cacerts");
142+
if (Files.isRegularFile(defaultJvmTrustStoreLocation)) {
143+
LOG.debug("Mapping default scanner JVM truststore location '{}' to new properties", defaultJvmTrustStoreLocation);
144+
adaptedProperties.put("sonar.scanner.truststorePath", defaultJvmTrustStoreLocation.toString());
145+
adaptedProperties.put("sonar.scanner.truststorePassword", System.getProperty("javax.net.ssl.trustStorePassword", "changeit"));
146+
}
147+
}
148+
return Map.copyOf(adaptedProperties);
149+
}
150+
132151
/**
133152
* Older SonarQube versions used to rely on some different properties, or even {@link System} properties.
134153
* For backward compatibility, we adapt the new properties to the old format.
135154
*/
136-
@Nonnull
137-
Map<String, String> adaptDeprecatedProperties(Map<String, String> properties, HttpConfig httpConfig) {
155+
Map<String, String> adaptDeprecatedPropertiesForInProcessBootstrapping(Map<String, String> properties, HttpConfig httpConfig) {
138156
var adaptedProperties = new HashMap<>(properties);
139157
if (!adaptedProperties.containsKey(HttpConfig.READ_TIMEOUT_SEC_PROPERTY)) {
140158
adaptedProperties.put(HttpConfig.READ_TIMEOUT_SEC_PROPERTY, "" + httpConfig.getSocketTimeout().get(ChronoUnit.SECONDS));

lib/src/main/java/org/sonarsource/scanner/lib/internal/http/OkHttpClientFactory.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,11 +113,11 @@ private static SSLFactory configureSsl(SslConfig sslConfig) {
113113
sslFactoryBuilder.withSystemPropertyDerivedIdentityMaterial();
114114
}
115115
var keyStoreConfig = sslConfig.getKeyStore();
116-
if (keyStoreConfig != null && Files.exists(keyStoreConfig.getPath())) {
116+
if (keyStoreConfig != null) {
117117
sslFactoryBuilder.withIdentityMaterial(keyStoreConfig.getPath(), keyStoreConfig.getKeyStorePassword().toCharArray(), keyStoreConfig.getKeyStoreType());
118118
}
119119
var trustStoreConfig = sslConfig.getTrustStore();
120-
if (trustStoreConfig != null && Files.exists(trustStoreConfig.getPath())) {
120+
if (trustStoreConfig != null) {
121121
KeyStore trustStore = loadKeyStoreWithBouncyCastle(
122122
trustStoreConfig.getPath(),
123123
trustStoreConfig.getKeyStorePassword().toCharArray(),

lib/src/test/java/org/sonarsource/scanner/lib/ScannerEngineBootstrapperTest.java

Lines changed: 41 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -269,7 +269,7 @@ void should_set_deprecated_timeout_property() {
269269

270270
when(httpConfig.getSocketTimeout()).thenReturn(Duration.ofSeconds(100));
271271

272-
var adapted = underTest.adaptDeprecatedProperties(Map.of(), httpConfig);
272+
var adapted = underTest.adaptDeprecatedPropertiesForInProcessBootstrapping(Map.of(), httpConfig);
273273
assertThat(adapted).containsEntry("sonar.ws.timeout", "100");
274274
}
275275

@@ -282,7 +282,7 @@ void should_set_deprecated_proxy_properties() {
282282

283283
when(httpConfig.getProxy()).thenReturn(new Proxy(Proxy.Type.HTTP, new InetSocketAddress("myproxy", 8080)));
284284

285-
underTest.adaptDeprecatedProperties(Map.of(), httpConfig);
285+
underTest.adaptDeprecatedPropertiesForInProcessBootstrapping(Map.of(), httpConfig);
286286

287287
assertThat(System.getProperties()).contains(
288288
entry("http.proxyHost", "myproxy"),
@@ -302,12 +302,50 @@ void should_set_deprecated_ssl_properties() {
302302
new CertificateStore(Paths.get("some/keystore.p12"), "keystorePass"),
303303
new CertificateStore(Paths.get("some/truststore.p12"), "truststorePass")));
304304

305-
underTest.adaptDeprecatedProperties(Map.of(), httpConfig);
305+
underTest.adaptDeprecatedPropertiesForInProcessBootstrapping(Map.of(), httpConfig);
306306

307307
assertThat(System.getProperties()).contains(
308308
entry("javax.net.ssl.keyStore", "some/keystore.p12"),
309309
entry("javax.net.ssl.keyStorePassword", "keystorePass"),
310310
entry("javax.net.ssl.trustStore", "some/truststore.p12"),
311311
entry("javax.net.ssl.trustStorePassword", "truststorePass"));
312312
}
313+
314+
@Test
315+
void should_set_ssl_properties_from_cacerts() {
316+
var httpConfig = mock(HttpConfig.class);
317+
when(httpConfig.getSslConfig()).thenReturn(new SslConfig(null, null));
318+
319+
var adapted = underTest.adaptDeprecatedPropertiesForForkedBootstrapping(Map.of(), httpConfig);
320+
321+
assertThat(adapted).contains(
322+
entry("sonar.scanner.truststorePath", Paths.get(System.getProperty("java.home"), "lib", "security", "cacerts").toString()),
323+
entry("sonar.scanner.truststorePassword", "changeit"));
324+
}
325+
326+
@Test
327+
void should_not_set_ssl_properties_from_cacerts_if_already_set_as_scanner_props(@TempDir Path tempDir) throws IOException {
328+
var cacerts = tempDir.resolve("truststore.p12");
329+
Files.createFile(cacerts);
330+
var httpConfig = mock(HttpConfig.class);
331+
when(httpConfig.getSslConfig()).thenReturn(new SslConfig(null, new CertificateStore(cacerts, "something")));
332+
333+
var adapted = underTest.adaptDeprecatedPropertiesForForkedBootstrapping(Map.of(), httpConfig);
334+
335+
assertThat(adapted).isEmpty();
336+
}
337+
338+
@Test
339+
void should_not_set_ssl_properties_from_cacerts_if_already_set_as_JVM_props(@TempDir Path tempDir) throws IOException {
340+
var cacerts = tempDir.resolve("truststore.p12");
341+
Files.createFile(cacerts);
342+
var httpConfig = mock(HttpConfig.class);
343+
when(httpConfig.getSslConfig()).thenReturn(new SslConfig(null, null));
344+
345+
when(system.getProperty("javax.net.ssl.trustStore")).thenReturn(cacerts.toString());
346+
347+
var adapted = underTest.adaptDeprecatedPropertiesForForkedBootstrapping(Map.of(), httpConfig);
348+
349+
assertThat(adapted).isEmpty();
350+
}
313351
}

0 commit comments

Comments
 (0)