Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@

import javax.annotation.CheckForNull;
import javax.annotation.Nullable;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;

Expand All @@ -44,6 +45,7 @@ public class ServerConfiguration {
private final int readTimeoutMs;
private SSLSocketFactory sslSocketFactory = null;
private X509TrustManager sslTrustManager = null;
private HostnameVerifier hostnameVerifier = null;

private ServerConfiguration(Builder builder) {
this.url = builder.url;
Expand All @@ -58,6 +60,7 @@ private ServerConfiguration(Builder builder) {
this.readTimeoutMs = builder.readTimeoutMs;
this.sslSocketFactory = builder.sslSocketFactory;
this.sslTrustManager = builder.sslTrustManager;
this.hostnameVerifier = builder.hostnameVerifier;
}

@Override
Expand Down Expand Up @@ -116,6 +119,11 @@ public SSLSocketFactory getSSLSocketFactory() {
return sslSocketFactory;
}

@CheckForNull
public HostnameVerifier getHostnameVerifier() {
return hostnameVerifier;
}

@CheckForNull
public String getPassword() {
return password;
Expand Down Expand Up @@ -161,6 +169,7 @@ public static class Builder {
private int readTimeoutMs = DEFAULT_READ_TIMEOUT_MILLISECONDS;
private SSLSocketFactory sslSocketFactory = null;
private X509TrustManager sslTrustManager = null;
private HostnameVerifier hostnameVerifier = null;

private Builder() {
}
Expand Down Expand Up @@ -200,6 +209,11 @@ public Builder trustManager(X509TrustManager sslTrustManager) {
return this;
}

public Builder hostnameVerifier(HostnameVerifier hostnameVerifier) {
this.hostnameVerifier = hostnameVerifier;
return this;
}

/**
* Optional login/password, for example "admin"
*/
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ private static WsConnector buildClient(ServerConfiguration serverConfig) {
.connectTimeoutMilliseconds(serverConfig.getConnectTimeoutMs())
.setSSLSocketFactory(serverConfig.getSSLSocketFactory())
.setTrustManager(serverConfig.getTrustManager())
.setHostnameVerifier(serverConfig.getHostnameVerifier())
.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
import java.net.Proxy;
import java.util.Map;
import javax.annotation.Nullable;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
import okhttp3.Call;
Expand Down Expand Up @@ -83,6 +84,7 @@ private HttpConnector(Builder builder) {
okHttpClientBuilder.setReadTimeoutMs(builder.readTimeoutMs);
okHttpClientBuilder.setSSLSocketFactory(builder.sslSocketFactory);
okHttpClientBuilder.setTrustManager(builder.sslTrustManager);
okHttpClientBuilder.setHostnameVerifier(builder.hostnameVerifier);
this.okHttpClient = okHttpClientBuilder.build();
this.noRedirectOkHttpClient = newClientWithoutRedirect(this.okHttpClient);
}
Expand Down Expand Up @@ -251,6 +253,7 @@ public static class Builder {
private int readTimeoutMs = DEFAULT_READ_TIMEOUT_MILLISECONDS;
private SSLSocketFactory sslSocketFactory = null;
private X509TrustManager sslTrustManager = null;
private HostnameVerifier hostnameVerifier = null;

/**
* Private since 5.5.
Expand Down Expand Up @@ -320,6 +323,14 @@ public Builder setTrustManager(@Nullable X509TrustManager sslTrustManager) {
return this;
}

/**
* Optional hostname verifier.
*/
public Builder setHostnameVerifier(@Nullable HostnameVerifier hostnameVerifier) {
this.hostnameVerifier = hostnameVerifier;
return this;
}

/**
* Sets the read timeout to a specified timeout, in milliseconds.
* A timeout of zero is interpreted as an infinite timeout. Default value is {@link #DEFAULT_READ_TIMEOUT_MILLISECONDS}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@
*/
package org.sonarsource.sonarlint.core.util.ws;

import static java.util.Arrays.asList;
import static org.apache.commons.lang.StringUtils.defaultString;

import java.io.FileInputStream;
import java.io.IOException;
import java.net.Proxy;
Expand All @@ -32,6 +35,7 @@
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.KeyManager;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
Expand All @@ -46,9 +50,6 @@
import okhttp3.Request;
import okhttp3.Response;

import static java.util.Arrays.asList;
import static org.apache.commons.lang.StringUtils.defaultString;

/**
* Helper to build an instance of {@link okhttp3.OkHttpClient} that
* correctly supports HTTPS and proxy authentication. It also handles
Expand All @@ -69,6 +70,7 @@ public class OkHttpClientBuilder {
private long readTimeoutMs = -1;
private SSLSocketFactory sslSocketFactory = null;
private X509TrustManager sslTrustManager = null;
private HostnameVerifier hostnameVerifier = null;

/**
* Optional User-Agent. If set, then all the requests sent by the
Expand Down Expand Up @@ -97,6 +99,14 @@ public OkHttpClientBuilder setTrustManager(@Nullable X509TrustManager sslTrustMa
return this;
}

/**
* Optional Hostname Verifier.
*/
public OkHttpClientBuilder setHostnameVerifier(@Nullable HostnameVerifier hostnameVerifier) {
this.hostnameVerifier = hostnameVerifier;
return this;
}

/**
* Optional proxy. If set, then all the requests sent by the
* {@link OkHttpClient} will reach the proxy. If not set,
Expand Down Expand Up @@ -189,7 +199,9 @@ public OkHttpClient build() {
X509TrustManager trustManager = sslTrustManager != null ? sslTrustManager : systemDefaultTrustManager();
SSLSocketFactory sslFactory = sslSocketFactory != null ? sslSocketFactory : systemDefaultSslSocketFactory(trustManager);
builder.sslSocketFactory(sslFactory, trustManager);

if (hostnameVerifier != null) {
builder.hostnameVerifier(hostnameVerifier);
}
return builder.build();
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,10 @@
*/
package org.sonarlint.languageserver;

import static java.util.Collections.singleton;
import static java.util.Objects.nonNull;
import static org.apache.commons.lang.StringUtils.isBlank;

import com.google.gson.Gson;
import com.google.gson.JsonElement;
import com.google.gson.JsonSyntaxException;
Expand All @@ -34,6 +38,9 @@
import java.nio.file.Path;
import java.nio.file.PathMatcher;
import java.nio.file.Paths;
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.X509Certificate;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
Expand All @@ -51,6 +58,10 @@
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.X509TrustManager;
import org.eclipse.lsp4j.CodeAction;
import org.eclipse.lsp4j.CodeActionParams;
import org.eclipse.lsp4j.CodeLens;
Expand Down Expand Up @@ -108,7 +119,6 @@
import org.eclipse.lsp4j.services.TextDocumentService;
import org.eclipse.lsp4j.services.WorkspaceService;
import org.sonar.api.internal.apachecommons.lang.StringUtils;
import org.sonar.api.rule.RuleKey;
import org.sonarsource.sonarlint.core.client.api.common.RuleDetails;
import org.sonarsource.sonarlint.core.client.api.common.analysis.AnalysisResults;
import org.sonarsource.sonarlint.core.client.api.common.analysis.ClientInputFile;
Expand All @@ -128,10 +138,6 @@
import org.sonarsource.sonarlint.core.client.api.util.FileUtils;
import org.sonarsource.sonarlint.core.telemetry.TelemetryPathManager;

import static java.util.Collections.singleton;
import static java.util.Objects.nonNull;
import static org.apache.commons.lang.StringUtils.isBlank;

public class SonarLintLanguageServer implements LanguageServer, WorkspaceService, TextDocumentService {
private static final String USER_AGENT = "CodeScan Language Server";

Expand Down Expand Up @@ -329,13 +335,34 @@ private void updateServerStorage(ConnectedSonarLintEngine engine, ServerInfo ser
}

private static ServerConfiguration getServerConfiguration(ServerInfo serverInfo) {
X509TrustManager trustManager = null;
SSLSocketFactory socketFactory = null;
HostnameVerifier hostnameVerifier = null;

if (Boolean.parseBoolean(System.getProperty("http.allowUntrustedSsl"))) {
trustManager = new SelfSignedSslTrustManager();

try {
SSLContext sslContext = SSLContext.getInstance("SSL");
sslContext.init(null, new X509TrustManager[] {trustManager}, new java.security.SecureRandom());
socketFactory = sslContext.getSocketFactory();
} catch (KeyManagementException | NoSuchAlgorithmException e) {
throw new IllegalStateException(e.getMessage(), e);
}

hostnameVerifier = (hostname, session) -> true;
}

return ServerConfiguration.builder()
.url(serverInfo.serverUrl)
.token(serverInfo.token)
.organizationKey(serverInfo.organizationKey)
.userAgent(USER_AGENT)
.proxyCredentials(System.getProperty("http.proxyUser"), System.getProperty("http.proxyPassword"))
.build();
.url(serverInfo.serverUrl)
.token(serverInfo.token)
.organizationKey(serverInfo.organizationKey)
.userAgent(USER_AGENT)
.proxyCredentials(System.getProperty("http.proxyUser"), System.getProperty("http.proxyPassword"))
.trustManager(trustManager)
.sslSocketFactory(socketFactory)
.hostnameVerifier(hostnameVerifier)
.build();
}

private void updateBinding(@Nullable Map<?, ?> connectedModeProject) {
Expand Down Expand Up @@ -981,4 +1008,24 @@ static class ServerProjectBinding {
this.projectKey = projectKey;
}
}

/**
* Custom trust manager which helps to accept self-signed untrusted certificates.
*/
private static class SelfSignedSslTrustManager implements X509TrustManager {

@Override
public X509Certificate[] getAcceptedIssuers() {
return new X509Certificate[0];
}

@Override
public void checkServerTrusted(X509Certificate[] chain, String authType) {
}

@Override
public void checkClientTrusted(X509Certificate[] chain, String authType) {
}
}

}