You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@cassandra.apache.org by ja...@apache.org on 2018/03/22 13:41:24 UTC
cassandra git commit: Correct and clarify SSLFactory.getSslContext
method and call sites
Repository: cassandra
Updated Branches:
refs/heads/trunk f109f200a -> 11496039f
Correct and clarify SSLFactory.getSslContext method and call sites
patch by Dinesh Joshi; reviewed by jasobrown for CASSANDRA-14314
Project: http://git-wip-us.apache.org/repos/asf/cassandra/repo
Commit: http://git-wip-us.apache.org/repos/asf/cassandra/commit/11496039
Tree: http://git-wip-us.apache.org/repos/asf/cassandra/tree/11496039
Diff: http://git-wip-us.apache.org/repos/asf/cassandra/diff/11496039
Branch: refs/heads/trunk
Commit: 11496039fb18bb45407246602e31740c56d28157
Parents: f109f20
Author: Dinesh A. Joshi <di...@apple.com>
Authored: Sat Mar 17 17:17:42 2018 -0700
Committer: Jason Brown <ja...@gmail.com>
Committed: Thu Mar 22 06:38:56 2018 -0700
----------------------------------------------------------------------
CHANGES.txt | 1 +
.../cassandra/config/DatabaseDescriptor.java | 6 +-
.../cassandra/config/EncryptionOptions.java | 35 +++++
.../apache/cassandra/net/MessagingService.java | 6 +-
.../cassandra/net/async/NettyFactory.java | 6 +-
.../cassandra/net/async/OptionalSslHandler.java | 2 +-
.../apache/cassandra/security/SSLFactory.java | 154 +++++++++++--------
.../service/NativeTransportService.java | 3 +-
.../streaming/DefaultConnectionFactory.java | 2 +-
.../org/apache/cassandra/transport/Server.java | 7 +-
.../cassandra/transport/SimpleClient.java | 5 +-
.../cassandra/net/MessagingServiceTest.java | 8 +-
.../async/OutboundMessagingConnectionTest.java | 7 +-
.../cassandra/security/SSLFactoryTest.java | 46 +++++-
.../service/NativeTransportServiceTest.java | 13 +-
15 files changed, 194 insertions(+), 107 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/CHANGES.txt
----------------------------------------------------------------------
diff --git a/CHANGES.txt b/CHANGES.txt
index c092a9f..f86a380 100644
--- a/CHANGES.txt
+++ b/CHANGES.txt
@@ -1,4 +1,5 @@
4.0
+ * Correct and clarify SSLFactory.getSslContext method and call sites (CASSANDRA-14314)
* Use zero as default score in DynamicEndpointSnitch (CASSANDRA-14252)
* Handle static and partition deletion properly on ThrottledUnfilteredIterator (CASSANDRA-14315)
* NodeTool clientstats should show SSL Cipher (CASSANDRA-14322)
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
index 2e772c5..bf00d40 100644
--- a/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
+++ b/src/java/org/apache/cassandra/config/DatabaseDescriptor.java
@@ -2005,17 +2005,17 @@ public class DatabaseDescriptor
conf.dynamic_snitch_badness_threshold = dynamicBadnessThreshold;
}
- public static EncryptionOptions.ServerEncryptionOptions getServerEncryptionOptions()
+ public static EncryptionOptions.ServerEncryptionOptions getInternodeMessagingEncyptionOptions()
{
return conf.server_encryption_options;
}
- public static void setServerEncryptionOptions(EncryptionOptions.ServerEncryptionOptions encryptionOptions)
+ public static void setInternodeMessagingEncyptionOptions(EncryptionOptions.ServerEncryptionOptions encryptionOptions)
{
conf.server_encryption_options = encryptionOptions;
}
- public static EncryptionOptions getClientEncryptionOptions()
+ public static EncryptionOptions getNativeProtocolEncryptionOptions()
{
return conf.client_encryption_options;
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/src/java/org/apache/cassandra/config/EncryptionOptions.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/config/EncryptionOptions.java b/src/java/org/apache/cassandra/config/EncryptionOptions.java
index 5260dff..45579fb 100644
--- a/src/java/org/apache/cassandra/config/EncryptionOptions.java
+++ b/src/java/org/apache/cassandra/config/EncryptionOptions.java
@@ -17,6 +17,9 @@
*/
package org.apache.cassandra.config;
+import java.util.Arrays;
+import java.util.Objects;
+
public class EncryptionOptions
{
public String keystore = "conf/.keystore";
@@ -54,6 +57,38 @@ public class EncryptionOptions
optional = options.optional;
}
+ @Override
+ public boolean equals(Object o)
+ {
+ if (o == this)
+ return true;
+ if (o == null || getClass() != o.getClass())
+ return false;
+
+ EncryptionOptions opt = (EncryptionOptions)o;
+ return Objects.equals(keystore, opt.keystore) &&
+ Objects.equals(truststore, opt.truststore) &&
+ Objects.equals(algorithm, opt.algorithm) &&
+ Objects.equals(protocol, opt.protocol) &&
+ Arrays.equals(cipher_suites, opt.cipher_suites) &&
+ require_client_auth == opt.require_client_auth &&
+ require_endpoint_verification == opt.require_endpoint_verification;
+ }
+
+ @Override
+ public int hashCode()
+ {
+ int result = 0;
+ result += 31 * (keystore == null ? 0 : keystore.hashCode());
+ result += 31 * (truststore == null ? 0 : truststore.hashCode());
+ result += 31 * (algorithm == null ? 0 : algorithm.hashCode());
+ result += 31 * (protocol == null ? 0 : protocol.hashCode());
+ result += 31 * Arrays.hashCode(cipher_suites);
+ result += 31 * Boolean.hashCode(require_client_auth);
+ result += 31 * Boolean.hashCode(require_endpoint_verification);
+ return result;
+ }
+
public static class ServerEncryptionOptions extends EncryptionOptions
{
public enum InternodeEncryption
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/src/java/org/apache/cassandra/net/MessagingService.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/net/MessagingService.java b/src/java/org/apache/cassandra/net/MessagingService.java
index 573cf7d..c6ef986 100644
--- a/src/java/org/apache/cassandra/net/MessagingService.java
+++ b/src/java/org/apache/cassandra/net/MessagingService.java
@@ -737,7 +737,7 @@ public final class MessagingService implements MessagingServiceMBean
public void listen()
{
- listen(DatabaseDescriptor.getServerEncryptionOptions());
+ listen(DatabaseDescriptor.getInternodeMessagingEncyptionOptions());
}
public void listen(ServerEncryptionOptions serverEncryptionOptions)
@@ -1606,7 +1606,7 @@ public final class MessagingService implements MessagingServiceMBean
InetAddressAndPort preferredRemote = SystemKeyspace.getPreferredIP(to);
InetAddressAndPort local = FBUtilities.getLocalAddressAndPort();
- ServerEncryptionOptions encryptionOptions = secure ? DatabaseDescriptor.getServerEncryptionOptions() : null;
+ ServerEncryptionOptions encryptionOptions = secure ? DatabaseDescriptor.getInternodeMessagingEncyptionOptions() : null;
IInternodeAuthenticator authenticator = DatabaseDescriptor.getInternodeAuthenticator();
pool = new OutboundMessagingPool(preferredRemote, local, encryptionOptions, backPressure.newState(to), authenticator);
@@ -1656,7 +1656,7 @@ public final class MessagingService implements MessagingServiceMBean
public static boolean isEncryptedConnection(InetAddressAndPort address)
{
IEndpointSnitch snitch = DatabaseDescriptor.getEndpointSnitch();
- switch (DatabaseDescriptor.getServerEncryptionOptions().internode_encryption)
+ switch (DatabaseDescriptor.getInternodeMessagingEncyptionOptions().internode_encryption)
{
case none:
return false; // if nothing needs to be encrypted then return immediately.
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/src/java/org/apache/cassandra/net/async/NettyFactory.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/net/async/NettyFactory.java b/src/java/org/apache/cassandra/net/async/NettyFactory.java
index d891043..86ed4e7 100644
--- a/src/java/org/apache/cassandra/net/async/NettyFactory.java
+++ b/src/java/org/apache/cassandra/net/async/NettyFactory.java
@@ -122,7 +122,7 @@ public final class NettyFactory
NettyFactory(boolean useEpoll)
{
this.useEpoll = useEpoll;
- acceptGroup = getEventLoopGroup(useEpoll, determineAcceptGroupSize(DatabaseDescriptor.getServerEncryptionOptions()),
+ acceptGroup = getEventLoopGroup(useEpoll, determineAcceptGroupSize(DatabaseDescriptor.getInternodeMessagingEncyptionOptions()),
"MessagingService-NettyAcceptor-Thread", false);
inboundGroup = getEventLoopGroup(useEpoll, FBUtilities.getAvailableProcessors(), "MessagingService-NettyInbound-Thread", false);
outboundGroup = getEventLoopGroup(useEpoll, FBUtilities.getAvailableProcessors(), "MessagingService-NettyOutbound-Thread", true);
@@ -287,7 +287,7 @@ public final class NettyFactory
}
else
{
- SslContext sslContext = SSLFactory.getSslContext(encryptionOptions, true, true);
+ SslContext sslContext = SSLFactory.getSslContext(encryptionOptions, true, SSLFactory.ConnectionType.INTERNODE_MESSAGING, SSLFactory.SocketType.SERVER);
InetSocketAddress peer = encryptionOptions.require_endpoint_verification ? channel.remoteAddress() : null;
SslHandler sslHandler = newSslHandler(channel, sslContext, peer);
logger.trace("creating inbound netty SslContext: context={}, engine={}", sslContext.getClass().getName(), sslHandler.engine().getClass().getName());
@@ -362,7 +362,7 @@ public final class NettyFactory
// order of handlers: ssl -> logger -> handshakeHandler
if (params.encryptionOptions != null)
{
- SslContext sslContext = SSLFactory.getSslContext(params.encryptionOptions, true, false);
+ SslContext sslContext = SSLFactory.getSslContext(params.encryptionOptions, true, SSLFactory.ConnectionType.INTERNODE_MESSAGING, SSLFactory.SocketType.CLIENT);
// for some reason channel.remoteAddress() will return null
InetAddressAndPort address = params.connectionId.remote();
InetSocketAddress peer = params.encryptionOptions.require_endpoint_verification ? new InetSocketAddress(address.address, address.port) : null;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/src/java/org/apache/cassandra/net/async/OptionalSslHandler.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/net/async/OptionalSslHandler.java b/src/java/org/apache/cassandra/net/async/OptionalSslHandler.java
index b60ae13..d57518c 100644
--- a/src/java/org/apache/cassandra/net/async/OptionalSslHandler.java
+++ b/src/java/org/apache/cassandra/net/async/OptionalSslHandler.java
@@ -51,7 +51,7 @@ public class OptionalSslHandler extends ByteToMessageDecoder
if (SslHandler.isEncrypted(in))
{
// Connection uses SSL/TLS, replace the detection handler with a SslHandler and so use encryption.
- SslContext sslContext = SSLFactory.getSslContext(encryptionOptions, true, true);
+ SslContext sslContext = SSLFactory.getSslContext(encryptionOptions, true, SSLFactory.ConnectionType.INTERNODE_MESSAGING, SSLFactory.SocketType.SERVER);
Channel channel = ctx.channel();
InetSocketAddress peer = encryptionOptions.require_endpoint_verification ? (InetSocketAddress) channel.remoteAddress() : null;
SslHandler sslHandler = NettyFactory.newSslHandler(channel, sslContext, peer);
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/src/java/org/apache/cassandra/security/SSLFactory.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/security/SSLFactory.java b/src/java/org/apache/cassandra/security/SSLFactory.java
index 395ea42..d64dded 100644
--- a/src/java/org/apache/cassandra/security/SSLFactory.java
+++ b/src/java/org/apache/cassandra/security/SSLFactory.java
@@ -30,9 +30,9 @@ import java.util.Arrays;
import java.util.Date;
import java.util.Enumeration;
import java.util.List;
-import java.util.concurrent.CopyOnWriteArrayList;
+import java.util.Objects;
+import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.TimeUnit;
-import java.util.concurrent.atomic.AtomicReference;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocket;
@@ -54,33 +54,47 @@ import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.SupportedCipherSuiteFilter;
+import io.netty.util.ReferenceCountUtil;
import org.apache.cassandra.concurrent.ScheduledExecutors;
import org.apache.cassandra.config.EncryptionOptions;
/**
* A Factory for providing and setting up client {@link SSLSocket}s. Also provides
* methods for creating both JSSE {@link SSLContext} instances as well as netty {@link SslContext} instances.
- *
+ * <p>
* Netty {@link SslContext} instances are expensive to create (as well as to destroy) and consume a lof of resources
* (especially direct memory), but instances can be reused across connections (assuming the SSL params are the same).
- * Hence we cache created instances in {@link #clientSslContext} and {@link #serverSslContext}.
+ * Hence we cache created instances in {@link #cachedSslContexts}.
*/
public final class SSLFactory
{
private static final Logger logger = LoggerFactory.getLogger(SSLFactory.class);
- @VisibleForTesting
- static volatile boolean checkedExpiry = false;
+ /**
+ * Indicator if a connection is shared with a client application ({@link ConnectionType#NATIVE_TRANSPORT})
+ * or another cassandra node ({@link ConnectionType#INTERNODE_MESSAGING}).
+ */
+ public enum ConnectionType
+ {
+ NATIVE_TRANSPORT, INTERNODE_MESSAGING
+ }
/**
- * A cached reference of the {@link SslContext} for client-facing connections.
+ * Indicates if the process holds the inbound/listening end of the socket ({@link SocketType#SERVER})), or the
+ * outbound side ({@link SocketType#CLIENT}).
*/
- private static final AtomicReference<SslContext> clientSslContext = new AtomicReference<>();
+ public enum SocketType
+ {
+ SERVER, CLIENT
+ }
+
+ @VisibleForTesting
+ static volatile boolean checkedExpiry = false;
/**
- * A cached reference of the {@link SslContext} for peer-to-peer, internode messaging connections.
+ * Cached references of SSL Contexts
*/
- private static final AtomicReference<SslContext> serverSslContext = new AtomicReference<>();
+ private static final ConcurrentHashMap<CacheKey, SslContext> cachedSslContexts = new ConcurrentHashMap<>();
/**
* List of files that trigger hot reloading of SSL certificates
@@ -107,21 +121,13 @@ public final class SSLFactory
*/
private static class HotReloadableFile
{
- enum Type
- {
- SERVER,
- CLIENT
- }
-
private final File file;
private volatile long lastModTime;
- private final Type certType;
- HotReloadableFile(String path, Type type)
+ HotReloadableFile(String path)
{
file = new File(path);
lastModTime = file.lastModified();
- certType = type;
}
boolean shouldReload()
@@ -131,16 +137,6 @@ public final class SSLFactory
lastModTime = curModTime;
return result;
}
-
- public boolean isServer()
- {
- return certType == Type.SERVER;
- }
-
- public boolean isClient()
- {
- return certType == Type.CLIENT;
- }
}
/**
@@ -172,7 +168,7 @@ public final class SSLFactory
try (InputStream tsf = Files.newInputStream(Paths.get(options.truststore)))
{
TrustManagerFactory tmf = TrustManagerFactory.getInstance(
- options.algorithm == null ? TrustManagerFactory.getDefaultAlgorithm() : options.algorithm);
+ options.algorithm == null ? TrustManagerFactory.getDefaultAlgorithm() : options.algorithm);
KeyStore ts = KeyStore.getInstance(options.store_type);
ts.load(tsf, options.truststore_password.toCharArray());
tmf.init(ts);
@@ -189,7 +185,7 @@ public final class SSLFactory
try (InputStream ksf = Files.newInputStream(Paths.get(options.keystore)))
{
KeyManagerFactory kmf = KeyManagerFactory.getInstance(
- options.algorithm == null ? KeyManagerFactory.getDefaultAlgorithm() : options.algorithm);
+ options.algorithm == null ? KeyManagerFactory.getDefaultAlgorithm() : options.algorithm);
KeyStore ks = KeyStore.getInstance(options.store_type);
ks.load(ksf, options.keystore_password.toCharArray());
if (!checkedExpiry)
@@ -233,26 +229,41 @@ public final class SSLFactory
/**
* get a netty {@link SslContext} instance
*/
- public static SslContext getSslContext(EncryptionOptions options, boolean buildTruststore, boolean forServer) throws IOException
+ public static SslContext getSslContext(EncryptionOptions options, boolean buildTruststore, ConnectionType connectionType,
+ SocketType socketType) throws IOException
{
- return getSslContext(options, buildTruststore, forServer, OpenSsl.isAvailable());
+ return getSslContext(options, buildTruststore, connectionType, socketType, OpenSsl.isAvailable());
}
/**
* Get a netty {@link SslContext} instance.
*/
@VisibleForTesting
- static SslContext getSslContext(EncryptionOptions options, boolean buildTruststore, boolean forServer, boolean useOpenSsl) throws IOException
+ static SslContext getSslContext(EncryptionOptions options, boolean buildTruststore, ConnectionType connectionType,
+ SocketType socketType, boolean useOpenSsl) throws IOException
{
-
+ CacheKey key = new CacheKey(options, connectionType, socketType);
SslContext sslContext;
- if (forServer && (sslContext = serverSslContext.get()) != null)
+ sslContext = cachedSslContexts.get(key);
+ if (sslContext != null)
return sslContext;
- if (!forServer && (sslContext = clientSslContext.get()) != null)
+ sslContext = createNettySslContext(options, buildTruststore, connectionType, socketType, useOpenSsl);
+ SslContext previous = cachedSslContexts.putIfAbsent(key, sslContext);
+ if (previous == null)
return sslContext;
+ ReferenceCountUtil.release(sslContext);
+ return previous;
+ }
+
+ /**
+ * Create a Netty {@link SslContext}
+ */
+ static SslContext createNettySslContext(EncryptionOptions options, boolean buildTruststore, ConnectionType connectionType,
+ SocketType socketType, boolean useOpenSsl) throws IOException
+ {
/*
There is a case where the netty/openssl combo might not support using KeyManagerFactory. specifically,
I've seen this with the netty-tcnative dynamic openssl implementation. using the netty-tcnative static-boringssl
@@ -261,12 +272,9 @@ public final class SSLFactory
{@link SslContextBuilder#forServer(File, File, String)}). However, we are not supporting that now to keep
the config/yaml API simple.
*/
- KeyManagerFactory kmf = null;
- if (forServer || options.require_client_auth)
- kmf = buildKeyManagerFactory(options);
-
+ KeyManagerFactory kmf = buildKeyManagerFactory(options);
SslContextBuilder builder;
- if (forServer)
+ if (socketType == SocketType.SERVER)
{
builder = SslContextBuilder.forServer(kmf);
builder.clientAuth(options.require_client_auth ? ClientAuth.REQUIRE : ClientAuth.NONE);
@@ -286,19 +294,14 @@ public final class SSLFactory
if (buildTruststore)
builder.trustManager(buildTrustManagerFactory(options));
- SslContext ctx = builder.build();
- AtomicReference<SslContext> ref = forServer ? serverSslContext : clientSslContext;
- if (ref.compareAndSet(null, ctx))
- return ctx;
-
- return ref.get();
+ return builder.build();
}
/**
* Performs a lightweight check whether the certificate files have been refreshed.
*
* @throws IllegalStateException if {@link #initHotReloading(EncryptionOptions.ServerEncryptionOptions, EncryptionOptions, boolean)}
- * is not called first
+ * is not called first
*/
public static void checkCertFilesForHotReloading()
{
@@ -307,16 +310,10 @@ public final class SSLFactory
logger.trace("Checking whether certificates have been updated");
- if (hotReloadableFiles.stream().anyMatch(f -> f.isServer() && f.shouldReload()))
- {
- logger.info("Server ssl certificates have been updated. Reseting the context for new peer connections.");
- serverSslContext.set(null);
- }
-
- if (hotReloadableFiles.stream().anyMatch(f -> f.isClient() && f.shouldReload()))
+ if (hotReloadableFiles.stream().anyMatch(HotReloadableFile::shouldReload))
{
- logger.info("Client ssl certificates have been updated. Reseting the context for new client connections.");
- clientSslContext.set(null);
+ logger.info("SSL certificates have been updated. Reseting the ssl contexts for new connections.");
+ cachedSslContexts.clear();
}
}
@@ -339,14 +336,14 @@ public final class SSLFactory
if (serverEncryptionOptions.enabled)
{
- fileList.add(new HotReloadableFile(serverEncryptionOptions.keystore, HotReloadableFile.Type.SERVER));
- fileList.add(new HotReloadableFile(serverEncryptionOptions.truststore, HotReloadableFile.Type.SERVER));
+ fileList.add(new HotReloadableFile(serverEncryptionOptions.keystore));
+ fileList.add(new HotReloadableFile(serverEncryptionOptions.truststore));
}
if (clientEncryptionOptions.enabled)
{
- fileList.add(new HotReloadableFile(clientEncryptionOptions.keystore, HotReloadableFile.Type.CLIENT));
- fileList.add(new HotReloadableFile(clientEncryptionOptions.truststore, HotReloadableFile.Type.CLIENT));
+ fileList.add(new HotReloadableFile(clientEncryptionOptions.keystore));
+ fileList.add(new HotReloadableFile(clientEncryptionOptions.truststore));
}
hotReloadableFiles = ImmutableList.copyOf(fileList);
@@ -360,4 +357,37 @@ public final class SSLFactory
isHotReloadingInitialized = true;
}
+
+ static class CacheKey
+ {
+ private final EncryptionOptions encryptionOptions;
+ private final ConnectionType connectionType;
+ private final SocketType socketType;
+
+ public CacheKey(EncryptionOptions encryptionOptions, ConnectionType connectionType, SocketType socketType)
+ {
+ this.encryptionOptions = encryptionOptions;
+ this.connectionType = connectionType;
+ this.socketType = socketType;
+ }
+
+ public boolean equals(Object o)
+ {
+ if (this == o) return true;
+ if (o == null || getClass() != o.getClass()) return false;
+ CacheKey cacheKey = (CacheKey) o;
+ return (connectionType == cacheKey.connectionType &&
+ socketType == cacheKey.socketType &&
+ Objects.equals(encryptionOptions, cacheKey.encryptionOptions));
+ }
+
+ public int hashCode()
+ {
+ int result = 0;
+ result += 31 * connectionType.hashCode();
+ result += 31 * socketType.hashCode();
+ result += 31 * encryptionOptions.hashCode();
+ return result;
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/src/java/org/apache/cassandra/service/NativeTransportService.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/service/NativeTransportService.java b/src/java/org/apache/cassandra/service/NativeTransportService.java
index cec9b2b..d70e56e 100644
--- a/src/java/org/apache/cassandra/service/NativeTransportService.java
+++ b/src/java/org/apache/cassandra/service/NativeTransportService.java
@@ -29,7 +29,6 @@ import java.util.Map.Entry;
import java.util.concurrent.TimeUnit;
import com.google.common.annotations.VisibleForTesting;
-import com.google.common.collect.Lists;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -92,7 +91,7 @@ public class NativeTransportService
.withEventLoopGroup(workerGroup)
.withHost(nativeAddr);
- if (!DatabaseDescriptor.getClientEncryptionOptions().enabled)
+ if (!DatabaseDescriptor.getNativeProtocolEncryptionOptions().enabled)
{
servers = Collections.singleton(builder.withSSL(false).withPort(nativePort).build());
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/src/java/org/apache/cassandra/streaming/DefaultConnectionFactory.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/streaming/DefaultConnectionFactory.java b/src/java/org/apache/cassandra/streaming/DefaultConnectionFactory.java
index d9ed8be..609d2a0 100644
--- a/src/java/org/apache/cassandra/streaming/DefaultConnectionFactory.java
+++ b/src/java/org/apache/cassandra/streaming/DefaultConnectionFactory.java
@@ -49,7 +49,7 @@ public class DefaultConnectionFactory implements StreamConnectionFactory
@Override
public Channel createConnection(OutboundConnectionIdentifier connectionId, int protocolVersion) throws IOException
{
- ServerEncryptionOptions encryptionOptions = DatabaseDescriptor.getServerEncryptionOptions();
+ ServerEncryptionOptions encryptionOptions = DatabaseDescriptor.getInternodeMessagingEncyptionOptions();
if (encryptionOptions.internode_encryption == ServerEncryptionOptions.InternodeEncryption.none)
encryptionOptions = null;
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/src/java/org/apache/cassandra/transport/Server.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/Server.java b/src/java/org/apache/cassandra/transport/Server.java
index 0f666d8..7aade66 100644
--- a/src/java/org/apache/cassandra/transport/Server.java
+++ b/src/java/org/apache/cassandra/transport/Server.java
@@ -24,8 +24,6 @@ import java.net.UnknownHostException;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.atomic.AtomicBoolean;
-import javax.net.ssl.SSLContext;
-import javax.net.ssl.SSLEngine;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
@@ -140,7 +138,7 @@ public class Server implements CassandraDaemon.Server
if (this.useSSL)
{
- final EncryptionOptions clientEnc = DatabaseDescriptor.getClientEncryptionOptions();
+ final EncryptionOptions clientEnc = DatabaseDescriptor.getNativeProtocolEncryptionOptions();
if (clientEnc.optional)
{
@@ -407,7 +405,8 @@ public class Server implements CassandraDaemon.Server
protected final SslHandler createSslHandler(ByteBufAllocator allocator) throws IOException
{
- SslContext sslContext = SSLFactory.getSslContext(encryptionOptions, encryptionOptions.require_client_auth, true);
+ SslContext sslContext = SSLFactory.getSslContext(encryptionOptions, encryptionOptions.require_client_auth,
+ SSLFactory.ConnectionType.NATIVE_TRANSPORT, SSLFactory.SocketType.SERVER);
return sslContext.newHandler(allocator);
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/src/java/org/apache/cassandra/transport/SimpleClient.java
----------------------------------------------------------------------
diff --git a/src/java/org/apache/cassandra/transport/SimpleClient.java b/src/java/org/apache/cassandra/transport/SimpleClient.java
index 07463e2..db7de8d 100644
--- a/src/java/org/apache/cassandra/transport/SimpleClient.java
+++ b/src/java/org/apache/cassandra/transport/SimpleClient.java
@@ -52,12 +52,10 @@ import org.apache.cassandra.transport.messages.PrepareMessage;
import org.apache.cassandra.transport.messages.QueryMessage;
import org.apache.cassandra.transport.messages.ResultMessage;
import org.apache.cassandra.transport.messages.StartupMessage;
-import org.apache.cassandra.utils.MD5Digest;
import io.netty.channel.Channel;
import io.netty.channel.ChannelFuture;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelPipeline;
-import io.netty.handler.ssl.SslHandler;
public class SimpleClient implements Closeable
{
@@ -283,7 +281,8 @@ public class SimpleClient implements Closeable
protected void initChannel(Channel channel) throws Exception
{
super.initChannel(channel);
- SslContext sslContext = SSLFactory.getSslContext(encryptionOptions, encryptionOptions.require_client_auth, true);
+ SslContext sslContext = SSLFactory.getSslContext(encryptionOptions, encryptionOptions.require_client_auth,
+ SSLFactory.ConnectionType.NATIVE_TRANSPORT, SSLFactory.SocketType.CLIENT);
channel.pipeline().addFirst("ssl", sslContext.newHandler(channel.alloc()));
}
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/test/unit/org/apache/cassandra/net/MessagingServiceTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/net/MessagingServiceTest.java b/test/unit/org/apache/cassandra/net/MessagingServiceTest.java
index 4ce3422..c3ebe32 100644
--- a/test/unit/org/apache/cassandra/net/MessagingServiceTest.java
+++ b/test/unit/org/apache/cassandra/net/MessagingServiceTest.java
@@ -22,7 +22,6 @@ package org.apache.cassandra.net;
import java.io.IOException;
import java.net.InetAddress;
-import java.net.InetSocketAddress;
import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collections;
@@ -48,9 +47,6 @@ import org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions;
import org.apache.cassandra.db.SystemKeyspace;
import org.apache.cassandra.db.monitoring.ApproximateTime;
import org.apache.cassandra.exceptions.ConfigurationException;
-import org.apache.cassandra.io.util.DataInputPlus.DataInputStreamPlus;
-import org.apache.cassandra.io.util.DataOutputStreamPlus;
-import org.apache.cassandra.io.util.WrappedDataOutputStreamPlus;
import org.apache.cassandra.locator.InetAddressAndPort;
import org.apache.cassandra.net.MessagingService.ServerChannel;
import org.apache.cassandra.net.async.NettyFactory;
@@ -96,7 +92,7 @@ public class MessagingServiceTest
DatabaseDescriptor.setBackPressureStrategy(new MockBackPressureStrategy(Collections.emptyMap()));
DatabaseDescriptor.setBroadcastAddress(InetAddress.getByName("127.0.0.1"));
originalAuthenticator = DatabaseDescriptor.getInternodeAuthenticator();
- originalServerEncryptionOptions = DatabaseDescriptor.getServerEncryptionOptions();
+ originalServerEncryptionOptions = DatabaseDescriptor.getInternodeMessagingEncyptionOptions();
originalListenAddress = InetAddressAndPort.getByAddressOverrideDefaults(DatabaseDescriptor.getListenAddress(), DatabaseDescriptor.getStoragePort());
}
@@ -115,7 +111,7 @@ public class MessagingServiceTest
public void tearDown()
{
DatabaseDescriptor.setInternodeAuthenticator(originalAuthenticator);
- DatabaseDescriptor.setServerEncryptionOptions(originalServerEncryptionOptions);
+ DatabaseDescriptor.setInternodeMessagingEncyptionOptions(originalServerEncryptionOptions);
DatabaseDescriptor.setShouldListenOnBroadcastAddress(false);
DatabaseDescriptor.setListenAddress(originalListenAddress.address);
FBUtilities.reset();
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/test/unit/org/apache/cassandra/net/async/OutboundMessagingConnectionTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/net/async/OutboundMessagingConnectionTest.java b/test/unit/org/apache/cassandra/net/async/OutboundMessagingConnectionTest.java
index bf6e066..6a8dc83 100644
--- a/test/unit/org/apache/cassandra/net/async/OutboundMessagingConnectionTest.java
+++ b/test/unit/org/apache/cassandra/net/async/OutboundMessagingConnectionTest.java
@@ -20,7 +20,6 @@ package org.apache.cassandra.net.async;
import java.io.IOException;
import java.net.InetAddress;
-import java.net.InetSocketAddress;
import java.util.HashMap;
import java.util.Map;
import java.util.Optional;
@@ -88,14 +87,14 @@ public class OutboundMessagingConnectionTest
omc.setChannelWriter(ChannelWriter.create(channel, omc::handleMessageResult, Optional.empty()));
snitch = DatabaseDescriptor.getEndpointSnitch();
- encryptionOptions = DatabaseDescriptor.getServerEncryptionOptions();
+ encryptionOptions = DatabaseDescriptor.getInternodeMessagingEncyptionOptions();
}
@After
public void tearDown()
{
DatabaseDescriptor.setEndpointSnitch(snitch);
- DatabaseDescriptor.setServerEncryptionOptions(encryptionOptions);
+ DatabaseDescriptor.setInternodeMessagingEncyptionOptions(encryptionOptions);
channel.finishAndReleaseAll();
}
@@ -506,7 +505,7 @@ public class OutboundMessagingConnectionTest
ServerEncryptionOptions encryptionOptions = new ServerEncryptionOptions();
encryptionOptions.enabled = true;
encryptionOptions.internode_encryption = ServerEncryptionOptions.InternodeEncryption.all;
- DatabaseDescriptor.setServerEncryptionOptions(encryptionOptions);
+ DatabaseDescriptor.setInternodeMessagingEncyptionOptions(encryptionOptions);
omc = new OutboundMessagingConnection(connectionId, encryptionOptions, Optional.empty(), new AllowAllInternodeAuthenticator());
int peerVersion = MessagingService.VERSION_30;
MessagingService.instance().setVersion(connectionId.remote(), MessagingService.VERSION_30);
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/test/unit/org/apache/cassandra/security/SSLFactoryTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/security/SSLFactoryTest.java b/test/unit/org/apache/cassandra/security/SSLFactoryTest.java
index 5153a11..19e88de 100644
--- a/test/unit/org/apache/cassandra/security/SSLFactoryTest.java
+++ b/test/unit/org/apache/cassandra/security/SSLFactoryTest.java
@@ -30,7 +30,9 @@ import org.junit.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
+import io.netty.handler.ssl.JdkSslContext;
import io.netty.handler.ssl.OpenSsl;
+import io.netty.handler.ssl.OpenSslContext;
import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.util.SelfSignedCertificate;
import org.apache.cassandra.config.DatabaseDescriptor;
@@ -93,16 +95,20 @@ public class SSLFactoryTest
}
EncryptionOptions options = addKeystoreOptions(encryptionOptions);
- SslContext sslContext = SSLFactory.getSslContext(options, true, true, true);
+ SslContext sslContext = SSLFactory.getSslContext(options, true, SSLFactory.ConnectionType.NATIVE_TRANSPORT,
+ SSLFactory.SocketType.CLIENT, true);
Assert.assertNotNull(sslContext);
+ Assert.assertTrue(sslContext instanceof OpenSslContext);
}
@Test
public void getSslContext_JdkSsl() throws IOException
{
EncryptionOptions options = addKeystoreOptions(encryptionOptions);
- SslContext sslContext = SSLFactory.getSslContext(options, true, true, false);
+ SslContext sslContext = SSLFactory.getSslContext(options, true, SSLFactory.ConnectionType.NATIVE_TRANSPORT,
+ SSLFactory.SocketType.CLIENT, false);
Assert.assertNotNull(sslContext);
+ Assert.assertTrue(sslContext instanceof JdkSslContext);
Assert.assertEquals(Arrays.asList(encryptionOptions.cipher_suites), sslContext.cipherSuites());
}
@@ -113,14 +119,14 @@ public class SSLFactoryTest
return options;
}
- @Test (expected = IOException.class)
+ @Test(expected = IOException.class)
public void buildTrustManagerFactory_NoFile() throws IOException
{
encryptionOptions.truststore = "/this/is/probably/not/a/file/on/your/test/machine";
SSLFactory.buildTrustManagerFactory(encryptionOptions);
}
- @Test (expected = IOException.class)
+ @Test(expected = IOException.class)
public void buildTrustManagerFactory_BadPassword() throws IOException
{
encryptionOptions.truststore_password = "HomeOfBadPasswords";
@@ -134,7 +140,7 @@ public class SSLFactoryTest
Assert.assertNotNull(trustManagerFactory);
}
- @Test (expected = IOException.class)
+ @Test(expected = IOException.class)
public void buildKeyManagerFactory_NoFile() throws IOException
{
EncryptionOptions options = addKeystoreOptions(encryptionOptions);
@@ -142,7 +148,7 @@ public class SSLFactoryTest
SSLFactory.buildKeyManagerFactory(options);
}
- @Test (expected = IOException.class)
+ @Test(expected = IOException.class)
public void buildKeyManagerFactory_BadPassword() throws IOException
{
EncryptionOptions options = addKeystoreOptions(encryptionOptions);
@@ -169,7 +175,8 @@ public class SSLFactoryTest
SSLFactory.initHotReloading((ServerEncryptionOptions) options, options, true);
- SslContext oldCtx = SSLFactory.getSslContext(options, true, true, OpenSsl.isAvailable());
+ SslContext oldCtx = SSLFactory.getSslContext(options, true, SSLFactory.ConnectionType.NATIVE_TRANSPORT,
+ SSLFactory.SocketType.CLIENT, OpenSsl.isAvailable());
File keystoreFile = new File(options.keystore);
SSLFactory.checkCertFilesForHotReloading();
@@ -177,7 +184,8 @@ public class SSLFactoryTest
keystoreFile.setLastModified(System.currentTimeMillis());
SSLFactory.checkCertFilesForHotReloading();
- SslContext newCtx = SSLFactory.getSslContext(options, true, true, OpenSsl.isAvailable());
+ SslContext newCtx = SSLFactory.getSslContext(options, true, SSLFactory.ConnectionType.NATIVE_TRANSPORT,
+ SSLFactory.SocketType.CLIENT, OpenSsl.isAvailable());
Assert.assertNotSame(oldCtx, newCtx);
}
@@ -190,4 +198,26 @@ public class SSLFactoryTest
DatabaseDescriptor.loadConfig();
}
}
+
+ @Test
+ public void getSslContext_ParamChanges() throws IOException
+ {
+ EncryptionOptions options = addKeystoreOptions(encryptionOptions);
+ options.enabled = true;
+ options.cipher_suites = new String[]{ "TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256" };
+
+ SslContext ctx1 = SSLFactory.getSslContext(options, true, SSLFactory.ConnectionType.NATIVE_TRANSPORT,
+ SSLFactory.SocketType.CLIENT, OpenSsl.isAvailable());
+
+ Assert.assertTrue(ctx1.isClient());
+ Assert.assertArrayEquals(ctx1.cipherSuites().toArray(), options.cipher_suites);
+
+ options.cipher_suites = new String[]{ "TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256" };
+
+ SslContext ctx2 = SSLFactory.getSslContext(options, true, SSLFactory.ConnectionType.NATIVE_TRANSPORT,
+ SSLFactory.SocketType.CLIENT, OpenSsl.isAvailable());
+
+ Assert.assertTrue(ctx2.isClient());
+ Assert.assertArrayEquals(ctx2.cipherSuites().toArray(), options.cipher_suites);
+ }
}
http://git-wip-us.apache.org/repos/asf/cassandra/blob/11496039/test/unit/org/apache/cassandra/service/NativeTransportServiceTest.java
----------------------------------------------------------------------
diff --git a/test/unit/org/apache/cassandra/service/NativeTransportServiceTest.java b/test/unit/org/apache/cassandra/service/NativeTransportServiceTest.java
index 334a9af..c918fd6 100644
--- a/test/unit/org/apache/cassandra/service/NativeTransportServiceTest.java
+++ b/test/unit/org/apache/cassandra/service/NativeTransportServiceTest.java
@@ -20,7 +20,6 @@ package org.apache.cassandra.service;
import java.util.Arrays;
import java.util.function.BooleanSupplier;
import java.util.function.Consumer;
-import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
@@ -48,7 +47,7 @@ public class NativeTransportServiceTest
@After
public void resetConfig()
{
- DatabaseDescriptor.getClientEncryptionOptions().enabled = false;
+ DatabaseDescriptor.getNativeProtocolEncryptionOptions().enabled = false;
DatabaseDescriptor.setNativeTransportPortSSL(null);
}
@@ -129,8 +128,8 @@ public class NativeTransportServiceTest
public void testSSLOnly()
{
// default ssl settings: client encryption enabled and default native transport port used for ssl only
- DatabaseDescriptor.getClientEncryptionOptions().enabled = true;
- DatabaseDescriptor.getClientEncryptionOptions().optional = false;
+ DatabaseDescriptor.getNativeProtocolEncryptionOptions().enabled = true;
+ DatabaseDescriptor.getNativeProtocolEncryptionOptions().optional = false;
withService((NativeTransportService service) ->
{
@@ -146,8 +145,8 @@ public class NativeTransportServiceTest
public void testSSLOptional()
{
// default ssl settings: client encryption enabled and default native transport port used for optional ssl
- DatabaseDescriptor.getClientEncryptionOptions().enabled = true;
- DatabaseDescriptor.getClientEncryptionOptions().optional = true;
+ DatabaseDescriptor.getNativeProtocolEncryptionOptions().enabled = true;
+ DatabaseDescriptor.getNativeProtocolEncryptionOptions().optional = true;
withService((NativeTransportService service) ->
{
@@ -163,7 +162,7 @@ public class NativeTransportServiceTest
public void testSSLWithNonSSL()
{
// ssl+non-ssl settings: client encryption enabled and additional ssl port specified
- DatabaseDescriptor.getClientEncryptionOptions().enabled = true;
+ DatabaseDescriptor.getNativeProtocolEncryptionOptions().enabled = true;
DatabaseDescriptor.setNativeTransportPortSSL(8432);
withService((NativeTransportService service) ->
---------------------------------------------------------------------
To unsubscribe, e-mail: commits-unsubscribe@cassandra.apache.org
For additional commands, e-mail: commits-help@cassandra.apache.org