diff --git a/plugins/maven-server-api/src/main/java/org/jetbrains/idea/maven/server/RemoteMavenServerBase.java b/plugins/maven-server-api/src/main/java/org/jetbrains/idea/maven/server/RemoteMavenServerBase.java index 2bf30ceec925..ff8bc7be548d 100644 --- a/plugins/maven-server-api/src/main/java/org/jetbrains/idea/maven/server/RemoteMavenServerBase.java +++ b/plugins/maven-server-api/src/main/java/org/jetbrains/idea/maven/server/RemoteMavenServerBase.java @@ -6,7 +6,7 @@ import org.jetbrains.idea.maven.server.security.ssl.SslIDEConfirmingTrustStore; public class RemoteMavenServerBase extends RemoteServer { protected static void startMavenServer(MavenServerBase mavenServer, String[] args) throws Exception { - if(System.getProperty("delegate.ssl.to.ide")!=null) { + if (Boolean.getBoolean("delegate.ssl.to.ide")) { setupDelegatingSsl(); } diff --git a/plugins/maven-server-api/src/main/java/org/jetbrains/idea/maven/server/security/ssl/SslIDEConfirmingTrustStore.java b/plugins/maven-server-api/src/main/java/org/jetbrains/idea/maven/server/security/ssl/SslIDEConfirmingTrustStore.java index 7d712567fcb8..6dcc06ee7f40 100644 --- a/plugins/maven-server-api/src/main/java/org/jetbrains/idea/maven/server/security/ssl/SslIDEConfirmingTrustStore.java +++ b/plugins/maven-server-api/src/main/java/org/jetbrains/idea/maven/server/security/ssl/SslIDEConfirmingTrustStore.java @@ -1,19 +1,25 @@ // Copyright 2000-2024 JetBrains s.r.o. and contributors. Use of this source code is governed by the Apache 2.0 license. package org.jetbrains.idea.maven.server.security.ssl; +import org.jetbrains.idea.maven.server.MavenServerGlobals; + import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManager; +import javax.net.ssl.TrustManagerFactory; import javax.net.ssl.X509TrustManager; import java.io.ByteArrayOutputStream; import java.io.PrintStream; import java.io.UnsupportedEncodingException; import java.nio.charset.StandardCharsets; import java.security.KeyManagementException; +import java.security.KeyStore; +import java.security.KeyStoreException; import java.security.NoSuchAlgorithmException; import java.security.cert.CertificateEncodingException; import java.security.cert.CertificateException; import java.security.cert.X509Certificate; -import java.util.Base64; +import java.util.*; +import java.util.concurrent.ConcurrentHashMap; public final class SslIDEConfirmingTrustStore { @@ -40,7 +46,8 @@ public final class SslIDEConfirmingTrustStore { // it depends on the library you're using. SSLContext.setDefault(sslContext); } - catch (NoSuchAlgorithmException | KeyManagementException ignore) { + catch (NoSuchAlgorithmException | KeyManagementException | KeyStoreException e) { + MavenServerGlobals.getLogger().error(e); } } @@ -48,10 +55,56 @@ public final class SslIDEConfirmingTrustStore { ourMultiplexor.start(); } + private static class TrustRequestKey { + private final X509Certificate[] myChain; + private final String myType; + + TrustRequestKey(X509Certificate[] chain, String authType) { + myChain = chain; + myType = authType; + } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (!(o instanceof TrustRequestKey)) return false; + TrustRequestKey key = (TrustRequestKey)o; + return Objects.deepEquals(myChain, key.myChain) && Objects.equals(myType, key.myType); + } + + @Override + public int hashCode() { + return Objects.hash(Arrays.hashCode(myChain), myType); + } + } + private static class IdeDelegateTrustManager implements X509TrustManager { + private ConcurrentHashMap succeed = new ConcurrentHashMap<>(); + private final List myTrustManagers; + + IdeDelegateTrustManager() throws NoSuchAlgorithmException, KeyStoreException { + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); + trustManagerFactory.init((KeyStore)null); + myTrustManagers = new ArrayList<>(); + + for (TrustManager m : trustManagerFactory.getTrustManagers()) { + if (m instanceof X509TrustManager) { + myTrustManagers.add((X509TrustManager)m); + } + } + } + @Override public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException { - checkTrusted(chain, authType, CHECK_CLIENT_TRUSTED); + for (X509TrustManager m : myTrustManagers) { + try { + m.checkClientTrusted(chain, authType); + return; + } + catch (CertificateException ignore) { + } + } + throw new CertificateException(); } @SuppressWarnings("UseOfSystemOutOrSystemErr") @@ -64,10 +117,24 @@ public final class SslIDEConfirmingTrustStore { @Override public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException { - checkTrusted(chain, authType, CHECK_SERVER_TRUSTED); + for (X509TrustManager m : myTrustManagers) { + try { + m.checkClientTrusted(chain, authType); + return; + } + catch (CertificateException ignore) { + } + } + TrustRequestKey key = new TrustRequestKey(chain, authType); + Boolean cached = succeed.get(key); + if (cached != null && cached) { + return; + } + doCheckTrusted(chain, authType, CHECK_SERVER_TRUSTED); + succeed.put(key, Boolean.TRUE); } - private void checkTrusted(X509Certificate[] chain, String authType, String methodSignature) throws CertificateException { + private void doCheckTrusted(X509Certificate[] chain, String authType, String methodSignature) throws CertificateException { ByteArrayOutputStream os = new ByteArrayOutputStream(); Integer key = ourMultiplexor.getKey(); try (PrintStream out = new PrintStream(os, false, "ISO-8859-1")) { diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerCMDState.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerCMDState.java index c098714e44e5..b72f260530e1 100644 --- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerCMDState.java +++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/server/MavenServerCMDState.java @@ -112,6 +112,10 @@ public class MavenServerCMDState extends CommandLineState { params.getVMParametersList().addProperty("maven.collect.local.stat", "true"); } + if (Registry.is("maven.delegate.trust.ssl.to.ide")) { + params.getVMParametersList().addProperty("delegate.ssl.to.ide", "true"); + } + String profilerOption = getProfilerVMString(); if (profilerOption != null) { params.getVMParametersList() diff --git a/plugins/maven/src/main/resources/META-INF/plugin.xml b/plugins/maven/src/main/resources/META-INF/plugin.xml index 99d2bda8653a..cf18f34671de 100644 --- a/plugins/maven/src/main/resources/META-INF/plugin.xml +++ b/plugins/maven/src/main/resources/META-INF/plugin.xml @@ -402,6 +402,9 @@ + + XML org.jetbrains.idea.maven.dom.converters.MavenArtifactCoordinatesConverter$MyUpdateIndicesIntention