Repository: geode Updated Branches: refs/heads/develop 31e82d6d6 -> b77e1c7d1
GEODE-3445: Add gfsh connect option --skip-ssl-validation Project: http://git-wip-us.apache.org/repos/asf/geode/repo Commit: http://git-wip-us.apache.org/repos/asf/geode/commit/b77e1c7d Tree: http://git-wip-us.apache.org/repos/asf/geode/tree/b77e1c7d Diff: http://git-wip-us.apache.org/repos/asf/geode/diff/b77e1c7d Branch: refs/heads/develop Commit: b77e1c7d1e1dc31a539496483c8e9f739155f021 Parents: 31e82d6 Author: Jared Stewart <[email protected]> Authored: Mon Aug 21 14:02:36 2017 -0700 Committer: Jared Stewart <[email protected]> Committed: Tue Aug 22 12:03:00 2017 -0700 ---------------------------------------------------------------------- ...shConnectToLocatorWithSSLAcceptanceTest.java | 110 +++++++++++++++++++ .../geode/test/dunit/rules/gfsh/GfshRule.java | 5 +- .../geode/test/dunit/rules/gfsh/GfshScript.java | 12 +- .../internal/cli/commands/ConnectCommand.java | 17 +-- 4 files changed, 131 insertions(+), 13 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/geode/blob/b77e1c7d/geode-assembly/src/test/java/org/apache/geode/management/GfshConnectToLocatorWithSSLAcceptanceTest.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/management/GfshConnectToLocatorWithSSLAcceptanceTest.java b/geode-assembly/src/test/java/org/apache/geode/management/GfshConnectToLocatorWithSSLAcceptanceTest.java new file mode 100644 index 0000000..75d60a3 --- /dev/null +++ b/geode-assembly/src/test/java/org/apache/geode/management/GfshConnectToLocatorWithSSLAcceptanceTest.java @@ -0,0 +1,110 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more contributor license + * agreements. See the NOTICE file distributed with this work for additional information regarding + * copyright ownership. The ASF licenses this file to You under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the License. You may obtain a + * copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software distributed under the License + * is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express + * or implied. See the License for the specific language governing permissions and limitations under + * the License. + */ +package org.apache.geode.management; + +import static org.apache.geode.distributed.ConfigurationProperties.SSL_CIPHERS; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_ENABLED_COMPONENTS; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_PASSWORD; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_KEYSTORE_TYPE; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_PROTOCOLS; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE_PASSWORD; +import static org.apache.geode.distributed.ConfigurationProperties.SSL_TRUSTSTORE_TYPE; +import static org.apache.geode.util.test.TestUtil.getResourcePath; +import static org.assertj.core.api.Assertions.assertThat; + +import java.io.File; +import java.io.FileOutputStream; +import java.io.IOException; +import java.util.Properties; + +import org.junit.Before; +import org.junit.Rule; +import org.junit.Test; +import org.junit.experimental.categories.Category; +import org.junit.rules.TemporaryFolder; + +import org.apache.geode.security.SecurableCommunicationChannels; +import org.apache.geode.test.dunit.rules.gfsh.GfshRule; +import org.apache.geode.test.dunit.rules.gfsh.GfshScript; +import org.apache.geode.test.junit.categories.AcceptanceTest; + +@Category(AcceptanceTest.class) +public class GfshConnectToLocatorWithSSLAcceptanceTest { + @Rule + public GfshRule gfshRule = new GfshRule(); + + @Rule + public TemporaryFolder temporaryFolder = new TemporaryFolder(); + + private File sslPropertiesFile; + + @Before + public void setup() throws IOException { + File jks = new File(getResourcePath(getClass(), "/ssl/trusted.keystore")); + assertThat(jks).exists(); + + Properties serverProps = new Properties(); + serverProps.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannels.ALL); + serverProps.setProperty(SSL_KEYSTORE, jks.getAbsolutePath()); + serverProps.setProperty(SSL_KEYSTORE_PASSWORD, "password"); + serverProps.setProperty(SSL_KEYSTORE_TYPE, "JKS"); + serverProps.setProperty(SSL_TRUSTSTORE, jks.getAbsolutePath()); + serverProps.setProperty(SSL_TRUSTSTORE_PASSWORD, "password"); + serverProps.setProperty(SSL_TRUSTSTORE_TYPE, "JKS"); + serverProps.setProperty(SSL_CIPHERS, "any"); + serverProps.setProperty(SSL_PROTOCOLS, "any"); + + sslPropertiesFile = temporaryFolder.newFile("ssl.properties"); + serverProps.store(new FileOutputStream(sslPropertiesFile), null); + + GfshScript startLocator = + GfshScript.of("start locator --name=locator --security-properties-file=" + + sslPropertiesFile.getAbsolutePath()); + gfshRule.execute(startLocator); + } + + @Test + public void canConnectOverHttpWithUnsignedSSLCertificateIfSkipSslValidationIsSet() + throws Exception { + GfshScript connect = + GfshScript.of("connect --use-http --skip-ssl-validation --security-properties-file=" + + sslPropertiesFile.getAbsolutePath()); + gfshRule.execute(connect); + } + + @Test + public void cannotConnectOverHttpWithUnsignedSSLCertificateIfSkipSslValidationIsNotSet() + throws Exception { + GfshScript connect = GfshScript + .of("connect --use-http --security-properties-file=" + sslPropertiesFile.getAbsolutePath()) + .expectFailure(); + gfshRule.execute(connect); + } + + @Test + public void cannotConnectOverHttpWithoutSSL() throws Exception { + GfshScript connect = GfshScript.of("connect --use-http").expectFailure(); + gfshRule.execute(connect); + } + + @Test + public void canConnectOverJmxWithSSL() throws Exception { + GfshScript connect = GfshScript.of("connect --use-http=false --security-properties-file=" + + sslPropertiesFile.getAbsolutePath()); + gfshRule.execute(connect); + } +} http://git-wip-us.apache.org/repos/asf/geode/blob/b77e1c7d/geode-assembly/src/test/java/org/apache/geode/test/dunit/rules/gfsh/GfshRule.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/test/dunit/rules/gfsh/GfshRule.java b/geode-assembly/src/test/java/org/apache/geode/test/dunit/rules/gfsh/GfshRule.java index fa25f14..f77cc77 100644 --- a/geode-assembly/src/test/java/org/apache/geode/test/dunit/rules/gfsh/GfshRule.java +++ b/geode-assembly/src/test/java/org/apache/geode/test/dunit/rules/gfsh/GfshRule.java @@ -31,7 +31,6 @@ import java.util.stream.Collectors; import org.junit.rules.ExternalResource; import org.junit.rules.TemporaryFolder; -import org.apache.geode.internal.lang.SystemUtils; import org.apache.geode.management.internal.cli.commands.StatusLocatorRealGfshTest; import org.apache.geode.management.internal.cli.util.CommandStringBuilder; import org.apache.geode.test.dunit.rules.RequiresGeodeHome; @@ -144,7 +143,7 @@ public class GfshRule extends ExternalResource { new CommandStringBuilder("stop server").addOption("dir", dir).toString(); GfshScript stopServerScript = - new GfshScript(stopServerCommand).withName("stop-server-teardown").awaitQuietly(); + new GfshScript(stopServerCommand).withName("teardown-stop-server").awaitQuietly(); execute(stopServerScript); } @@ -153,7 +152,7 @@ public class GfshRule extends ExternalResource { new CommandStringBuilder("stop locator").addOption("dir", dir).toString(); GfshScript stopServerScript = - new GfshScript(stopLocatorCommand).withName("stop-locator-teardown").awaitQuietly(); + new GfshScript(stopLocatorCommand).withName("teardown-stop-locator").awaitQuietly(); execute(stopServerScript); } http://git-wip-us.apache.org/repos/asf/geode/blob/b77e1c7d/geode-assembly/src/test/java/org/apache/geode/test/dunit/rules/gfsh/GfshScript.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/org/apache/geode/test/dunit/rules/gfsh/GfshScript.java b/geode-assembly/src/test/java/org/apache/geode/test/dunit/rules/gfsh/GfshScript.java index 52ef0d3..5b140e0 100644 --- a/geode-assembly/src/test/java/org/apache/geode/test/dunit/rules/gfsh/GfshScript.java +++ b/geode-assembly/src/test/java/org/apache/geode/test/dunit/rules/gfsh/GfshScript.java @@ -16,7 +16,6 @@ package org.apache.geode.test.dunit.rules.gfsh; import static org.assertj.core.api.Assertions.assertThat; -import java.nio.file.Path; import java.util.ArrayList; import java.util.List; import java.util.concurrent.TimeUnit; @@ -25,7 +24,7 @@ import org.apache.geode.management.internal.cli.util.ThreePhraseGenerator; public class GfshScript { private final String[] commands; - private String name = new ThreePhraseGenerator().generate('-'); + private String name; private TimeUnit timeoutTimeUnit = TimeUnit.MINUTES; private int timeout = 1; private boolean awaitQuietly = false; @@ -34,6 +33,7 @@ public class GfshScript { public GfshScript(String... commands) { this.commands = commands; + this.name = defaultName(commands); } /** @@ -152,4 +152,12 @@ public class GfshScript { public String getName() { return name; } + + private String defaultName(String... commands) { + try { + return commands[0].substring(0, commands[0].indexOf("-")); + } catch (Exception handled) { + return new ThreePhraseGenerator().generate('-'); + } + } } http://git-wip-us.apache.org/repos/asf/geode/blob/b77e1c7d/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java index 274f61c..d0f2e5a 100644 --- a/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java +++ b/geode-core/src/main/java/org/apache/geode/management/internal/cli/commands/ConnectCommand.java @@ -29,9 +29,11 @@ import java.util.Map; import java.util.Objects; import java.util.Properties; +import javax.net.ssl.HostnameVerifier; import javax.net.ssl.HttpsURLConnection; import javax.net.ssl.KeyManagerFactory; import javax.net.ssl.SSLContext; +import javax.net.ssl.SSLSession; import javax.net.ssl.TrustManagerFactory; import org.apache.commons.lang.StringUtils; @@ -112,7 +114,10 @@ public class ConnectCommand implements GfshCommand { help = CliStrings.CONNECT__SECURITY_PROPERTIES__HELP) final File gfSecurityPropertiesFile, @CliOption(key = {CliStrings.CONNECT__USE_SSL}, specifiedDefaultValue = "true", unspecifiedDefaultValue = "false", - help = CliStrings.CONNECT__USE_SSL__HELP) boolean useSsl) + help = CliStrings.CONNECT__USE_SSL__HELP) boolean useSsl, + @CliOption(key = {"skip-ssl-validation"}, specifiedDefaultValue = "true", + unspecifiedDefaultValue = "false", + help = "When connecting via HTTP, connects using 1-way SSL validation rather than 2-way SSL validation.") boolean skipSslValidation) throws MalformedURLException { Result result; @@ -145,12 +150,10 @@ public class ConnectCommand implements GfshCommand { gfProperties.setProperty(UserInputProperty.PASSWORD.getKey(), password); } - // TODO: refactor this to be more readable, like - /* - * if(useHttp) connectOverHttp else if(jmxManagerEndPoint==null) connectToLocator to get the - * jmxManagerEndPoint else connectTo jmxManagerEndPoint - */ if (useHttp) { + if (skipSslValidation) { + HttpsURLConnection.setDefaultHostnameVerifier((String s, SSLSession sslSession) -> true); + } result = httpConnect(gfProperties, url); } else { result = jmxConnect(gfProperties, useSsl, jmxManagerEndPoint, locatorEndPoint, false); @@ -160,8 +163,6 @@ public class ConnectCommand implements GfshCommand { } /** - * - * @param gfsh * @param useSsl if true, and no files/options passed, we would still insist on prompting for ssl * config (considered only when the last three parameters are null) * @param gfPropertiesFile gemfire properties file, can be null
