/* * 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 org.apache.commons.lang.ArrayUtils; import org.apache.commons.lang.StringUtils; import org.apache.geode.GemFireConfigException; import org.apache.geode.distributed.internal.DistributionConfig; import org.apache.geode.internal.admin.SSLConfig; import org.apache.geode.internal.security.SecurableCommunicationChannel; import java.util.HashMap; import java.util.Map; import java.util.Properties; public class SSLConfigurationFactory { public static final String JAVAX_KEYSTORE = "javax.net.ssl.keyStore"; public static final String JAVAX_KEYSTORE_TYPE = "javax.net.ssl.keyStoreType"; public static final String JAVAX_KEYSTORE_PASSWORD = "javax.net.ssl.keyStorePassword"; public static final String JAVAX_TRUSTSTORE = "javax.net.ssl.trustStore"; public static final String JAVAX_TRUSTSTORE_PASSWORD = "javax.net.ssl.trustStorePassword"; public static final String JAVAX_TRUSTSTORE_TYPE = "javax.net.ssl.trustStoreType"; private static SSLConfigurationFactory instance = new SSLConfigurationFactory(); private DistributionConfig distributionConfig = null; private Map<SecurableCommunicationChannel, SSLConfig> registeredSSLConfig = new HashMap<>(); private SSLConfigurationFactory() {} private synchronized static SSLConfigurationFactory getInstance() { if (instance == null) { instance = new SSLConfigurationFactory(); } return instance; } private DistributionConfig getDistributionConfig() { if (distributionConfig == null) { throw new GemFireConfigException("SSL Configuration requires a valid distribution config."); } return distributionConfig; } public static void setDistributionConfig(final DistributionConfig distributionConfig) { if (distributionConfig == null) { throw new GemFireConfigException("SSL Configuration requires a valid distribution config."); } getInstance().distributionConfig = distributionConfig; } public static SSLConfig getSSLConfigForComponent( SecurableCommunicationChannel sslEnabledComponent) { SSLConfig sslConfig = getInstance().getRegisteredSSLConfigForComponent(sslEnabledComponent); if (sslConfig == null) { sslConfig = getInstance().createSSLConfigForComponent(sslEnabledComponent); getInstance().registeredSSLConfigForComponent(sslEnabledComponent, sslConfig); } return sslConfig; } private synchronized void registeredSSLConfigForComponent( final SecurableCommunicationChannel sslEnabledComponent, final SSLConfig sslConfig) { registeredSSLConfig.put(sslEnabledComponent, sslConfig); } private SSLConfig createSSLConfigForComponent( final SecurableCommunicationChannel sslEnabledComponent) { SSLConfig sslConfig = createSSLConfig(sslEnabledComponent); SecurableCommunicationChannel[] sslEnabledComponents = getDistributionConfig().getSecurableCommunicationChannels(); if (sslEnabledComponents.length == 0) { sslConfig = configureLegacyClusterSSL(sslConfig); } sslConfig.setSecurableCommunicationChannel(sslEnabledComponent); switch (sslEnabledComponent) { case ALL: { // Create a SSLConfig separate for HTTP Service. As the require-authentication might differ createSSLConfigForComponent(SecurableCommunicationChannel.WEB); break; } case CLUSTER: { if (sslEnabledComponents.length > 0) { sslConfig = setAliasForComponent(sslConfig, getDistributionConfig().getClusterSSLAlias()); } else { sslConfig = configureLegacyClusterSSL(sslConfig); } break; } case LOCATOR: { if (sslEnabledComponents.length > 0) { sslConfig = setAliasForComponent(sslConfig, getDistributionConfig().getLocatorSSLAlias()); } break; } case SERVER: { if (sslEnabledComponents.length > 0) { sslConfig = setAliasForComponent(sslConfig, getDistributionConfig().getServerSSLAlias()); } else { sslConfig = configureLegacyServerSSL(sslConfig); } break; } case GATEWAY: { if (sslEnabledComponents.length > 0) { sslConfig = setAliasForComponent(sslConfig, getDistributionConfig().getGatewaySSLAlias()); } else { sslConfig = configureLegacyGatewaySSL(sslConfig); } break; } case WEB: { if (sslEnabledComponents.length > 0) { sslConfig = setAliasForComponent(sslConfig, getDistributionConfig().getHTTPServiceSSLAlias()); sslConfig.setRequireAuth(getDistributionConfig().getSSLWebRequireAuthentication()); } else { sslConfig = configureLegacyHttpServiceSSL(sslConfig); } break; } case JMX: { if (sslEnabledComponents.length > 0) { sslConfig = setAliasForComponent(sslConfig, getDistributionConfig().getJMXSSLAlias()); } else { sslConfig = configureLegacyJMXSSL(sslConfig); } break; } } configureSSLPropertiesFromSystemProperties(sslConfig); return sslConfig; } private SSLConfig setAliasForComponent(final SSLConfig sslConfig, final String clusterSSLAlias) { if (!StringUtils.isEmpty(clusterSSLAlias)) { sslConfig.setAlias(clusterSSLAlias); } return sslConfig; } private SSLConfig createSSLConfig(final SecurableCommunicationChannel sslEnabledComponent) { SSLConfig sslConfig = new SSLConfig(); sslConfig.setCiphers(getDistributionConfig().getSSLCiphers()); sslConfig.setEnabled(determineIfSSLEnabledForSSLComponent(sslEnabledComponent)); sslConfig.setKeystore(getDistributionConfig().getSSLKeyStore()); sslConfig.setKeystorePassword(getDistributionConfig().getSSLKeyStorePassword()); sslConfig.setKeystoreType(getDistributionConfig().getSSLKeyStoreType()); sslConfig.setTruststore(getDistributionConfig().getSSLTrustStore()); sslConfig.setTruststorePassword(getDistributionConfig().getSSLTrustStorePassword()); sslConfig.setProtocols(getDistributionConfig().getSSLProtocols()); sslConfig.setRequireAuth(getDistributionConfig().getSSLRequireAuthentication()); sslConfig.setAlias(getDistributionConfig().getSSLDefaultAlias()); return sslConfig; } private boolean determineIfSSLEnabledForSSLComponent( final SecurableCommunicationChannel sslEnabledComponent) { if (ArrayUtils.contains(getDistributionConfig().getSecurableCommunicationChannels(), SecurableCommunicationChannel.NONE)) { return false; } if (ArrayUtils.contains(getDistributionConfig().getSecurableCommunicationChannels(), SecurableCommunicationChannel.ALL)) { return true; } return ArrayUtils.contains(getDistributionConfig().getSecurableCommunicationChannels(), sslEnabledComponent) ? true : false; } /** * Configure a sslConfig for the cluster using the legacy configuration * * @return A sslConfig object describing the ssl config for the server component * @deprecated as of Geode 1.0 */ private SSLConfig configureLegacyClusterSSL(SSLConfig sslConfig) { sslConfig.setCiphers(getDistributionConfig().getClusterSSLCiphers()); sslConfig.setEnabled(getDistributionConfig().getClusterSSLEnabled()); sslConfig.setKeystore(getDistributionConfig().getClusterSSLKeyStore()); sslConfig.setKeystorePassword(getDistributionConfig().getClusterSSLKeyStorePassword()); sslConfig.setKeystoreType(getDistributionConfig().getClusterSSLKeyStoreType()); sslConfig.setTruststore(getDistributionConfig().getClusterSSLTrustStore()); sslConfig.setTruststorePassword(getDistributionConfig().getClusterSSLTrustStorePassword()); sslConfig.setProtocols(getDistributionConfig().getClusterSSLProtocols()); sslConfig.setRequireAuth(getDistributionConfig().getClusterSSLRequireAuthentication()); return sslConfig; } /** * Configure a sslConfig for the server using the legacy configuration * * @return A sslConfig object describing the ssl config for the server component * @deprecated as of Geode 1.0 */ private SSLConfig configureLegacyServerSSL(SSLConfig sslConfig) { sslConfig.setCiphers(getDistributionConfig().getServerSSLCiphers()); sslConfig.setEnabled(getDistributionConfig().getServerSSLEnabled()); sslConfig.setKeystore(getDistributionConfig().getServerSSLKeyStore()); sslConfig.setKeystorePassword(getDistributionConfig().getServerSSLKeyStorePassword()); sslConfig.setKeystoreType(getDistributionConfig().getServerSSLKeyStoreType()); sslConfig.setTruststore(getDistributionConfig().getServerSSLTrustStore()); sslConfig.setTruststorePassword(getDistributionConfig().getServerSSLTrustStorePassword()); sslConfig.setProtocols(getDistributionConfig().getServerSSLProtocols()); sslConfig.setRequireAuth(getDistributionConfig().getServerSSLRequireAuthentication()); return sslConfig; } /** * Configure a sslConfig for the jmx using the legacy configuration * * @return A sslConfig object describing the ssl config for the jmx component * @deprecated as of Geode 1.0 */ private SSLConfig configureLegacyJMXSSL(SSLConfig sslConfig) { sslConfig.setCiphers(getDistributionConfig().getJmxManagerSSLCiphers()); sslConfig.setEnabled(getDistributionConfig().getJmxManagerSSLEnabled()); sslConfig.setKeystore(getDistributionConfig().getJmxManagerSSLKeyStore()); sslConfig.setKeystorePassword(getDistributionConfig().getJmxManagerSSLKeyStorePassword()); sslConfig.setKeystoreType(getDistributionConfig().getJmxManagerSSLKeyStoreType()); sslConfig.setTruststore(getDistributionConfig().getJmxManagerSSLTrustStore()); sslConfig.setTruststorePassword(getDistributionConfig().getJmxManagerSSLTrustStorePassword()); sslConfig.setProtocols(getDistributionConfig().getJmxManagerSSLProtocols()); sslConfig.setRequireAuth(getDistributionConfig().getJmxManagerSSLRequireAuthentication()); return sslConfig; } /** * Configure a sslConfig for the gateway using the legacy configuration * * @return A sslConfig object describing the ssl config for the gateway component * @deprecated as of Geode 1.0 */ private SSLConfig configureLegacyGatewaySSL(SSLConfig sslConfig) { sslConfig.setCiphers(getDistributionConfig().getGatewaySSLCiphers()); sslConfig.setEnabled(getDistributionConfig().getGatewaySSLEnabled()); sslConfig.setKeystore(getDistributionConfig().getGatewaySSLKeyStore()); sslConfig.setKeystorePassword(getDistributionConfig().getGatewaySSLKeyStorePassword()); sslConfig.setKeystoreType(getDistributionConfig().getGatewaySSLKeyStoreType()); sslConfig.setTruststore(getDistributionConfig().getGatewaySSLTrustStore()); sslConfig.setTruststorePassword(getDistributionConfig().getGatewaySSLTrustStorePassword()); sslConfig.setProtocols(getDistributionConfig().getGatewaySSLProtocols()); sslConfig.setRequireAuth(getDistributionConfig().getGatewaySSLRequireAuthentication()); return sslConfig; } /** * Configure a sslConfig for the http service using the legacy configuration * * @return A sslConfig object describing the ssl config for the http service component * @deprecated as of Geode 1.0 */ private SSLConfig configureLegacyHttpServiceSSL(SSLConfig sslConfig) { sslConfig.setCiphers(getDistributionConfig().getHttpServiceSSLCiphers()); sslConfig.setEnabled(getDistributionConfig().getHttpServiceSSLEnabled()); sslConfig.setKeystore(getDistributionConfig().getHttpServiceSSLKeyStore()); sslConfig.setKeystorePassword(getDistributionConfig().getHttpServiceSSLKeyStorePassword()); sslConfig.setKeystoreType(getDistributionConfig().getHttpServiceSSLKeyStoreType()); sslConfig.setTruststore(getDistributionConfig().getHttpServiceSSLTrustStore()); sslConfig.setTruststorePassword(getDistributionConfig().getHttpServiceSSLTrustStorePassword()); sslConfig.setProtocols(getDistributionConfig().getHttpServiceSSLProtocols()); sslConfig.setRequireAuth(getDistributionConfig().getHttpServiceSSLRequireAuthentication()); return sslConfig; } private SSLConfig configureSSLPropertiesFromSystemProperties(SSLConfig sslConfig) { return configureSSLPropertiesFromSystemProperties(sslConfig, null); } private SSLConfig configureSSLPropertiesFromSystemProperties(SSLConfig sslConfig, Properties properties) { if (StringUtils.isEmpty(sslConfig.getKeystore())) { sslConfig.setKeystore(getValueFromSystemProperties(properties, JAVAX_KEYSTORE)); } if (StringUtils.isEmpty(sslConfig.getKeystoreType())) { sslConfig.setKeystoreType(getValueFromSystemProperties(properties, JAVAX_KEYSTORE_TYPE)); } if (StringUtils.isEmpty(sslConfig.getKeystorePassword())) { sslConfig .setKeystorePassword(getValueFromSystemProperties(properties, JAVAX_KEYSTORE_PASSWORD)); } if (StringUtils.isEmpty(sslConfig.getTruststore())) { sslConfig.setTruststore(getValueFromSystemProperties(properties, JAVAX_TRUSTSTORE)); } if (StringUtils.isEmpty(sslConfig.getTruststorePassword())) { sslConfig.setTruststorePassword( getValueFromSystemProperties(properties, JAVAX_TRUSTSTORE_PASSWORD)); } if (StringUtils.isEmpty(sslConfig.getTruststoreType())) { sslConfig.setTruststoreType(getValueFromSystemProperties(properties, JAVAX_TRUSTSTORE_TYPE)); } return sslConfig; } private String getValueFromSystemProperties(final Properties properties, String property) { String propertyValue = null; if (properties != null) { propertyValue = properties.getProperty(property); } if (property != null) { propertyValue = System.getProperty(property); if (propertyValue != null) { if (propertyValue.trim().equals("")) { propertyValue = System.getenv(property); } } } return propertyValue; } private SSLConfig getRegisteredSSLConfigForComponent( final SecurableCommunicationChannel sslEnabledComponent) { return registeredSSLConfig.get(sslEnabledComponent); } public static void close() { getInstance().clearSSLConfigForAllComponents(); getInstance().distributionConfig = null; } private void clearSSLConfigForAllComponents() { registeredSSLConfig.clear(); } @Deprecated public static SSLConfig getSSLConfigForComponent(final boolean useSSL, final boolean needClientAuth, final String protocols, final String ciphers, final Properties gfsecurityProps, final String alias) { SSLConfig sslConfig = new SSLConfig(); sslConfig.setAlias(alias); sslConfig.setCiphers(ciphers); sslConfig.setProtocols(protocols); sslConfig.setRequireAuth(needClientAuth); sslConfig.setEnabled(useSSL); sslConfig = getInstance().configureSSLPropertiesFromSystemProperties(sslConfig, gfsecurityProps); return sslConfig; } }