/* * 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.internal.net; import static org.apache.geode.distributed.ConfigurationProperties.CLUSTER_SSL_ENABLED; import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT; import static org.apache.geode.distributed.ConfigurationProperties.SSL_CIPHERS; import static org.apache.geode.distributed.ConfigurationProperties.SSL_CLUSTER_ALIAS; import static org.apache.geode.distributed.ConfigurationProperties.SSL_DEFAULT_ALIAS; import static org.apache.geode.distributed.ConfigurationProperties.SSL_ENABLED_COMPONENTS; import static org.apache.geode.distributed.ConfigurationProperties.SSL_GATEWAY_ALIAS; import static org.apache.geode.distributed.ConfigurationProperties.SSL_JMX_ALIAS; 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_LOCATOR_ALIAS; import static org.apache.geode.distributed.ConfigurationProperties.SSL_PROTOCOLS; import static org.apache.geode.distributed.ConfigurationProperties.SSL_SERVER_ALIAS; 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_WEB_ALIAS; import static org.apache.geode.distributed.ConfigurationProperties.SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION; import static org.junit.Assert.assertEquals; import org.apache.commons.lang.StringUtils; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.distributed.internal.DistributionConfigImpl; import org.apache.geode.internal.admin.SSLConfig; import org.apache.geode.internal.security.SecurableCommunicationChannel; import org.apache.geode.test.junit.categories.MembershipTest; import org.apache.geode.test.junit.categories.UnitTest; import org.junit.After; import org.junit.Rule; import org.junit.Test; import org.junit.contrib.java.lang.system.RestoreSystemProperties; import org.junit.experimental.categories.Category; import java.util.Properties; @Category({UnitTest.class, MembershipTest.class}) public class SSLConfigurationFactoryJUnitTest { @Rule public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties(); @After public void tearDownTest() { SSLConfigurationFactory.close(); } @Test public void getNonSSLConfiguration() throws Exception { Properties properties = new Properties(); DistributionConfigImpl distributionConfig = new DistributionConfigImpl(properties); SSLConfigurationFactory.setDistributionConfig(distributionConfig); for (SecurableCommunicationChannel securableComponent : SecurableCommunicationChannel .values()) { assertSSLConfig(properties, SSLConfigurationFactory.getSSLConfigForComponent(securableComponent), securableComponent, distributionConfig); } } @Test public void getSSLConfigWithCommaDelimitedProtocols() throws Exception { Properties properties = new Properties(); properties.setProperty(SSL_ENABLED_COMPONENTS, "all"); properties.setProperty(SSL_KEYSTORE, "someKeyStore"); properties.setProperty(SSL_KEYSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_KEYSTORE_TYPE, "JKS"); properties.setProperty(SSL_TRUSTSTORE, "someKeyStore"); properties.setProperty(SSL_TRUSTSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_DEFAULT_ALIAS, "defaultAlias"); properties.setProperty(SSL_CIPHERS, "Cipher1,Cipher2"); properties.setProperty(SSL_PROTOCOLS, "Protocol1,Protocol2"); DistributionConfigImpl distributionConfig = new DistributionConfigImpl(properties); SSLConfigurationFactory.setDistributionConfig(distributionConfig); for (SecurableCommunicationChannel securableComponent : SecurableCommunicationChannel .values()) { assertSSLConfig(properties, SSLConfigurationFactory.getSSLConfigForComponent(securableComponent), securableComponent, distributionConfig); } } @Test public void getSSLConfigWithCommaDelimitedCiphers() throws Exception { Properties properties = new Properties(); properties.setProperty(SSL_ENABLED_COMPONENTS, "all"); properties.setProperty(SSL_KEYSTORE, "someKeyStore"); properties.setProperty(SSL_KEYSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_KEYSTORE_TYPE, "JKS"); properties.setProperty(SSL_TRUSTSTORE, "someKeyStore"); properties.setProperty(SSL_TRUSTSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_DEFAULT_ALIAS, "defaultAlias"); properties.setProperty(SSL_CIPHERS, "Cipher1,Cipher2"); properties.setProperty(SSL_PROTOCOLS, "any"); DistributionConfigImpl distributionConfig = new DistributionConfigImpl(properties); SSLConfigurationFactory.setDistributionConfig(distributionConfig); for (SecurableCommunicationChannel securableCommunicationChannel : SecurableCommunicationChannel .values()) { assertSSLConfig(properties, SSLConfigurationFactory.getSSLConfigForComponent(securableCommunicationChannel), securableCommunicationChannel, distributionConfig); } } @Test public void getSSLConfigForComponentALL() throws Exception { Properties properties = new Properties(); properties.setProperty(SSL_ENABLED_COMPONENTS, "all"); properties.setProperty(SSL_KEYSTORE, "someKeyStore"); properties.setProperty(SSL_KEYSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_KEYSTORE_TYPE, "JKS"); properties.setProperty(SSL_TRUSTSTORE, "someKeyStore"); properties.setProperty(SSL_TRUSTSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_DEFAULT_ALIAS, "defaultAlias"); properties.setProperty(SSL_CIPHERS, "any"); properties.setProperty(SSL_PROTOCOLS, "any"); DistributionConfigImpl distributionConfig = new DistributionConfigImpl(properties); SSLConfigurationFactory.setDistributionConfig(distributionConfig); for (SecurableCommunicationChannel securableCommunicationChannel : SecurableCommunicationChannel .values()) { assertSSLConfig(properties, SSLConfigurationFactory.getSSLConfigForComponent(securableCommunicationChannel), securableCommunicationChannel, distributionConfig); } } @Test public void getSSLConfigForComponentHTTPService() throws Exception { Properties properties = new Properties(); properties.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant()); properties.setProperty(SSL_KEYSTORE, "someKeyStore"); properties.setProperty(SSL_KEYSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_KEYSTORE_TYPE, "JKS"); properties.setProperty(SSL_TRUSTSTORE, "someKeyStore"); properties.setProperty(SSL_TRUSTSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_DEFAULT_ALIAS, "defaultAlias"); properties.setProperty(SSL_CIPHERS, "any"); properties.setProperty(SSL_PROTOCOLS, "any"); DistributionConfigImpl distributionConfig = new DistributionConfigImpl(properties); SSLConfigurationFactory.setDistributionConfig(distributionConfig); for (SecurableCommunicationChannel securableCommunicationChannel : SecurableCommunicationChannel .values()) { assertSSLConfig(properties, SSLConfigurationFactory.getSSLConfigForComponent(securableCommunicationChannel), securableCommunicationChannel, distributionConfig); } } @Test public void getSSLConfigForComponentHTTPServiceWithAlias() throws Exception { Properties properties = new Properties(); properties.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant()); properties.setProperty(SSL_KEYSTORE, "someKeyStore"); properties.setProperty(SSL_KEYSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_KEYSTORE_TYPE, "JKS"); properties.setProperty(SSL_TRUSTSTORE, "someKeyStore"); properties.setProperty(SSL_TRUSTSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_DEFAULT_ALIAS, "defaultAlias"); properties.setProperty(SSL_WEB_ALIAS, "httpAlias"); properties.setProperty(SSL_CIPHERS, "any"); properties.setProperty(SSL_PROTOCOLS, "any"); DistributionConfigImpl distributionConfig = new DistributionConfigImpl(properties); SSLConfigurationFactory.setDistributionConfig(distributionConfig); for (SecurableCommunicationChannel securableCommunicationChannel : SecurableCommunicationChannel .values()) { assertSSLConfig(properties, SSLConfigurationFactory.getSSLConfigForComponent(securableCommunicationChannel), securableCommunicationChannel, distributionConfig); } } @Test public void getSSLConfigForComponentHTTPServiceWithMutualAuth() throws Exception { Properties properties = new Properties(); properties.setProperty(SSL_ENABLED_COMPONENTS, SecurableCommunicationChannel.WEB.getConstant()); properties.setProperty(SSL_KEYSTORE, "someKeyStore"); properties.setProperty(SSL_KEYSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_KEYSTORE_TYPE, "JKS"); properties.setProperty(SSL_TRUSTSTORE, "someKeyStore"); properties.setProperty(SSL_TRUSTSTORE_PASSWORD, "keystorePassword"); properties.setProperty(SSL_DEFAULT_ALIAS, "defaultAlias"); properties.setProperty(SSL_WEB_ALIAS, "httpAlias"); properties.setProperty(SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION, "true"); properties.setProperty(SSL_CIPHERS, "any"); properties.setProperty(SSL_PROTOCOLS, "any"); DistributionConfigImpl distributionConfig = new DistributionConfigImpl(properties); SSLConfigurationFactory.setDistributionConfig(distributionConfig); for (SecurableCommunicationChannel securableCommunicationChannel : SecurableCommunicationChannel .values()) { assertSSLConfig(properties, SSLConfigurationFactory.getSSLConfigForComponent(securableCommunicationChannel), securableCommunicationChannel, distributionConfig); } } @Test public void getSSLConfigUsingJavaProperties() { Properties properties = new Properties(); properties.setProperty(CLUSTER_SSL_ENABLED, "true"); properties.setProperty(MCAST_PORT, "0"); System.setProperty(SSLConfigurationFactory.JAVAX_KEYSTORE, "keystore"); System.setProperty(SSLConfigurationFactory.JAVAX_KEYSTORE_TYPE, "JKS"); System.setProperty(SSLConfigurationFactory.JAVAX_KEYSTORE_PASSWORD, "keystorePassword"); System.setProperty(SSLConfigurationFactory.JAVAX_TRUSTSTORE, "truststore"); System.setProperty(SSLConfigurationFactory.JAVAX_TRUSTSTORE_PASSWORD, "truststorePassword"); System.setProperty(SSLConfigurationFactory.JAVAX_TRUSTSTORE_TYPE, "JKS"); DistributionConfigImpl distributionConfig = new DistributionConfigImpl(properties); SSLConfigurationFactory.setDistributionConfig(distributionConfig); SSLConfig sslConfig = SSLConfigurationFactory.getSSLConfigForComponent(SecurableCommunicationChannel.CLUSTER); assertEquals(true, sslConfig.isEnabled()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_KEYSTORE), sslConfig.getKeystore()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_KEYSTORE_PASSWORD), sslConfig.getKeystorePassword()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_KEYSTORE_TYPE), sslConfig.getKeystoreType()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_TRUSTSTORE), sslConfig.getTruststore()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_TRUSTSTORE_PASSWORD), sslConfig.getTruststorePassword()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_TRUSTSTORE_TYPE), sslConfig.getTruststoreType()); assertEquals(true, sslConfig.isEnabled()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_KEYSTORE), sslConfig.getKeystore()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_KEYSTORE_PASSWORD), sslConfig.getKeystorePassword()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_KEYSTORE_TYPE), sslConfig.getKeystoreType()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_TRUSTSTORE), sslConfig.getTruststore()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_TRUSTSTORE_PASSWORD), sslConfig.getTruststorePassword()); assertEquals(System.getProperty(SSLConfigurationFactory.JAVAX_TRUSTSTORE_TYPE), sslConfig.getTruststoreType()); } @Test public void getSSLHTTPMutualAuthenticationOffWithDefaultConfiguration() { Properties properties = new Properties(); properties.setProperty(CLUSTER_SSL_ENABLED, "true"); properties.setProperty(MCAST_PORT, "0"); DistributionConfigImpl distributionConfig = new DistributionConfigImpl(properties); SSLConfigurationFactory.setDistributionConfig(distributionConfig); SSLConfig sslConfig = SSLConfigurationFactory.getSSLConfigForComponent(SecurableCommunicationChannel.WEB); assertEquals(false, sslConfig.isRequireAuth()); assertEquals(true, sslConfig.isEnabled()); sslConfig = SSLConfigurationFactory.getSSLConfigForComponent(SecurableCommunicationChannel.CLUSTER); assertEquals(true, sslConfig.isRequireAuth()); assertEquals(true, sslConfig.isEnabled()); sslConfig = SSLConfigurationFactory.getSSLConfigForComponent(SecurableCommunicationChannel.GATEWAY); assertEquals(true, sslConfig.isRequireAuth()); assertEquals(true, sslConfig.isEnabled()); sslConfig = SSLConfigurationFactory.getSSLConfigForComponent(SecurableCommunicationChannel.SERVER); assertEquals(true, sslConfig.isRequireAuth()); assertEquals(true, sslConfig.isEnabled()); sslConfig = SSLConfigurationFactory.getSSLConfigForComponent(SecurableCommunicationChannel.JMX); assertEquals(true, sslConfig.isRequireAuth()); assertEquals(true, sslConfig.isEnabled()); } private void assertSSLConfig(final Properties properties, final SSLConfig sslConfig, final SecurableCommunicationChannel expectedSecurableComponent, final DistributionConfigImpl distributionConfig) { assertEquals(isSSLComponentEnabled(expectedSecurableComponent, distributionConfig.getSecurableCommunicationChannels()), sslConfig.isEnabled()); if (sslConfig.isEnabled()) { assertEquals(properties.getProperty(SSL_KEYSTORE), sslConfig.getKeystore()); assertEquals(properties.getProperty(SSL_KEYSTORE_PASSWORD), sslConfig.getKeystorePassword()); assertEquals(properties.getProperty(SSL_KEYSTORE_TYPE), sslConfig.getKeystoreType()); assertEquals(properties.getProperty(SSL_TRUSTSTORE), sslConfig.getTruststore()); assertEquals(properties.getProperty(SSL_TRUSTSTORE_PASSWORD), sslConfig.getTruststorePassword()); assertEquals(properties.getProperty(SSL_CIPHERS).replace(",", " "), sslConfig.getCiphers()); assertEquals(properties.getProperty(SSL_PROTOCOLS).replace(",", " "), sslConfig.getProtocols()); assertEquals(getCorrectAlias(expectedSecurableComponent, properties), sslConfig.getAlias()); assertEquals(requiresAuthentication(properties, expectedSecurableComponent), sslConfig.isRequireAuth()); assertEquals(expectedSecurableComponent, sslConfig.getSecuredCommunicationChannel()); } } private boolean requiresAuthentication(final Properties properties, final SecurableCommunicationChannel expectedSecurableComponent) { boolean defaultAuthentication = expectedSecurableComponent.equals(SecurableCommunicationChannel.WEB) ? DistributionConfig.DEFAULT_SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION : DistributionConfig.DEFAULT_SSL_REQUIRE_AUTHENTICATION; String httpRequiresAuthentication = properties.getProperty(SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION); return httpRequiresAuthentication == null ? defaultAuthentication : Boolean.parseBoolean(httpRequiresAuthentication); } private String getCorrectAlias(final SecurableCommunicationChannel expectedSecurableComponent, final Properties properties) { switch (expectedSecurableComponent) { case ALL: return properties.getProperty(SSL_DEFAULT_ALIAS); case CLUSTER: return getAliasForComponent(properties, SSL_CLUSTER_ALIAS); case GATEWAY: return getAliasForComponent(properties, SSL_GATEWAY_ALIAS); case WEB: return getAliasForComponent(properties, SSL_WEB_ALIAS); case JMX: return getAliasForComponent(properties, SSL_JMX_ALIAS); case LOCATOR: return getAliasForComponent(properties, SSL_LOCATOR_ALIAS); case SERVER: return getAliasForComponent(properties, SSL_SERVER_ALIAS); default: return properties.getProperty(SSL_DEFAULT_ALIAS); } } private String getAliasForComponent(final Properties properties, final String componentAliasProperty) { String aliasProperty = properties.getProperty(componentAliasProperty); return !StringUtils.isEmpty(aliasProperty) ? aliasProperty : properties.getProperty(SSL_DEFAULT_ALIAS); } private boolean isSSLComponentEnabled( final SecurableCommunicationChannel expectedSecurableComponent, final SecurableCommunicationChannel[] securableComponents) { for (SecurableCommunicationChannel securableCommunicationChannel : securableComponents) { if (SecurableCommunicationChannel.ALL.equals(securableCommunicationChannel) || securableCommunicationChannel.equals(expectedSecurableComponent)) { return true; } } return false; } }