From 7ebb457c3d99ed0d71d57ea43406f3cd0342dab2 Mon Sep 17 00:00:00 2001 From: irengrig Date: Mon, 28 Jan 2013 17:21:04 +0400 Subject: [PATCH] Subversion: allow to define SSL protocol in settings (important since in jdk 1.6 and maybe 1.7 they have a bug with 'all' protocols defined from client - connection is not successful) for IDEA-90674 Checkout from https SVN Repository problem --- .../jetbrains/idea/svn/SvnConfigurable.form | 62 ++++++++++++++++++- .../jetbrains/idea/svn/SvnConfigurable.java | 47 ++++++++++++++ .../jetbrains/idea/svn/SvnConfiguration.java | 15 +++++ .../src/org/jetbrains/idea/svn/SvnVcs.java | 23 +++++-- 4 files changed, 140 insertions(+), 7 deletions(-) diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form index 39bb9355c6a7..5a95d28b5b14 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.form @@ -227,7 +227,7 @@ - + @@ -237,7 +237,7 @@ - + @@ -251,7 +251,7 @@ - + @@ -387,6 +387,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java index efb1da21c511..e7e26ca894cf 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfigurable.java @@ -28,10 +28,12 @@ import com.intellij.openapi.project.Project; import com.intellij.openapi.ui.Messages; import com.intellij.openapi.ui.TextFieldWithBrowseButton; import com.intellij.openapi.util.Comparing; +import com.intellij.openapi.util.SystemInfo; import com.intellij.openapi.vfs.VirtualFile; import com.intellij.openapi.vfs.VirtualFileManager; import com.intellij.ui.MultiLineTooltipUI; import com.intellij.ui.components.JBCheckBox; +import com.intellij.ui.components.JBRadioButton; import com.intellij.util.Consumer; import org.jetbrains.annotations.NonNls; import org.jetbrains.annotations.NotNull; @@ -67,6 +69,10 @@ public class SvnConfigurable implements Configurable { private JSpinner mySSHReadTimeout; private TextFieldWithBrowseButton myCommandLineClient; private JSpinner myHttpTimeout; + private JBRadioButton mySSLv3RadioButton; + private JBRadioButton myTLSv1RadioButton; + private JBRadioButton myAllRadioButton; + private JLabel mySSLExplicitly; @NonNls private static final String HELP_ID = "project.propSubversion"; @@ -130,6 +136,29 @@ public class SvnConfigurable implements Configurable { } }); myNumRevsInAnnotations.setEnabled(myMaximumNumberOfRevisionsCheckBox.isSelected()); + + final ButtonGroup bg = new ButtonGroup(); + bg.add(mySSLv3RadioButton); + bg.add(myTLSv1RadioButton); + bg.add(myAllRadioButton); + if (SvnVcs.isSSLProtocolExplicitlySet()) { + mySSLv3RadioButton.setEnabled(false); + myTLSv1RadioButton.setEnabled(false); + myAllRadioButton.setEnabled(false); + mySSLExplicitly.setVisible(true); + mySSLExplicitly.setText("Set explicitly to: " + System.getProperty(SvnVcs.SVNKIT_HTTP_SSL_PROTOCOLS)); + } else { + mySSLv3RadioButton.setEnabled(true); + myTLSv1RadioButton.setEnabled(true); + myAllRadioButton.setEnabled(true); + mySSLExplicitly.setVisible(false); + final String version = SystemInfo.JAVA_RUNTIME_VERSION; + final boolean jdkBugFixed = version.startsWith("1.7") || version.startsWith("1.8"); + if (! jdkBugFixed) { + mySSLExplicitly.setVisible(true); + mySSLExplicitly.setText("Setting 'All' value in this JDK version (" + version + ") is not recommended."); + } + } } public static void selectConfigirationDirectory(@NotNull String path, @NotNull final Consumer dirConsumer, @@ -190,6 +219,13 @@ public class SvnConfigurable implements Configurable { return HELP_ID; } + private SvnConfiguration.SSLProtocols getSelectedSSL() { + if (myAllRadioButton.isSelected()) return SvnConfiguration.SSLProtocols.all; + if (mySSLv3RadioButton.isSelected()) return SvnConfiguration.SSLProtocols.sslv3; + if (myTLSv1RadioButton.isSelected()) return SvnConfiguration.SSLProtocols.tlsv1; + throw new IllegalStateException(); + } + public boolean isModified() { if (myComponent == null) { return false; @@ -233,6 +269,7 @@ public class SvnConfigurable implements Configurable { if (configuration.getHttpTimeout()/1000 != ((SpinnerNumberModel) myHttpTimeout.getModel()).getNumber().longValue()) { return true; } + if (! getSelectedSSL().equals(configuration.SSL_PROTOCOLS)) return true; final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance(); if (! Comparing.equal(applicationSettings17.getCommandLinePath(), myCommandLineClient.getText().trim())) return true; return !configuration.getConfigurationDirectory().equals(myConfigurationDirectoryText.getText().trim()); @@ -265,6 +302,8 @@ public class SvnConfigurable implements Configurable { configuration.mySSHConnectionTimeout = ((SpinnerNumberModel) mySSHConnectionTimeout.getModel()).getNumber().longValue() * 1000; configuration.mySSHReadTimeout = ((SpinnerNumberModel) mySSHReadTimeout.getModel()).getNumber().longValue() * 1000; configuration.myUseAcceleration = acceleration(); + configuration.SSL_PROTOCOLS = getSelectedSSL(); + SvnVcs.getInstance(myProject).refreshSSLProperty(); final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance(); applicationSettings17.setCommandLinePath(myCommandLineClient.getText().trim()); @@ -307,6 +346,14 @@ public class SvnConfigurable implements Configurable { setAcceleration(configuration.myUseAcceleration); final SvnApplicationSettings applicationSettings17 = SvnApplicationSettings.getInstance(); myCommandLineClient.setText(applicationSettings17.getCommandLinePath()); + + if (SvnConfiguration.SSLProtocols.sslv3.equals(configuration.SSL_PROTOCOLS)) { + mySSLv3RadioButton.setSelected(true); + } else if (SvnConfiguration.SSLProtocols.tlsv1.equals(configuration.SSL_PROTOCOLS)) { + myTLSv1RadioButton.setSelected(true); + } else { + myAllRadioButton.setSelected(true); + } } public void disposeUIResources() { diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java index 08faa52a9218..14c005427be6 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnConfiguration.java @@ -109,6 +109,8 @@ public class SvnConfiguration implements PersistentStateComponent { public boolean FORCE_UPDATE = false; public boolean IGNORE_EXTERNALS = false; public Boolean TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE; + public SSLProtocols SSL_PROTOCOLS = (SystemInfo.JAVA_RUNTIME_VERSION.startsWith("1.7") || SystemInfo.JAVA_RUNTIME_VERSION.startsWith("1.8")) ? + SSLProtocols.all : SSLProtocols.sslv3; public UseAcceleration myUseAcceleration = UseAcceleration.nothing; @@ -434,6 +436,14 @@ public class SvnConfiguration implements PersistentStateComponent { myCleanupRun = Boolean.parseBoolean(cleanupRun.getValue()); } final Attribute treeConflictMergeNewFilesPlace = element.getAttribute("TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE"); + final Attribute protocols = element.getAttribute("SSL_PROTOCOLS"); + if (protocols != null) { + try { + SSL_PROTOCOLS = SSLProtocols.valueOf(protocols.getValue()); + } catch (IllegalArgumentException e) { + // + } + } if (treeConflictMergeNewFilesPlace != null) { TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE = Boolean.parseBoolean(treeConflictMergeNewFilesPlace.getValue()); } @@ -472,6 +482,7 @@ public class SvnConfiguration implements PersistentStateComponent { element.setAttribute("myUseAcceleration", "" + myUseAcceleration); element.setAttribute("myAutoUpdateAfterCommit", "" + myAutoUpdateAfterCommit); element.setAttribute(CLEANUP_ON_START_RUN, "" + myCleanupRun); + element.setAttribute("SSL_PROTOCOLS", SSL_PROTOCOLS.name()); if (TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE != null) { element.setAttribute("TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE", "" + TREE_CONFLICT_MERGE_THEIRS_NEW_INTO_OLD_PLACE); } @@ -611,4 +622,8 @@ public class SvnConfiguration implements PersistentStateComponent { public void setCleanupRun(boolean cleanupRun) { myCleanupRun = cleanupRun; } + + public static enum SSLProtocols { + sslv3, tlsv1, all + } } diff --git a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java index 9799f33a7183..4636a493fe39 100644 --- a/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java +++ b/plugins/svn4idea/src/org/jetbrains/idea/svn/SvnVcs.java @@ -167,6 +167,7 @@ public class SvnVcs extends AbstractVcs { private final SvnLoadedBrachesStorage myLoadedBranchesStorage; public static final String SVNKIT_HTTP_SSL_PROTOCOLS = "svnkit.http.sslProtocols"; + private static boolean ourSSLProtocolsExplicitlySet = false; private final SvnExecutableChecker myChecker; public static final Processor ourBusyExceptionProcessor = new Processor() { @@ -215,10 +216,11 @@ public class SvnVcs extends AbstractVcs { } initLogFilters(); - // Alexander Kitaev says it is default value (SSLv3) - since 8254 - if (!SystemInfo.JAVA_RUNTIME_VERSION.startsWith("1.7") && System.getProperty(SVNKIT_HTTP_SSL_PROTOCOLS) == null) { - System.setProperty(SVNKIT_HTTP_SSL_PROTOCOLS, "SSLv3"); - } + ourSSLProtocolsExplicitlySet = System.getProperty(SVNKIT_HTTP_SSL_PROTOCOLS) != null; + } + + public static boolean isSSLProtocolExplicitlySet() { + return ourSSLProtocolsExplicitlySet; } public SvnVcs(final Project project, MessageBus bus, SvnConfiguration svnConfiguration, final SvnLoadedBrachesStorage storage) { @@ -240,6 +242,8 @@ public class SvnVcs extends AbstractVcs { dumpFileStatus(SvnFileStatus.EXTERNAL); dumpFileStatus(SvnFileStatus.OBSTRUCTED); + refreshSSLProperty(); + final ProjectLevelVcsManager vcsManager = ProjectLevelVcsManager.getInstance(project); myAddConfirmation = vcsManager.getStandardConfirmation(VcsConfiguration.StandardConfirmation.ADD, this); myDeleteConfirmation = vcsManager.getStandardConfirmation(VcsConfiguration.StandardConfirmation.REMOVE, this); @@ -922,6 +926,17 @@ public class SvnVcs extends AbstractVcs { } } + public void refreshSSLProperty() { + if (ourSSLProtocolsExplicitlySet) return; + if (SvnConfiguration.SSLProtocols.all.equals(myConfiguration.SSL_PROTOCOLS)) { + System.clearProperty(SVNKIT_HTTP_SSL_PROTOCOLS); + } else if (SvnConfiguration.SSLProtocols.sslv3.equals(myConfiguration.SSL_PROTOCOLS)) { + System.setProperty(SVNKIT_HTTP_SSL_PROTOCOLS, "SSLv3"); + } else if (SvnConfiguration.SSLProtocols.tlsv1.equals(myConfiguration.SSL_PROTOCOLS)) { + System.setProperty(SVNKIT_HTTP_SSL_PROTOCOLS, "TLSv1"); + } + } + private static class JavaSVNDebugLogger extends SVNDebugLogAdapter { private final boolean myLoggingEnabled; private final boolean myLogNative;