GEODE-17: make sure commands tests are run in useHttp mode. * added the CommandOverHttpDUnitTest in geode-web * added GfshCommandsOverHttpSecurityTest in geode-web * move ConnectCommandWithHttpAndSSLDUnitTest to geode-web * make sure ConnectCommandWithHttpAndSSLDUnitTest is running with the correct connection method * updated the trusted.keystore with the supported algorithm * create a SuiteRunner so that we can run tests in a suite yet have them report to its own xml
Project: http://git-wip-us.apache.org/repos/asf/incubator-geode/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-geode/commit/c79b64ff Tree: http://git-wip-us.apache.org/repos/asf/incubator-geode/tree/c79b64ff Diff: http://git-wip-us.apache.org/repos/asf/incubator-geode/diff/c79b64ff Branch: refs/heads/feature/GEODE-835 Commit: c79b64ff41f278ecffe0408cc4478bb6d19d3518 Parents: 97d6172 Author: Jinmei Liao <jil...@pivotal.io> Authored: Tue May 10 13:03:41 2016 -0700 Committer: Jinmei Liao <jil...@pivotal.io> Committed: Fri May 13 14:08:42 2016 -0700 ---------------------------------------------------------------------- .../SharedConfigurationEndToEndDUnitTest.java | 12 +- .../internal/security/shiro/ShiroPrincipal.java | 2 +- .../cli/commands/CliCommandTestBase.java | 47 +-- .../ConnectCommandWithHttpAndSSLDUnitTest.java | 305 ------------------- .../SharedConfigurationCommandsDUnitTest.java | 8 +- .../security/GfshCommandsSecurityTest.java | 9 +- .../src/test/resources/ssl/trusted.keystore | Bin 1078 -> 2241 bytes .../test/junit/runner/SuiteBlockRunner.java | 46 +++ .../gemfire/test/junit/runner/SuiteRunner.java | 53 ++++ .../ClusterConfigurationDUnitTest.java | 10 +- geode-web/build.gradle | 11 + .../cli/commands/CommandOverHttpDUnitTest.java | 58 ++++ .../ConnectCommandWithHttpAndSSLDUnitTest.java | 305 +++++++++++++++++++ .../GfshCommandsOverHttpSecurityTest.java | 29 ++ 14 files changed, 528 insertions(+), 367 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-assembly/src/test/java/com/gemstone/gemfire/management/internal/configuration/SharedConfigurationEndToEndDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-assembly/src/test/java/com/gemstone/gemfire/management/internal/configuration/SharedConfigurationEndToEndDUnitTest.java b/geode-assembly/src/test/java/com/gemstone/gemfire/management/internal/configuration/SharedConfigurationEndToEndDUnitTest.java index caee9ea..a6221e9 100644 --- a/geode-assembly/src/test/java/com/gemstone/gemfire/management/internal/configuration/SharedConfigurationEndToEndDUnitTest.java +++ b/geode-assembly/src/test/java/com/gemstone/gemfire/management/internal/configuration/SharedConfigurationEndToEndDUnitTest.java @@ -36,10 +36,6 @@ import java.util.HashSet; import java.util.Properties; import java.util.Set; -import org.apache.commons.io.FileUtils; -import org.junit.Test; -import org.junit.experimental.categories.Category; - import com.gemstone.gemfire.cache.Cache; import com.gemstone.gemfire.cache.CacheFactory; import com.gemstone.gemfire.cache.RegionShortcut; @@ -61,6 +57,10 @@ import com.gemstone.gemfire.test.dunit.VM; import com.gemstone.gemfire.test.dunit.WaitCriterion; import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import org.apache.commons.io.FileUtils; +import org.junit.Test; +import org.junit.experimental.categories.Category; + @Category(DistributedTest.class) public class SharedConfigurationEndToEndDUnitTest extends CliCommandTestBase { @@ -116,7 +116,7 @@ public class SharedConfigurationEndToEndDUnitTest extends CliCommandTestBase { public void testStartServerAndExecuteCommands() throws Exception { final HeadlessGfsh gfsh = new HeadlessGfsh("gfsh2", 300, this.gfshDir); assertNotNull(gfsh); - shellConnect(jmxHost, jmxPort, httpPort, gfsh); + connect(jmxHost, jmxPort, httpPort, gfsh); serverNames.addAll(startServers(gfsh, locatorString, 2, "Server", 1)); doCreateCommands(); @@ -380,7 +380,7 @@ public class SharedConfigurationEndToEndDUnitTest extends CliCommandTestBase { int jmxPort = (Integer)result[2]; int httpPort = (Integer)result[3]; - shellConnect(jmxHost, jmxPort, httpPort, gfsh); + connect(jmxHost, jmxPort, httpPort, gfsh); // Create a cache in VM 1 VM dataMember = getHost(0).getVM(1); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/ShiroPrincipal.java ---------------------------------------------------------------------- diff --git a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/ShiroPrincipal.java b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/ShiroPrincipal.java index 8413ebb..621eb87 100644 --- a/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/ShiroPrincipal.java +++ b/geode-core/src/main/java/com/gemstone/gemfire/internal/security/shiro/ShiroPrincipal.java @@ -30,7 +30,7 @@ public class ShiroPrincipal implements Principal { @Override public String getName() { - return subject.toString(); + return subject.getPrincipal().toString(); } public Subject getSubject(){ http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/CliCommandTestBase.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/CliCommandTestBase.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/CliCommandTestBase.java index 4b25165..a0966f9 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/CliCommandTestBase.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/CliCommandTestBase.java @@ -39,7 +39,6 @@ import com.gemstone.gemfire.management.internal.cli.parser.CommandTarget; import com.gemstone.gemfire.management.internal.cli.result.CommandResult; import com.gemstone.gemfire.management.internal.cli.shell.Gfsh; import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder; -import com.gemstone.gemfire.management.internal.security.JSONAuthorization; import com.gemstone.gemfire.test.dunit.Host; import com.gemstone.gemfire.test.dunit.cache.internal.JUnit4CacheTestCase; @@ -57,11 +56,8 @@ public abstract class CliCommandTestBase extends JUnit4CacheTestCase { private transient HeadlessGfsh shell; - protected boolean useHttpOnConnect = false; - protected boolean enableAuth = false; - protected String jsonAuthorization = "cacheServer.json"; - protected String username = "super-user"; - protected String password = "1234567"; + public static final String USE_HTTP_SYSTEM_PROPERTY = "useHTTP"; + private boolean useHttpOnConnect = Boolean.getBoolean(USE_HTTP_SYSTEM_PROPERTY); private transient int httpPort; private transient int jmxPort; @@ -107,12 +103,12 @@ public abstract class CliCommandTestBase extends JUnit4CacheTestCase { @SuppressWarnings("serial") protected HeadlessGfsh setUpJmxManagerOnVm0ThenConnect(final Properties props) { setUpJMXManagerOnVM(0, props); - shellConnect(); + connect(this.jmxHost, this.jmxPort, this.httpPort, getDefaultShell()); return shell; } protected void setUpJMXManagerOnVM(int vm, final Properties props) { - Object[] result = (Object[]) Host.getHost(0).getVM(vm).invoke("setUpJmxManagerOnVm0ThenConnect", () -> { + Object[] result = (Object[]) Host.getHost(0).getVM(vm).invoke("setUpJmxManagerOnVm"+vm, () -> { final Object[] results = new Object[3]; final Properties localProps = (props != null ? props : new Properties()); @@ -138,14 +134,6 @@ public abstract class CliCommandTestBase extends JUnit4CacheTestCase { localProps.setProperty(DistributionConfig.JMX_MANAGER_PORT_NAME, String.valueOf(jmxPort)); localProps.setProperty(DistributionConfig.HTTP_SERVICE_PORT_NAME, String.valueOf(httpPort)); - if (enableAuth) { - localProps.put(DistributionConfig.SECURITY_CLIENT_AUTHENTICATOR_NAME, - JSONAuthorization.class.getName() + ".create"); - localProps.put(DistributionConfig.SECURITY_CLIENT_ACCESSOR_NAME, JSONAuthorization.class.getName() + ".create"); - - JSONAuthorization.setUpWithJsonFile(jsonAuthorization); - } - getSystem(localProps); verifyManagementServiceStarted(getCache()); @@ -214,33 +202,9 @@ public abstract class CliCommandTestBase extends JUnit4CacheTestCase { } } - /** - * Connect a shell to the JMX server at the given host and port - * - * - * @param host Host of the JMX server - * @param jmxPort Port of the JMX server - * @param shell Shell to connect - */ - protected void shellConnect(final String host, final int jmxPort, final int httpPort, HeadlessGfsh shell) { - assertTrue(host != null); - assertTrue(shell != null); - - connect(host, jmxPort, httpPort, shell); - } - - protected CommandResult shellConnect(){ - return connect(this.jmxHost, this.jmxPort, this.httpPort, getDefaultShell()); - } - - protected CommandResult connect(final String host, final int jmxPort, final int httpPort, HeadlessGfsh shell){ + protected void connect(final String host, final int jmxPort, final int httpPort, HeadlessGfsh shell){ final CommandStringBuilder command = new CommandStringBuilder(CliStrings.CONNECT); - if(enableAuth) { - command.addOption(CliStrings.CONNECT__USERNAME, username); - command.addOption(CliStrings.CONNECT__PASSWORD, password); - } - String endpoint; if (useHttpOnConnect) { endpoint = "http://" + host + ":" + httpPort + "/gemfire/v1"; @@ -261,7 +225,6 @@ public abstract class CliCommandTestBase extends JUnit4CacheTestCase { info("Successfully connected to managing node using " + (useHttpOnConnect ? "HTTP" : "JMX")); assertEquals(true, shell.isConnectedAndReady()); - return result; } /** http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/ConnectCommandWithHttpAndSSLDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/ConnectCommandWithHttpAndSSLDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/ConnectCommandWithHttpAndSSLDUnitTest.java deleted file mode 100644 index 2e0897d..0000000 --- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/ConnectCommandWithHttpAndSSLDUnitTest.java +++ /dev/null @@ -1,305 +0,0 @@ -/* - * 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 com.gemstone.gemfire.management.internal.cli.commands; - -import static com.gemstone.gemfire.distributed.internal.DistributionConfig.*; -import static com.gemstone.gemfire.management.internal.cli.i18n.CliStrings.*; -import static com.gemstone.gemfire.test.dunit.Assert.*; -import static com.gemstone.gemfire.util.test.TestUtil.*; - -import java.io.File; -import java.util.Properties; -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.HttpsURLConnection; -import javax.net.ssl.SSLSession; - -import org.junit.Ignore; -import org.junit.Test; -import org.junit.experimental.categories.Category; - -import com.gemstone.gemfire.management.internal.cli.HeadlessGfsh; -import com.gemstone.gemfire.management.internal.cli.result.CommandResult; -import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder; -import com.gemstone.gemfire.test.junit.categories.DistributedTest; -import com.gemstone.gemfire.test.junit.categories.SecurityTest; - -/** - * @since 8.1 - */ -@Category({ DistributedTest.class, SecurityTest.class }) -public class ConnectCommandWithHttpAndSSLDUnitTest extends CliCommandTestBase { - - private static final ThreadLocal<Properties> sslInfoHolder = new ThreadLocal<>(); - - private File jks; - - // TODO: should this test use @RunWith(Parameterized.class)? - - @Override - public final void postSetUpCliCommandTestBase() throws Exception { - this.jks = new File(getResourcePath(getClass(), "/ssl/trusted.keystore")); - } - - @Override - protected final void preTearDownCliCommandTestBase() throws Exception { - destroyDefaultSetup(); - } - - @Override - public final void postTearDownCacheTestCase() throws Exception { - sslInfoHolder.set(null); - } - - @Test - public void testMutualAuthentication() throws Exception { - Properties localProps = new Properties(); - localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_TYPE_NAME, "JKS"); - localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME, "SSL"); - localProps.setProperty(HTTP_SERVICE_SSL_REQUIRE_AUTHENTICATION_NAME, "true"); - localProps.setProperty(HTTP_SERVICE_SSL_TRUSTSTORE_NAME, jks.getCanonicalPath()); - localProps.setProperty(HTTP_SERVICE_SSL_TRUSTSTORE_PASSWORD_NAME, "password"); - - Properties clientProps = new Properties(); - clientProps.setProperty(CONNECT__KEY_STORE, jks.getCanonicalPath()); - clientProps.setProperty(CONNECT__KEY_STORE_PASSWORD, "password"); - clientProps.setProperty(CONNECT__SSL_PROTOCOLS, "SSL"); - clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); - clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); - - sslInfoHolder.set(clientProps); - setUpJmxManagerOnVm0ThenConnect(localProps); - } - - @Test - public void testSimpleSSL() throws Exception { - Properties localProps = new Properties(); - localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_TYPE_NAME, "JKS"); - - Properties clientProps = new Properties(); - clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); - clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); - - sslInfoHolder.set(clientProps); - setUpJmxManagerOnVm0ThenConnect(localProps); - } - - @Test - public void testSSLWithoutKeyStoreType() throws Exception { - Properties localProps = new Properties(); - localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); - - Properties clientProps = new Properties(); - clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); - clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); - - sslInfoHolder.set(clientProps); - setUpJmxManagerOnVm0ThenConnect(localProps); - } - - @Test - public void testSSLWithSSLProtocol() throws Exception { - Properties localProps = new Properties(); - localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); - localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"SSL"); - - Properties clientProps = new Properties(); - clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); - clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); - - sslInfoHolder.set(clientProps); - setUpJmxManagerOnVm0ThenConnect(localProps); - } - - @Test - public void testSSLWithTLSProtocol() throws Exception { - Properties localProps = new Properties(); - localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); - localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"TLS"); - - Properties clientProps = new Properties(); - clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); - clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); - - sslInfoHolder.set(clientProps); - setUpJmxManagerOnVm0ThenConnect(localProps); - } - - @Test - public void testSSLWithTLSv11Protocol() throws Exception { - Properties localProps = new Properties(); - localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); - localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"TLSv1.1"); - - Properties clientProps = new Properties(); - clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); - clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); - - sslInfoHolder.set(clientProps); - setUpJmxManagerOnVm0ThenConnect(localProps); - } - - @Test - public void testSSLWithTLSv12Protocol() throws Exception { - Properties localProps = new Properties(); - localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); - localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"TLSv1.2"); - - Properties clientProps = new Properties(); - clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); - clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); - - sslInfoHolder.set(clientProps); - setUpJmxManagerOnVm0ThenConnect(localProps); - } - - @Test - public void testWithMultipleProtocol() throws Exception { - Properties localProps = new Properties(); - localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); - localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"SSL,TLSv1.2"); - - Properties clientProps = new Properties(); - clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); - clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); - - sslInfoHolder.set(clientProps); - setUpJmxManagerOnVm0ThenConnect(localProps); - } - - @Ignore("disabled for unknown reason") - @Test - public void testSSLWithCipherSuite() throws Exception { - Properties localProps = new Properties(); - localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); - localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME, "TLSv1.2"); - - //Its bad to hard code here. But using SocketFactory.getDefaultCiphers() somehow is not working with the option - //"https.cipherSuites" which is required to restrict cipher suite with HttpsURLConnection - //Keeping the below code for further investigation on different Java versions ( 7 & 8) @TODO - - /*SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); - - sslContext.init(null, null, new java.security.SecureRandom()); - String[] cipherSuites = sslContext.getSocketFactory().getSupportedCipherSuites();*/ - - localProps.setProperty(HTTP_SERVICE_SSL_CIPHERS_NAME,"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"); - - Properties clientProps = new Properties(); - clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); - clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); - clientProps.setProperty(CONNECT__SSL_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"); - clientProps.setProperty(CONNECT__SSL_PROTOCOLS, "TLSv1.2"); - - sslInfoHolder.set(clientProps); - setUpJmxManagerOnVm0ThenConnect(localProps); - } - - @Ignore("disabled for unknown reason") - @Test - public void testSSLWithMultipleCipherSuite() throws Exception { - System.setProperty("javax.net.debug", "ssl,handshake,failure"); - - Properties localProps = new Properties(); - localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); - localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); - localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"TLSv1.2"); - localProps.setProperty(HTTP_SERVICE_SSL_CIPHERS_NAME,"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_EMPTY_RENEGOTIATION_INFO_SCSV"); - - Properties clientProps = new Properties(); - clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); - clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); - clientProps.setProperty(CONNECT__SSL_PROTOCOLS, "TLSv1.2"); - - sslInfoHolder.set(clientProps); - setUpJmxManagerOnVm0ThenConnect(localProps); - } - - @Override - protected void shellConnect(final String host, final int jmxPort, final int httpPort, final HeadlessGfsh shell) { - assertNotNull(host); - assertNotNull(shell); - - final CommandStringBuilder command = new CommandStringBuilder(CONNECT); - String endpoint; - - // This is for testing purpose only. If we remove this piece of code we will - // get a java.security.cert.CertificateException - // as matching hostname can not be obtained in all test environment. - HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { - @Override - public boolean verify(String string, SSLSession ssls) { - return true; - } - }); - - endpoint = "https://" + host + ":" + httpPort + "/gemfire/v1"; - - command.addOption(CONNECT__USE_HTTP, Boolean.TRUE.toString()); - command.addOption(CONNECT__URL, endpoint); - command.addOption(CONNECT__USE_SSL,Boolean.TRUE.toString()); - - if(sslInfoHolder.get().getProperty(CONNECT__KEY_STORE) != null){ - command.addOption(CONNECT__KEY_STORE, sslInfoHolder.get().getProperty(CONNECT__KEY_STORE)); - } - if(sslInfoHolder.get().getProperty(CONNECT__KEY_STORE_PASSWORD) != null){ - command.addOption(CONNECT__KEY_STORE_PASSWORD, sslInfoHolder.get().getProperty(CONNECT__KEY_STORE_PASSWORD)); - } - if(sslInfoHolder.get().getProperty(CONNECT__TRUST_STORE) != null){ - command.addOption(CONNECT__TRUST_STORE, sslInfoHolder.get().getProperty(CONNECT__TRUST_STORE)); - } - if(sslInfoHolder.get().getProperty(CONNECT__TRUST_STORE_PASSWORD) != null){ - command.addOption(CONNECT__TRUST_STORE_PASSWORD, sslInfoHolder.get().getProperty(CONNECT__TRUST_STORE_PASSWORD)); - } - if(sslInfoHolder.get().getProperty(CONNECT__SSL_PROTOCOLS) != null){ - command.addOption(CONNECT__SSL_PROTOCOLS, sslInfoHolder.get().getProperty(CONNECT__SSL_PROTOCOLS)); - } - if(sslInfoHolder.get().getProperty(CONNECT__SSL_CIPHERS) != null){ - command.addOption(CONNECT__SSL_CIPHERS, sslInfoHolder.get().getProperty(CONNECT__SSL_CIPHERS)); - } - - CommandResult result = executeCommand(shell, command.toString()); - - if (!shell.isConnectedAndReady()) { - fail("Connect command failed to connect to manager " + endpoint + " result=" + commandResultToString(result)); - } - - info("Successfully connected to managing node using HTTPS"); - assertEquals(true, shell.isConnectedAndReady()); - } - -} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/SharedConfigurationCommandsDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/SharedConfigurationCommandsDUnitTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/SharedConfigurationCommandsDUnitTest.java index 781ed98..334d2e1 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/SharedConfigurationCommandsDUnitTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/SharedConfigurationCommandsDUnitTest.java @@ -31,9 +31,6 @@ import java.io.IOException; import java.util.Properties; import java.util.Set; -import org.junit.Test; -import org.junit.experimental.categories.Category; - import com.gemstone.gemfire.cache.Cache; import com.gemstone.gemfire.cache.CacheFactory; import com.gemstone.gemfire.distributed.DistributedMember; @@ -54,6 +51,9 @@ import com.gemstone.gemfire.test.dunit.VM; import com.gemstone.gemfire.test.dunit.WaitCriterion; import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import org.junit.Test; +import org.junit.experimental.categories.Category; + /** * DUnit test to test export and import of shared configuration. */ @@ -167,7 +167,7 @@ public class SharedConfigurationCommandsDUnitTest extends CliCommandTestBase { }); HeadlessGfsh gfsh = getDefaultShell(); - shellConnect(locator1JmxHost, locator1JmxPort, locator1HttpPort, gfsh); + connect(locator1JmxHost, locator1JmxPort, locator1HttpPort, gfsh); // Create a cache in VM 1 VM dataMember = getHost(0).getVM(1); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java ---------------------------------------------------------------------- diff --git a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java index d96c96c..8eaaf6a 100644 --- a/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java +++ b/geode-core/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsSecurityTest.java @@ -39,9 +39,9 @@ import org.junit.experimental.categories.Category; @Category(IntegrationTest.class) public class GfshCommandsSecurityTest { - private static int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2); - private static int jmxPort = ports[0]; - private static int httpPort = ports[1]; + protected static int[] ports = AvailablePortHelper.getRandomAvailableTCPPorts(2); + protected static int jmxPort = ports[0]; + protected static int httpPort = ports[1]; private HeadlessGfsh gfsh = null; @@ -50,12 +50,13 @@ public class GfshCommandsSecurityTest { jmxPort, httpPort, "cacheServer.json"); @Rule - public GfshShellConnectionRule gfshConnection = null; + public GfshShellConnectionRule gfshConnection; public GfshCommandsSecurityTest(){ gfshConnection = new GfshShellConnectionRule(jmxPort, httpPort, false); } + @Before public void before(){ gfsh = gfshConnection.getGfsh(); http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-core/src/test/resources/ssl/trusted.keystore ---------------------------------------------------------------------- diff --git a/geode-core/src/test/resources/ssl/trusted.keystore b/geode-core/src/test/resources/ssl/trusted.keystore old mode 100755 new mode 100644 index 6057e3c..bd75039 Binary files a/geode-core/src/test/resources/ssl/trusted.keystore and b/geode-core/src/test/resources/ssl/trusted.keystore differ http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-junit/src/main/java/com/gemstone/gemfire/test/junit/runner/SuiteBlockRunner.java ---------------------------------------------------------------------- diff --git a/geode-junit/src/main/java/com/gemstone/gemfire/test/junit/runner/SuiteBlockRunner.java b/geode-junit/src/main/java/com/gemstone/gemfire/test/junit/runner/SuiteBlockRunner.java new file mode 100644 index 0000000..60fed84 --- /dev/null +++ b/geode-junit/src/main/java/com/gemstone/gemfire/test/junit/runner/SuiteBlockRunner.java @@ -0,0 +1,46 @@ +/* + * 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 com.gemstone.gemfire.test.junit.runner; + +import org.junit.runners.BlockJUnit4ClassRunner; +import org.junit.runners.model.FrameworkMethod; +import org.junit.runners.model.InitializationError; + +/** + * used by SuiteRunner to override the test method name + */ +public class SuiteBlockRunner extends BlockJUnit4ClassRunner { + + private Class<?> suiteClass; + + /** + * Creates a BlockJUnit4ClassRunner to run {@code klass} + * @param klass + * @throws InitializationError if the test class is malformed. + */ + public SuiteBlockRunner(final Class parentClass, final Class<?> klass) throws InitializationError { + super(klass); + this.suiteClass = parentClass; + } + + @Override + protected String testName(FrameworkMethod method) { + return method.getName()+"@"+ suiteClass.getName(); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-junit/src/main/java/com/gemstone/gemfire/test/junit/runner/SuiteRunner.java ---------------------------------------------------------------------- diff --git a/geode-junit/src/main/java/com/gemstone/gemfire/test/junit/runner/SuiteRunner.java b/geode-junit/src/main/java/com/gemstone/gemfire/test/junit/runner/SuiteRunner.java new file mode 100644 index 0000000..2a860c0 --- /dev/null +++ b/geode-junit/src/main/java/com/gemstone/gemfire/test/junit/runner/SuiteRunner.java @@ -0,0 +1,53 @@ +/* + * 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 com.gemstone.gemfire.test.junit.runner; + +import java.util.ArrayList; +import java.util.List; + +import org.junit.runner.Runner; +import org.junit.runners.Suite; +import org.junit.runners.model.InitializationError; +import org.junit.runners.model.RunnerBuilder; + +/** + * SuiteRunner is like Junit Suite, it's used in conjunction with <code>SuiteClass({xx.class, yy.class})</code> + * It's different from Suite in two ways: + * 1. it should only contain contain Junit4 test classes + * 2. the test method names inside each test class are appended with the suiteClass name so that the result will show up different + * as when you run these tests alone. + */ +public class SuiteRunner extends Suite { + + public SuiteRunner(final Class<?> klass, final RunnerBuilder builder) throws InitializationError { + super(klass, getRunners(klass)); + } + + private static List<Runner> getRunners(final Class<?> klass) throws InitializationError{ + SuiteClasses annotation = klass.getAnnotation(SuiteClasses.class); + if (annotation == null) { + throw new InitializationError(String.format("class '%s' must have a SuiteClasses annotation", klass.getName())); + } + Class<?>[] childClasses = annotation.value(); + List<Runner> runners = new ArrayList<>(); + for(Class childClass:childClasses){ + runners.add(new SuiteBlockRunner(klass, childClass)); + } + return runners; + } +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-wan/src/test/java/com/gemstone/gemfire/management/internal/configuration/ClusterConfigurationDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-wan/src/test/java/com/gemstone/gemfire/management/internal/configuration/ClusterConfigurationDUnitTest.java b/geode-wan/src/test/java/com/gemstone/gemfire/management/internal/configuration/ClusterConfigurationDUnitTest.java index 62bb793..d8692ce 100644 --- a/geode-wan/src/test/java/com/gemstone/gemfire/management/internal/configuration/ClusterConfigurationDUnitTest.java +++ b/geode-wan/src/test/java/com/gemstone/gemfire/management/internal/configuration/ClusterConfigurationDUnitTest.java @@ -40,10 +40,6 @@ import java.util.Map.Entry; import java.util.Properties; import java.util.Set; -import org.junit.Ignore; -import org.junit.Test; -import org.junit.experimental.categories.Category; - import com.gemstone.gemfire.cache.Cache; import com.gemstone.gemfire.cache.CacheFactory; import com.gemstone.gemfire.cache.Region; @@ -80,6 +76,10 @@ import com.gemstone.gemfire.test.dunit.VM; import com.gemstone.gemfire.test.dunit.WaitCriterion; import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; + @Category(DistributedTest.class) public class ClusterConfigurationDUnitTest extends CliCommandTestBase { @@ -663,7 +663,7 @@ public class ClusterConfigurationDUnitTest extends CliCommandTestBase { int jmxPort = (Integer)result[2]; int httpPort = (Integer)result[3]; - shellConnect(jmxHost, jmxPort, httpPort, gfsh); + connect(jmxHost, jmxPort, httpPort, gfsh); final String dataMemberWorkingDir = this.temporaryFolder.getRoot().getCanonicalPath() + File.separator + dataMember; http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-web/build.gradle ---------------------------------------------------------------------- diff --git a/geode-web/build.gradle b/geode-web/build.gradle index 5bd1d89..228751b 100755 --- a/geode-web/build.gradle +++ b/geode-web/build.gradle @@ -52,6 +52,9 @@ dependencies { testCompile project(':geode-junit') testRuntime project(':geode-common') testRuntime project(':geode-core') + testCompile files(project(':geode-core').sourceSets.test.output) + + testRuntime files(war.destinationDir) } //Remove the gradle output directories from the eclipse classpath. These @@ -69,6 +72,14 @@ idea.module.iml { } } +distributedTest { + dependsOn ':geode-core:webJar', 'war' +} + +integrationTest { + dependsOn ':geode-core:webJar', 'war' +} + war { classpath configurations.runtime classpath project(':geode-core').webJar.archivePath http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-web/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/CommandOverHttpDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-web/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/CommandOverHttpDUnitTest.java b/geode-web/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/CommandOverHttpDUnitTest.java new file mode 100644 index 0000000..9687eb7 --- /dev/null +++ b/geode-web/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/CommandOverHttpDUnitTest.java @@ -0,0 +1,58 @@ +/* + * 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 com.gemstone.gemfire.management.internal.cli.commands; + +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.runner.SuiteRunner; + +import org.junit.ClassRule; +import org.junit.contrib.java.lang.system.ProvideSystemProperty; +import org.junit.experimental.categories.Category; +import org.junit.runner.RunWith; +import org.junit.runners.Suite; + +@Category(DistributedTest.class) +@RunWith(SuiteRunner.class) +@Suite.SuiteClasses({ + ConfigCommandsDUnitTest.class, + DeployCommandsDUnitTest.class, + DiskStoreCommandsDUnitTest.class, + FunctionCommandsDUnitTest.class, + GemfireDataCommandsDUnitTest.class, + GetCommandOnRegionWithCacheLoaderDuringCacheMissDUnitTest.class, + IndexCommandsDUnitTest.class, + ListAndDescribeDiskStoreCommandsDUnitTest.class, + ListIndexCommandDUnitTest.class, + MemberCommandsDUnitTest.class, + MiscellaneousCommandsDUnitTest.class, + MiscellaneousCommandsExportLogsPart1DUnitTest.class, + MiscellaneousCommandsExportLogsPart2DUnitTest.class, + MiscellaneousCommandsExportLogsPart3DUnitTest.class, + MiscellaneousCommandsExportLogsPart4DUnitTest.class, + QueueCommandsDUnitTest.class, + SharedConfigurationCommandsDUnitTest.class, + ShellCommandsDUnitTest.class, + ShowDeadlockDUnitTest.class, + ShowMetricsDUnitTest.class, + ShowStackTraceDUnitTest.class, + UserCommandsDUnitTest.class +}) +public class CommandOverHttpDUnitTest { + @ClassRule + public static ProvideSystemProperty provideSystemProperty = new ProvideSystemProperty(CliCommandTestBase.USE_HTTP_SYSTEM_PROPERTY, "true"); +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-web/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/ConnectCommandWithHttpAndSSLDUnitTest.java ---------------------------------------------------------------------- diff --git a/geode-web/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/ConnectCommandWithHttpAndSSLDUnitTest.java b/geode-web/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/ConnectCommandWithHttpAndSSLDUnitTest.java new file mode 100644 index 0000000..a8f209b --- /dev/null +++ b/geode-web/src/test/java/com/gemstone/gemfire/management/internal/cli/commands/ConnectCommandWithHttpAndSSLDUnitTest.java @@ -0,0 +1,305 @@ +/* + * 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 com.gemstone.gemfire.management.internal.cli.commands; + +import static com.gemstone.gemfire.distributed.internal.DistributionConfig.*; +import static com.gemstone.gemfire.management.internal.cli.i18n.CliStrings.*; +import static com.gemstone.gemfire.test.dunit.Assert.*; +import static com.gemstone.gemfire.util.test.TestUtil.*; + +import java.io.File; +import java.util.Properties; +import javax.net.ssl.HostnameVerifier; +import javax.net.ssl.HttpsURLConnection; +import javax.net.ssl.SSLSession; + +import com.gemstone.gemfire.management.internal.cli.HeadlessGfsh; +import com.gemstone.gemfire.management.internal.cli.result.CommandResult; +import com.gemstone.gemfire.management.internal.cli.util.CommandStringBuilder; +import com.gemstone.gemfire.test.junit.categories.DistributedTest; +import com.gemstone.gemfire.test.junit.categories.SecurityTest; + +import org.junit.Ignore; +import org.junit.Test; +import org.junit.experimental.categories.Category; + +/** + * @since 8.1 + */ +@Category({ DistributedTest.class, SecurityTest.class }) +public class ConnectCommandWithHttpAndSSLDUnitTest extends CliCommandTestBase { + + private static final ThreadLocal<Properties> sslInfoHolder = new ThreadLocal<>(); + + private File jks; + + // TODO: should this test use @RunWith(Parameterized.class)? + + @Override + public final void postSetUpCliCommandTestBase() throws Exception { + this.jks = new File(getResourcePath(getClass(), "/ssl/trusted.keystore")); + } + + @Override + protected final void preTearDownCliCommandTestBase() throws Exception { + destroyDefaultSetup(); + } + + @Override + public final void postTearDownCacheTestCase() throws Exception { + sslInfoHolder.set(null); + } + + @Test + public void testMutualAuthentication() throws Exception { + Properties serverProps = new Properties(); + serverProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); + serverProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); + serverProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); + serverProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_TYPE_NAME, "JKS"); + serverProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME, "SSL"); + serverProps.setProperty(HTTP_SERVICE_SSL_REQUIRE_AUTHENTICATION_NAME, "true"); + serverProps.setProperty(HTTP_SERVICE_SSL_TRUSTSTORE_NAME, jks.getCanonicalPath()); + serverProps.setProperty(HTTP_SERVICE_SSL_TRUSTSTORE_PASSWORD_NAME, "password"); + + Properties clientProps = new Properties(); + clientProps.setProperty(CONNECT__KEY_STORE, jks.getCanonicalPath()); + clientProps.setProperty(CONNECT__KEY_STORE_PASSWORD, "password"); + clientProps.setProperty(CONNECT__SSL_PROTOCOLS, "SSL"); + clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); + clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); + + sslInfoHolder.set(clientProps); + setUpJmxManagerOnVm0ThenConnect(serverProps); + } + + @Test + public void testSimpleSSL() throws Exception { + Properties serverProps = new Properties(); + serverProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); + serverProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); + serverProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); + serverProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_TYPE_NAME, "JKS"); + + Properties clientProps = new Properties(); + clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); + clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); + + sslInfoHolder.set(clientProps); + setUpJmxManagerOnVm0ThenConnect(serverProps); + } + + @Test + public void testSSLWithoutKeyStoreType() throws Exception { + Properties localProps = new Properties(); + localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); + + Properties clientProps = new Properties(); + clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); + clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); + + sslInfoHolder.set(clientProps); + setUpJmxManagerOnVm0ThenConnect(localProps); + } + + @Test + public void testSSLWithSSLProtocol() throws Exception { + Properties localProps = new Properties(); + localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); + localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"SSL"); + + Properties clientProps = new Properties(); + clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); + clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); + + sslInfoHolder.set(clientProps); + setUpJmxManagerOnVm0ThenConnect(localProps); + } + + @Test + public void testSSLWithTLSProtocol() throws Exception { + Properties localProps = new Properties(); + localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); + localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"TLS"); + + Properties clientProps = new Properties(); + clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); + clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); + + sslInfoHolder.set(clientProps); + setUpJmxManagerOnVm0ThenConnect(localProps); + } + + @Test + public void testSSLWithTLSv11Protocol() throws Exception { + Properties localProps = new Properties(); + localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); + localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"TLSv1.1"); + + Properties clientProps = new Properties(); + clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); + clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); + + sslInfoHolder.set(clientProps); + setUpJmxManagerOnVm0ThenConnect(localProps); + } + + @Test + public void testSSLWithTLSv12Protocol() throws Exception { + Properties localProps = new Properties(); + localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); + localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"TLSv1.2"); + + Properties clientProps = new Properties(); + clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); + clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); + + sslInfoHolder.set(clientProps); + setUpJmxManagerOnVm0ThenConnect(localProps); + } + + @Test + public void testWithMultipleProtocol() throws Exception { + Properties localProps = new Properties(); + localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); + localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"SSL,TLSv1.2"); + + Properties clientProps = new Properties(); + clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); + clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); + + sslInfoHolder.set(clientProps); + setUpJmxManagerOnVm0ThenConnect(localProps); + } + + @Ignore("disabled for unknown reason") + @Test + public void testSSLWithCipherSuite() throws Exception { + Properties localProps = new Properties(); + localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); + localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME, "TLSv1.2"); + + //Its bad to hard code here. But using SocketFactory.getDefaultCiphers() somehow is not working with the option + //"https.cipherSuites" which is required to restrict cipher suite with HttpsURLConnection + //Keeping the below code for further investigation on different Java versions ( 7 & 8) @TODO + + /*SSLContext sslContext = SSLContext.getInstance("TLSv1.2"); + + sslContext.init(null, null, new java.security.SecureRandom()); + String[] cipherSuites = sslContext.getSocketFactory().getSupportedCipherSuites();*/ + + localProps.setProperty(HTTP_SERVICE_SSL_CIPHERS_NAME,"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"); + + Properties clientProps = new Properties(); + clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); + clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); + clientProps.setProperty(CONNECT__SSL_CIPHERS, "TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256"); + clientProps.setProperty(CONNECT__SSL_PROTOCOLS, "TLSv1.2"); + + sslInfoHolder.set(clientProps); + setUpJmxManagerOnVm0ThenConnect(localProps); + } + + @Ignore("disabled for unknown reason") + @Test + public void testSSLWithMultipleCipherSuite() throws Exception { + System.setProperty("javax.net.debug", "ssl,handshake,failure"); + + Properties localProps = new Properties(); + localProps.setProperty(HTTP_SERVICE_SSL_ENABLED_NAME, "true"); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_NAME, jks.getCanonicalPath()); + localProps.setProperty(HTTP_SERVICE_SSL_KEYSTORE_PASSWORD_NAME, "password"); + localProps.setProperty(HTTP_SERVICE_SSL_PROTOCOLS_NAME,"TLSv1.2"); + localProps.setProperty(HTTP_SERVICE_SSL_CIPHERS_NAME,"TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256,TLS_EMPTY_RENEGOTIATION_INFO_SCSV"); + + Properties clientProps = new Properties(); + clientProps.setProperty(CONNECT__TRUST_STORE, jks.getCanonicalPath()); + clientProps.setProperty(CONNECT__TRUST_STORE_PASSWORD, "password"); + clientProps.setProperty(CONNECT__SSL_PROTOCOLS, "TLSv1.2"); + + sslInfoHolder.set(clientProps); + setUpJmxManagerOnVm0ThenConnect(localProps); + } + + @Override + protected void connect(final String host, final int jmxPort, final int httpPort, final HeadlessGfsh shell) { + assertNotNull(host); + assertNotNull(shell); + + final CommandStringBuilder command = new CommandStringBuilder(CONNECT); + String endpoint; + + // This is for testing purpose only. If we remove this piece of code we will + // get a java.security.cert.CertificateException + // as matching hostname can not be obtained in all test environment. + HttpsURLConnection.setDefaultHostnameVerifier(new HostnameVerifier() { + @Override + public boolean verify(String string, SSLSession ssls) { + return true; + } + }); + + endpoint = "https://" + host + ":" + httpPort + "/gemfire/v1"; + + command.addOption(CONNECT__USE_HTTP, Boolean.TRUE.toString()); + command.addOption(CONNECT__URL, endpoint); + command.addOption(CONNECT__USE_SSL,Boolean.TRUE.toString()); + + if(sslInfoHolder.get().getProperty(CONNECT__KEY_STORE) != null){ + command.addOption(CONNECT__KEY_STORE, sslInfoHolder.get().getProperty(CONNECT__KEY_STORE)); + } + if(sslInfoHolder.get().getProperty(CONNECT__KEY_STORE_PASSWORD) != null){ + command.addOption(CONNECT__KEY_STORE_PASSWORD, sslInfoHolder.get().getProperty(CONNECT__KEY_STORE_PASSWORD)); + } + if(sslInfoHolder.get().getProperty(CONNECT__TRUST_STORE) != null){ + command.addOption(CONNECT__TRUST_STORE, sslInfoHolder.get().getProperty(CONNECT__TRUST_STORE)); + } + if(sslInfoHolder.get().getProperty(CONNECT__TRUST_STORE_PASSWORD) != null){ + command.addOption(CONNECT__TRUST_STORE_PASSWORD, sslInfoHolder.get().getProperty(CONNECT__TRUST_STORE_PASSWORD)); + } + if(sslInfoHolder.get().getProperty(CONNECT__SSL_PROTOCOLS) != null){ + command.addOption(CONNECT__SSL_PROTOCOLS, sslInfoHolder.get().getProperty(CONNECT__SSL_PROTOCOLS)); + } + if(sslInfoHolder.get().getProperty(CONNECT__SSL_CIPHERS) != null){ + command.addOption(CONNECT__SSL_CIPHERS, sslInfoHolder.get().getProperty(CONNECT__SSL_CIPHERS)); + } + + CommandResult result = executeCommand(shell, command.toString()); + + if (!shell.isConnectedAndReady()) { + fail("Connect command failed to connect to manager " + endpoint + " result=" + commandResultToString(result)); + } + + info("Successfully connected to managing node using HTTPS"); + assertEquals(true, shell.isConnectedAndReady()); + } + +} http://git-wip-us.apache.org/repos/asf/incubator-geode/blob/c79b64ff/geode-web/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsOverHttpSecurityTest.java ---------------------------------------------------------------------- diff --git a/geode-web/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsOverHttpSecurityTest.java b/geode-web/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsOverHttpSecurityTest.java new file mode 100644 index 0000000..af0cfad --- /dev/null +++ b/geode-web/src/test/java/com/gemstone/gemfire/management/internal/security/GfshCommandsOverHttpSecurityTest.java @@ -0,0 +1,29 @@ +/* + * 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 com.gemstone.gemfire.management.internal.security; + +import com.gemstone.gemfire.test.junit.categories.IntegrationTest; + +import org.junit.experimental.categories.Category; + +@Category(IntegrationTest.class) +public class GfshCommandsOverHttpSecurityTest extends GfshCommandsSecurityTest { + public GfshCommandsOverHttpSecurityTest(){ + gfshConnection = new GfshShellConnectionRule(jmxPort, httpPort, true); + } +}