You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@geode.apache.org by mi...@apache.org on 2020/01/14 15:15:25 UTC
[geode] branch develop updated: GEODE-7414_1: Define interface
(#4505)
This is an automated email from the ASF dual-hosted git repository.
mivanac pushed a commit to branch develop
in repository https://gitbox.apache.org/repos/asf/geode.git
The following commit(s) were added to refs/heads/develop by this push:
new dddfce0 GEODE-7414_1: Define interface (#4505)
dddfce0 is described below
commit dddfce0a273a542744b6baab1d3ea535d11894c7
Author: Mario Ivanac <48...@users.noreply.github.com>
AuthorDate: Tue Jan 14 16:14:59 2020 +0100
GEODE-7414_1: Define interface (#4505)
* GEODE-7414_1: Introduction of SSL Parameter Extension
- Define interface
- added config parameter
- added SSLParameterExtension implementation
---
.../integrationTest/resources/assembly_content.txt | 4 +
...SSLSocketParameterExtensionIntegrationTest.java | 242 +++++++++++++++++++++
.../geode/distributed/ConfigurationProperties.java | 16 ++
.../internal/AbstractDistributionConfig.java | 3 +
.../distributed/internal/DistributionConfig.java | 30 +++
.../internal/DistributionConfigImpl.java | 20 +-
.../org/apache/geode/internal/admin/SSLConfig.java | 42 +++-
.../internal/net/SSLConfigurationFactory.java | 2 +
.../apache/geode/internal/net/SocketCreator.java | 16 ++
.../apache/geode/net/SSLParameterExtension.java | 44 ++++
.../internal/DistributionConfigJUnitTest.java | 4 +-
.../topics/gemfire_properties.html.md.erb | 7 +
12 files changed, 424 insertions(+), 6 deletions(-)
diff --git a/geode-assembly/src/integrationTest/resources/assembly_content.txt b/geode-assembly/src/integrationTest/resources/assembly_content.txt
index 7fca5a5..1ea16d7 100644
--- a/geode-assembly/src/integrationTest/resources/assembly_content.txt
+++ b/geode-assembly/src/integrationTest/resources/assembly_content.txt
@@ -887,6 +887,10 @@ javadoc/org/apache/geode/modules/util/TouchReplicatedRegionEntriesFunction.html
javadoc/org/apache/geode/modules/util/package-frame.html
javadoc/org/apache/geode/modules/util/package-summary.html
javadoc/org/apache/geode/modules/util/package-tree.html
+javadoc/org/apache/geode/net/SSLParameterExtension.html
+javadoc/org/apache/geode/net/package-frame.html
+javadoc/org/apache/geode/net/package-summary.html
+javadoc/org/apache/geode/net/package-tree.html
javadoc/org/apache/geode/package-frame.html
javadoc/org/apache/geode/package-summary.html
javadoc/org/apache/geode/package-tree.html
diff --git a/geode-core/src/integrationTest/java/org/apache/geode/net/SSLSocketParameterExtensionIntegrationTest.java b/geode-core/src/integrationTest/java/org/apache/geode/net/SSLSocketParameterExtensionIntegrationTest.java
new file mode 100644
index 0000000..18c67d4
--- /dev/null
+++ b/geode-core/src/integrationTest/java/org/apache/geode/net/SSLSocketParameterExtensionIntegrationTest.java
@@ -0,0 +1,242 @@
+/*
+ * 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.net;
+
+import static org.apache.geode.distributed.ConfigurationProperties.CLUSTER_SSL_CIPHERS;
+import static org.apache.geode.distributed.ConfigurationProperties.CLUSTER_SSL_ENABLED;
+import static org.apache.geode.distributed.ConfigurationProperties.CLUSTER_SSL_PROTOCOLS;
+import static org.apache.geode.distributed.ConfigurationProperties.CLUSTER_SSL_REQUIRE_AUTHENTICATION;
+import static org.apache.geode.distributed.ConfigurationProperties.DISTRIBUTED_SYSTEM_ID;
+import static org.apache.geode.distributed.ConfigurationProperties.MCAST_PORT;
+import static org.apache.geode.distributed.ConfigurationProperties.SSL_PARAMETER_EXTENSION;
+import static org.apache.geode.internal.security.SecurableCommunicationChannel.CLUSTER;
+import static org.apache.geode.test.awaitility.GeodeAwaitility.await;
+import static org.assertj.core.api.Assertions.assertThat;
+import static org.junit.Assert.assertNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.ObjectInputStream;
+import java.io.ObjectOutputStream;
+import java.net.InetAddress;
+import java.net.ServerSocket;
+import java.net.Socket;
+import java.net.URL;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Properties;
+import java.util.concurrent.atomic.AtomicReference;
+
+import javax.net.ssl.SNIHostName;
+import javax.net.ssl.SNIServerName;
+import javax.net.ssl.SSLParameters;
+import javax.net.ssl.SSLSocket;
+
+import org.apache.commons.io.FileUtils;
+import org.junit.After;
+import org.junit.Before;
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.contrib.java.lang.system.RestoreSystemProperties;
+import org.junit.experimental.categories.Category;
+import org.junit.rules.ErrorCollector;
+import org.junit.rules.TemporaryFolder;
+import org.junit.rules.TestName;
+
+import org.apache.geode.cache.CacheFactory;
+import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.DistributionConfigImpl;
+import org.apache.geode.internal.cache.InternalCache;
+import org.apache.geode.internal.net.SocketCreator;
+import org.apache.geode.internal.net.SocketCreatorFactory;
+import org.apache.geode.test.dunit.IgnoredException;
+import org.apache.geode.test.junit.categories.MembershipTest;
+
+@Category({MembershipTest.class})
+public class SSLSocketParameterExtensionIntegrationTest {
+
+ private static final String MESSAGE =
+ SSLSocketParameterExtensionIntegrationTest.class.getName() + " Message";
+
+ private AtomicReference<String> messageFromClient = new AtomicReference<>();
+
+ private DistributionConfig distributionConfig;
+ private SocketCreator socketCreator;
+ private InetAddress localHost;
+ private Thread serverThread;
+ private ServerSocket serverSocket;
+ private Socket clientSocket;
+ private InternalCache cache;
+
+ @Rule
+ public ErrorCollector errorCollector = new ErrorCollector();
+
+ @Rule
+ public RestoreSystemProperties restoreSystemProperties = new RestoreSystemProperties();
+
+ @Rule
+ public TemporaryFolder temporaryFolder = new TemporaryFolder();
+
+ @Rule
+ public TestName testName = new TestName();
+
+
+ private Throwable serverException;
+
+ @Before
+ public void setUp() throws Exception {
+ IgnoredException.addIgnoredException("javax.net.ssl.SSLException: Read timed out");
+
+ File keystore = findTestKeystore();
+ System.setProperty("javax.net.ssl.trustStore", keystore.getCanonicalPath());
+ System.setProperty("javax.net.ssl.trustStorePassword", "password");
+ System.setProperty("javax.net.ssl.keyStore", keystore.getCanonicalPath());
+ System.setProperty("javax.net.ssl.keyStorePassword", "password");
+
+ Properties properties = new Properties();
+ properties.setProperty(MCAST_PORT, "0");
+ properties.setProperty(CLUSTER_SSL_ENABLED, "true");
+ properties.setProperty(CLUSTER_SSL_REQUIRE_AUTHENTICATION, "true");
+ properties.setProperty(CLUSTER_SSL_CIPHERS, "any");
+ properties.setProperty(CLUSTER_SSL_PROTOCOLS, "TLSv1.2");
+ properties.setProperty(SSL_PARAMETER_EXTENSION, MySSLParameterExtension.class.getName());
+ properties.setProperty(DISTRIBUTED_SYSTEM_ID, "11");
+
+ cache = (InternalCache) new CacheFactory(properties).create();
+
+ this.distributionConfig = new DistributionConfigImpl(properties);
+
+ SocketCreatorFactory.setDistributionConfig(this.distributionConfig);
+ this.socketCreator = SocketCreatorFactory.getSocketCreatorForComponent(CLUSTER);
+
+ this.localHost = InetAddress.getLocalHost();
+ }
+
+ @After
+ public void tearDown() throws Exception {
+ if (this.clientSocket != null) {
+ this.clientSocket.close();
+ }
+ if (this.serverSocket != null) {
+ this.serverSocket.close();
+ }
+ if (this.serverThread != null && this.serverThread.isAlive()) {
+ this.serverThread.interrupt();
+ }
+ SocketCreatorFactory.close();
+ cache.close();
+ }
+
+ @Test
+ public void securedSocketCheckExtensions() throws Exception {
+ this.serverSocket = this.socketCreator.createServerSocket(0, 0, this.localHost);
+ this.serverThread = startServer(this.serverSocket, 15000);
+
+ int serverPort = this.serverSocket.getLocalPort();
+ this.clientSocket = this.socketCreator.connectForServer(this.localHost, serverPort);
+
+ SSLSocket sslSocket = (SSLSocket) this.clientSocket;
+
+ List<SNIServerName> serverNames = new ArrayList<>(1);
+ SNIHostName serverName = new SNIHostName("11");
+ serverNames.add(serverName);
+
+ assertThat(sslSocket.getSSLParameters().getServerNames()).isEqualTo(serverNames);
+
+ // transmit expected string from Client to Server
+ ObjectOutputStream output = new ObjectOutputStream(this.clientSocket.getOutputStream());
+ output.writeObject(MESSAGE);
+ output.flush();
+
+ // this is the real assertion of this test
+ await().until(() -> {
+ return !serverThread.isAlive();
+ });
+ assertNull(serverException);
+ assertThat(this.messageFromClient.get()).isEqualTo(MESSAGE);
+ }
+
+ private File findTestKeystore() throws IOException {
+ return copyKeystoreResourceToFile("/ssl/trusted.keystore");
+ }
+
+ public File copyKeystoreResourceToFile(final String name) throws IOException {
+ URL resource = getClass().getResource(name);
+ assertThat(resource).isNotNull();
+
+ File file = this.temporaryFolder.newFile(name.replaceFirst(".*/", ""));
+ FileUtils.copyURLToFile(resource, file);
+ return file;
+ }
+
+ private Thread startServer(final ServerSocket serverSocket, int timeoutMillis) throws Exception {
+ Thread serverThread = new Thread(new MyThreadGroup(this.testName.getMethodName()), () -> {
+ try {
+ Socket socket = serverSocket.accept();
+ SocketCreatorFactory.getSocketCreatorForComponent(CLUSTER).handshakeIfSocketIsSSL(socket,
+ timeoutMillis);
+ assertThat(socket.getSoTimeout()).isEqualTo(0);
+
+ ObjectInputStream ois = new ObjectInputStream(socket.getInputStream());
+ messageFromClient.set((String) ois.readObject());
+ } catch (Throwable throwable) {
+ serverException = throwable;
+ }
+ }, this.testName.getMethodName() + "-server");
+
+ serverThread.start();
+ return serverThread;
+ }
+
+ private class MyThreadGroup extends ThreadGroup {
+
+ public MyThreadGroup(final String name) {
+ super(name);
+ }
+
+ @Override
+ public void uncaughtException(final Thread thread, final Throwable throwable) {
+ errorCollector.addError(throwable);
+ }
+ }
+
+ public static class MySSLParameterExtension implements SSLParameterExtension {
+ DistributionConfig config;
+
+ @Override
+ public void init(DistributionConfig config) {
+ this.config = config;
+ }
+
+ @Override
+ public SSLParameters modifySSLClientSocketParameters(SSLParameters parameters) {
+ List<SNIServerName> serverNames = new ArrayList<>(1);
+ SNIHostName serverName = new SNIHostName(String.valueOf(config.getDistributedSystemId()));
+ serverNames.add(serverName);
+ parameters.setServerNames(serverNames);
+ return parameters;
+ }
+
+ @Override
+ public SSLParameters modifySSLServerSocketParameters(SSLParameters parameters) {
+ List<SNIServerName> serverNames = new ArrayList<>(1);
+ SNIHostName serverName = new SNIHostName("server");
+ serverNames.add(serverName);
+ parameters.setServerNames(serverNames);
+ return parameters;
+ }
+
+ }
+}
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/ConfigurationProperties.java b/geode-core/src/main/java/org/apache/geode/distributed/ConfigurationProperties.java
index d06b962..f07988f 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/ConfigurationProperties.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/ConfigurationProperties.java
@@ -2155,6 +2155,22 @@ public interface ConfigurationProperties {
* <U>Since</U>: Geode 1.0
*/
String SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION = "ssl-web-require-authentication";
+
+ /**
+ * The static String definition of the <i>"ssl-parameter-extension"</i> property
+ *
+ * <U>Description</U>SSLParameterExtension module name for Clients that want to use SSL Parameter
+ * extensions.
+ * Module must implement SSLParameterExtension interface.
+ * </p>
+ * <U>Default</U>: ""
+ * </p>
+ * <U>Since</U>: Geode 1.12
+ * </p>
+ * <U>Allowed values</U>: class name
+ */
+ String SSL_PARAMETER_EXTENSION = "ssl-parameter-extension";
+
/**
* The static String definition of the <i>"validate-serializable-objects"</i> property
*
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/AbstractDistributionConfig.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/AbstractDistributionConfig.java
index c21d330..f88e14d 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/AbstractDistributionConfig.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/AbstractDistributionConfig.java
@@ -158,6 +158,7 @@ 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_PARAMETER_EXTENSION;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_PROTOCOLS;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_REQUIRE_AUTHENTICATION;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_SERVER_ALIAS;
@@ -1474,6 +1475,8 @@ public abstract class AbstractDistributionConfig extends AbstractConfig
m.put(SSL_DEFAULT_ALIAS, "The default certificate alias to be used in a multi-key keystore");
m.put(SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION,
"This property determines is the HTTP service with use mutual ssl authentication.");
+ m.put(SSL_PARAMETER_EXTENSION,
+ "User defined fully qualified class name implementing SSLParameterExtension interface for SSL parameter extensions. Defaults to \"{0}\". Legal values can be any \"class name\" implementing SSLParameterExtension that is present in the classpath.");
m.put(VALIDATE_SERIALIZABLE_OBJECTS,
"If true checks incoming java serializable objects against a filter");
m.put(SERIALIZABLE_OBJECT_FILTER, "The filter to check incoming java serializables against");
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfig.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfig.java
index d91bd6c..89a19a6 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfig.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfig.java
@@ -158,6 +158,7 @@ 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_PARAMETER_EXTENSION;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_PROTOCOLS;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_REQUIRE_AUTHENTICATION;
import static org.apache.geode.distributed.ConfigurationProperties.SSL_SERVER_ALIAS;
@@ -5257,6 +5258,35 @@ public interface DistributionConfig extends Config, LogConfig, StatisticsConfig
*/
boolean DEFAULT_SSL_WEB_SERVICE_REQUIRE_AUTHENTICATION = false;
+
+ /**
+ * Returns user defined class name SSL Parameter Extension in
+ * {@link ConfigurationProperties#SSL_PARAMETER_EXTENSION}
+ */
+ @ConfigAttributeGetter(name = SSL_PARAMETER_EXTENSION)
+ String getSSLParameterExtension();
+
+ /**
+ * Sets the user defined class name in {@link ConfigurationProperties#SSL_PARAMETER_EXTENSION}
+ * property.
+ */
+ @ConfigAttributeSetter(name = SSL_PARAMETER_EXTENSION)
+ void setSSLParameterExtension(String attValue);
+
+ /**
+ * The name of class for {@link ConfigurationProperties#SSL_PARAMETER_EXTENSION} property
+ */
+ @ConfigAttribute(type = String.class)
+ String SSL_PARAMETER_EXTENSION_NAME = SSL_PARAMETER_EXTENSION;
+
+ /**
+ * The default {@link ConfigurationProperties#SSL_PARAMETER_EXTENSION} class name.
+ * <p>
+ * Actual value of this is fully qualified <code>"class name"</code>.
+ */
+ String DEFAULT_SSL_PARAMETER_EXTENSION = "";
+
+
/**
* Returns the value of the {@link ConfigurationProperties#VALIDATE_SERIALIZABLE_OBJECTS} property
*/
diff --git a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfigImpl.java b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfigImpl.java
index 55d79b2..8a599ba 100644
--- a/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfigImpl.java
+++ b/geode-core/src/main/java/org/apache/geode/distributed/internal/DistributionConfigImpl.java
@@ -628,6 +628,11 @@ public class DistributionConfigImpl extends AbstractDistributionConfig implement
private String sslDefaultAlias = DEFAULT_SSL_ALIAS;
+ /**
+ * The SSL Parameter Extension class name
+ */
+ private String sslParameterExtension = DEFAULT_SSL_PARAMETER_EXTENSION;
+
private Map<String, ConfigSource> sourceMap =
Collections.synchronizedMap(new HashMap<>());
@@ -867,6 +872,7 @@ public class DistributionConfigImpl extends AbstractDistributionConfig implement
this.sslProperties = other.getSSLProperties();
this.sslDefaultAlias = other.getSSLDefaultAlias();
this.sslWebServiceRequireAuthentication = other.getSSLWebRequireAuthentication();
+ this.sslParameterExtension = other.getSSLParameterExtension();
validateSerializableObjects = other.getValidateSerializableObjects();
serializableObjectFilter = other.getSerializableObjectFilter();
@@ -3112,6 +3118,16 @@ public class DistributionConfigImpl extends AbstractDistributionConfig implement
}
@Override
+ public String getSSLParameterExtension() {
+ return sslParameterExtension;
+ }
+
+ @Override
+ public void setSSLParameterExtension(final String extension) {
+ sslParameterExtension = extension;
+ }
+
+ @Override
public boolean getValidateSerializableObjects() {
return validateSerializableObjects;
}
@@ -3288,6 +3304,7 @@ public class DistributionConfigImpl extends AbstractDistributionConfig implement
.append(sslKeyStorePassword, that.sslKeyStorePassword)
.append(sslTrustStore, that.sslTrustStore)
.append(sslTrustStorePassword, that.sslTrustStorePassword)
+ .append(sslParameterExtension, that.sslParameterExtension)
.append(locatorSSLAlias, that.locatorSSLAlias).append(sslDefaultAlias, that.sslDefaultAlias)
.append(sourceMap, that.sourceMap).append(userCommandPackages, that.userCommandPackages)
.append(offHeapMemorySize, that.offHeapMemorySize).append(shiroInit, that.shiroInit)
@@ -3360,7 +3377,8 @@ public class DistributionConfigImpl extends AbstractDistributionConfig implement
.append(httpServiceSSLAlias).append(securableCommunicationChannels).append(sslProtocols)
.append(sslCiphers).append(sslRequireAuthentication).append(sslKeyStore)
.append(sslKeyStoreType).append(sslKeyStorePassword).append(sslTrustStore)
- .append(sslTrustStorePassword).append(sslWebServiceRequireAuthentication)
+ .append(sslTrustStorePassword).append(sslParameterExtension)
+ .append(sslWebServiceRequireAuthentication)
.append(locatorSSLAlias).append(sslDefaultAlias).append(sourceMap)
.append(userCommandPackages).append(offHeapMemorySize).append(lockMemory).append(shiroInit)
.append(modifiable).append(threadMonitorEnabled).append(threadMonitorInterval)
diff --git a/geode-core/src/main/java/org/apache/geode/internal/admin/SSLConfig.java b/geode-core/src/main/java/org/apache/geode/internal/admin/SSLConfig.java
index 79b0283..b1e3f07 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/admin/SSLConfig.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/admin/SSLConfig.java
@@ -23,10 +23,15 @@ import java.security.KeyStore;
import java.util.Iterator;
import java.util.Properties;
+import org.apache.commons.lang3.StringUtils;
+
import org.apache.geode.annotations.Immutable;
import org.apache.geode.distributed.internal.DistributionConfig;
+import org.apache.geode.distributed.internal.InternalDistributedSystem;
+import org.apache.geode.internal.security.CallbackInstantiator;
import org.apache.geode.internal.security.SecurableCommunicationChannel;
import org.apache.geode.management.internal.SSLUtil;
+import org.apache.geode.net.SSLParameterExtension;
/**
* The SSL configuration settings for a GemFire distributed system.
@@ -60,6 +65,9 @@ public class SSLConfig {
@Immutable
private final Properties properties;
+ @Immutable
+ private final SSLParameterExtension sslParameterExtension;
+
private SSLConfig(boolean endpointIdentification,
boolean useDefaultSSLContext,
boolean enabled,
@@ -74,7 +82,8 @@ public class SSLConfig {
String truststoreType,
String alias,
SecurableCommunicationChannel securableCommunicationChannel,
- Properties properties) {
+ Properties properties,
+ SSLParameterExtension sslParameterExtension) {
this.endpointIdentification = endpointIdentification;
this.useDefaultSSLContext = useDefaultSSLContext;
this.enabled = enabled;
@@ -90,6 +99,7 @@ public class SSLConfig {
this.alias = alias;
this.securableCommunicationChannel = securableCommunicationChannel;
this.properties = properties;
+ this.sslParameterExtension = sslParameterExtension;
}
public String getAlias() {
@@ -160,6 +170,10 @@ public class SSLConfig {
return securableCommunicationChannel;
}
+ public SSLParameterExtension getSSLParameterExtension() {
+ return sslParameterExtension;
+ }
+
@Override
public String toString() {
return "SSLConfig{" + "enabled=" + enabled + ", protocols='" + protocols + '\'' + ", ciphers='"
@@ -168,7 +182,8 @@ public class SSLConfig {
+ '\'' + ", truststore='" + truststore + '\'' + ", truststorePassword='"
+ truststorePassword + '\'' + ", truststoreType='" + truststoreType + '\'' + ", alias='"
+ alias + '\'' + ", securableCommunicationChannel=" + securableCommunicationChannel
- + ", properties=" + properties + '}';
+ + ", properties=" + properties + '\'' + ", sslParameterExtension=" + sslParameterExtension
+ + '}';
}
/**
@@ -217,6 +232,7 @@ public class SSLConfig {
private String alias = null;
private SecurableCommunicationChannel securableCommunicationChannel = null;
private Properties properties = new Properties();
+ private SSLParameterExtension sslParameterExtension = null;
public Builder() {}
@@ -224,7 +240,7 @@ public class SSLConfig {
return new SSLConfig(endpointIdentification, useDefaultSSLContext, enabled,
protocols, ciphers, requireAuth, keystore, keystoreType, keystorePassword,
truststore, truststorePassword, truststoreType, alias, securableCommunicationChannel,
- properties);
+ properties, sslParameterExtension);
}
public Builder setAlias(final String alias) {
@@ -307,6 +323,26 @@ public class SSLConfig {
return this;
}
+ public Builder setSSLParameterExtension(
+ final String sslParameterExtensionConfig) {
+ if (StringUtils.isBlank(sslParameterExtensionConfig)) {
+ this.sslParameterExtension = null;
+ return this;
+ }
+ SSLParameterExtension sslParameterExtension =
+ CallbackInstantiator.getObjectOfTypeFromClassName(sslParameterExtensionConfig,
+ SSLParameterExtension.class);
+ InternalDistributedSystem ids = InternalDistributedSystem.getAnyInstance();
+
+ if (ids == null) {
+ this.sslParameterExtension = null;
+ return this;
+ }
+ sslParameterExtension.init(ids.getConfig());
+ this.sslParameterExtension = sslParameterExtension;
+ return this;
+ }
+
public String getKeystore() {
return keystore;
}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/net/SSLConfigurationFactory.java b/geode-core/src/main/java/org/apache/geode/internal/net/SSLConfigurationFactory.java
index b6c12c0..259d578 100644
--- a/geode-core/src/main/java/org/apache/geode/internal/net/SSLConfigurationFactory.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/net/SSLConfigurationFactory.java
@@ -58,6 +58,7 @@ public class SSLConfigurationFactory {
configureLegacyClusterSSL(distributionConfig, sslConfigBuilder);
}
sslConfigBuilder.setSecurableCommunicationChannel(sslEnabledComponent);
+
switch (sslEnabledComponent) {
case ALL: {
break;
@@ -140,6 +141,7 @@ public class SSLConfigurationFactory {
sslConfigBuilder.setRequireAuth(distributionConfig.getSSLRequireAuthentication());
sslConfigBuilder.setAlias(distributionConfig.getSSLDefaultAlias());
sslConfigBuilder.setUseDefaultSSLContext(distributionConfig.getSSLUseDefaultContext());
+ sslConfigBuilder.setSSLParameterExtension(distributionConfig.getSSLParameterExtension());
return sslConfigBuilder;
}
diff --git a/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java b/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java
index 807315c..439de6a 100755
--- a/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java
+++ b/geode-core/src/main/java/org/apache/geode/internal/net/SocketCreator.java
@@ -84,8 +84,10 @@ import org.apache.geode.internal.util.ArgumentRedactor;
import org.apache.geode.internal.util.PasswordUtil;
import org.apache.geode.logging.internal.log4j.api.LogService;
import org.apache.geode.management.internal.SSLUtil;
+import org.apache.geode.net.SSLParameterExtension;
import org.apache.geode.util.internal.GeodeGlossary;
+
/**
* Analyze configuration data (gemfire.properties) and configure sockets accordingly for SSL.
* <p>
@@ -967,6 +969,14 @@ public class SocketCreator {
if (!"any".equalsIgnoreCase(ciphers[0])) {
serverSocket.setEnabledCipherSuites(ciphers);
}
+
+ SSLParameterExtension sslParameterExtension = this.sslConfig.getSSLParameterExtension();
+ if (sslParameterExtension != null) {
+ SSLParameters modifiedParams =
+ sslParameterExtension.modifySSLServerSocketParameters(serverSocket.getSSLParameters());
+ serverSocket.setSSLParameters(modifiedParams);
+ }
+
}
/**
@@ -982,6 +992,12 @@ public class SocketCreator {
SSLParameters modifiedParams =
checkAndEnableHostnameValidation(sslSocket.getSSLParameters());
+
+ SSLParameterExtension sslParameterExtension = this.sslConfig.getSSLParameterExtension();
+ if (sslParameterExtension != null) {
+ modifiedParams =
+ sslParameterExtension.modifySSLClientSocketParameters(modifiedParams);
+ }
sslSocket.setSSLParameters(modifiedParams);
String[] protocols = this.sslConfig.getProtocolsAsStringArray();
diff --git a/geode-core/src/main/java/org/apache/geode/net/SSLParameterExtension.java b/geode-core/src/main/java/org/apache/geode/net/SSLParameterExtension.java
new file mode 100644
index 0000000..0ed4465
--- /dev/null
+++ b/geode-core/src/main/java/org/apache/geode/net/SSLParameterExtension.java
@@ -0,0 +1,44 @@
+/*
+ * 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.net;
+
+import javax.net.ssl.SSLParameters;
+
+import org.apache.geode.distributed.internal.DistributionConfig;
+
+/**
+ * User implementation of a SSLParameter extension logic.
+ *
+ * @since Geode 1.12
+ */
+
+public interface SSLParameterExtension {
+ /**
+ * Initialize the SSLParameterExtension.
+ *
+ * @param config the DistributionConfig
+ */
+ default void init(DistributionConfig config) {}
+
+ default SSLParameters modifySSLClientSocketParameters(SSLParameters parameters) {
+ return parameters;
+ }
+
+ default SSLParameters modifySSLServerSocketParameters(SSLParameters parameters) {
+ return parameters;
+ }
+
+}
diff --git a/geode-core/src/test/java/org/apache/geode/distributed/internal/DistributionConfigJUnitTest.java b/geode-core/src/test/java/org/apache/geode/distributed/internal/DistributionConfigJUnitTest.java
index fd53247..64d0022 100644
--- a/geode-core/src/test/java/org/apache/geode/distributed/internal/DistributionConfigJUnitTest.java
+++ b/geode-core/src/test/java/org/apache/geode/distributed/internal/DistributionConfigJUnitTest.java
@@ -103,7 +103,7 @@ public class DistributionConfigJUnitTest {
@Test
public void testGetAttributeNames() {
String[] attNames = AbstractDistributionConfig._getAttNames();
- assertThat(attNames.length).isEqualTo(167);
+ assertThat(attNames.length).isEqualTo(168);
List boolList = new ArrayList();
List intList = new ArrayList();
@@ -139,7 +139,7 @@ public class DistributionConfigJUnitTest {
// are.
assertEquals(35, boolList.size());
assertEquals(35, intList.size());
- assertEquals(87, stringList.size());
+ assertEquals(88, stringList.size());
assertEquals(5, fileList.size());
assertEquals(5, otherList.size());
}
diff --git a/geode-docs/reference/topics/gemfire_properties.html.md.erb b/geode-docs/reference/topics/gemfire_properties.html.md.erb
index afbfdea..8a23f6b 100644
--- a/geode-docs/reference/topics/gemfire_properties.html.md.erb
+++ b/geode-docs/reference/topics/gemfire_properties.html.md.erb
@@ -679,6 +679,13 @@ When enabled, also sets ssl-endpoint-identification-enabled to true.</td>
</tr>
<tr>
+<td>ssl-parameter-extension</td>
+<td>Specifies the implementation of the <code>SSLParameterExtension</code> interface that implements the SSL parameter extensions.</td>
+<td>S, L</td>
+<td><em>not set</em></td>
+</tr>
+
+<tr>
<td>ssl-protocols</td>
<td>Comma-separated list of SSL protocols or "any"</td>
<td>S, L</td>