cassandra-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From jasobr...@apache.org
Subject cassandra git commit: Correct and clarify SSLFactory.getSslContext method and call sites
Date Thu, 22 Mar 2018 13:41:24 GMT
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 <dinesh.joshi@apple.com>
Authored: Sat Mar 17 17:17:42 2018 -0700
Committer: Jason Brown <jasedbrown@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


Mime
View raw message