blob: afa0d66bac3b745f69c15780d2ebc2107a8467f5 [file] [log] [blame]
/*
* 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.cassandra.config;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Set;
import javax.annotation.Nullable;
import com.google.common.annotations.VisibleForTesting;
import com.google.common.collect.ImmutableList;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.apache.cassandra.locator.IEndpointSnitch;
import org.apache.cassandra.locator.InetAddressAndPort;
import org.apache.cassandra.security.DisableSslContextFactory;
import org.apache.cassandra.security.ISslContextFactory;
import org.apache.cassandra.utils.FBUtilities;
/**
* This holds various options used for enabling SSL/TLS encryption.
* Examples of such options are: supported cipher-suites, ssl protocol with version, accepted protocols, end-point
* verification, require client-auth/cert etc.
*/
public class EncryptionOptions
{
Logger logger = LoggerFactory.getLogger(EncryptionOptions.class);
public enum TlsEncryptionPolicy
{
UNENCRYPTED("unencrypted"),
OPTIONAL("optionally encrypted"),
ENCRYPTED("encrypted");
private final String description;
TlsEncryptionPolicy(String description)
{
this.description = description;
}
public String description()
{
return description;
}
}
/*
* If the ssl_context_factory is configured, most likely it won't use file based keystores and truststores and
* can choose to completely customize SSL context's creation. Most likely it won't also use keystore_password and
* truststore_passwords configurations as they are in plaintext format.
*/
public final ParameterizedClass ssl_context_factory;
public final String keystore;
@Nullable
public final String keystore_password;
public final String truststore;
@Nullable
public final String truststore_password;
public final List<String> cipher_suites;
protected String protocol;
protected List<String> accepted_protocols;
public final String algorithm;
public final String store_type;
public final boolean require_client_auth;
public final boolean require_endpoint_verification;
// ServerEncryptionOptions does not use the enabled flag at all instead using the existing
// internode_encryption option. So we force this private and expose through isEnabled
// so users of ServerEncryptionOptions can't accidentally use this when they should use isEnabled
// Long term we need to refactor ClientEncryptionOptions and ServerEncyrptionOptions to be separate
// classes so we can choose appropriate configuration for each.
// See CASSANDRA-15262 and CASSANDRA-15146
protected Boolean enabled;
protected Boolean optional;
// Calculated by calling applyConfig() after populating/parsing
protected Boolean isEnabled;
protected Boolean isOptional;
/*
* We will wait to initialize this until applyConfig() call to make sure we do it only when the caller is ready
* to use this option instance.
*/
public transient ISslContextFactory sslContextFactoryInstance;
public enum ConfigKey
{
KEYSTORE("keystore"),
KEYSTORE_PASSWORD("keystore_password"),
OUTBOUND_KEYSTORE("outbound_keystore"),
OUTBOUND_KEYSTORE_PASSWORD("outbound_keystore_password"),
TRUSTSTORE("truststore"),
TRUSTSTORE_PASSWORD("truststore_password"),
CIPHER_SUITES("cipher_suites"),
PROTOCOL("protocol"),
ACCEPTED_PROTOCOLS("accepted_protocols"),
ALGORITHM("algorithm"),
STORE_TYPE("store_type"),
REQUIRE_CLIENT_AUTH("require_client_auth"),
REQUIRE_ENDPOINT_VERIFICATION("require_endpoint_verification"),
ENABLED("enabled"),
OPTIONAL("optional");
final String keyName;
ConfigKey(String keyName)
{
this.keyName=keyName;
}
String getKeyName()
{
return keyName;
}
static Set<String> asSet()
{
Set<String> valueSet = new HashSet<>();
ConfigKey[] values = values();
for(ConfigKey key: values) {
valueSet.add(key.getKeyName().toLowerCase());
}
return valueSet;
}
}
public EncryptionOptions()
{
ssl_context_factory = new ParameterizedClass("org.apache.cassandra.security.DefaultSslContextFactory",
new HashMap<>());
keystore = "conf/.keystore";
keystore_password = null;
truststore = "conf/.truststore";
truststore_password = null;
cipher_suites = null;
protocol = null;
accepted_protocols = null;
algorithm = null;
store_type = "JKS";
require_client_auth = false;
require_endpoint_verification = false;
enabled = null;
optional = null;
}
public EncryptionOptions(ParameterizedClass ssl_context_factory, String keystore, String keystore_password,
String truststore, String truststore_password, List<String> cipher_suites,
String protocol, List<String> accepted_protocols, String algorithm, String store_type,
boolean require_client_auth, boolean require_endpoint_verification, Boolean enabled,
Boolean optional)
{
this.ssl_context_factory = ssl_context_factory;
this.keystore = keystore;
this.keystore_password = keystore_password;
this.truststore = truststore;
this.truststore_password = truststore_password;
this.cipher_suites = cipher_suites;
this.protocol = protocol;
this.accepted_protocols = accepted_protocols;
this.algorithm = algorithm;
this.store_type = store_type;
this.require_client_auth = require_client_auth;
this.require_endpoint_verification = require_endpoint_verification;
this.enabled = enabled;
this.optional = optional;
}
public EncryptionOptions(EncryptionOptions options)
{
ssl_context_factory = options.ssl_context_factory;
keystore = options.keystore;
keystore_password = options.keystore_password;
truststore = options.truststore;
truststore_password = options.truststore_password;
cipher_suites = options.cipher_suites;
protocol = options.protocol;
accepted_protocols = options.accepted_protocols;
algorithm = options.algorithm;
store_type = options.store_type;
require_client_auth = options.require_client_auth;
require_endpoint_verification = options.require_endpoint_verification;
enabled = options.enabled;
this.optional = options.optional;
}
/* Computes enabled and optional before use. Because the configuration can be loaded
* through pluggable mechanisms this is the only safe way to make sure that
* enabled and optional are set correctly.
*
* It also initializes the ISslContextFactory's instance
*/
public EncryptionOptions applyConfig()
{
ensureConfigNotApplied();
initializeSslContextFactory();
isEnabled = this.enabled != null && enabled;
if (optional != null)
{
isOptional = optional;
}
// If someone is asking for an _insecure_ connection and not explicitly telling us to refuse
// encrypted connections AND they have a keystore file, we assume they would like to be able
// to transition to encrypted connections in the future.
else if (sslContextFactoryInstance.hasKeystore())
{
isOptional = !isEnabled;
}
else
{
// Otherwise if there's no keystore, not possible to establish an optional secure connection
isOptional = false;
}
return this;
}
/**
* Prepares the parameterized keys provided in the configuration for {@link ISslContextFactory} to be passed in
* as the constructor for its implementation.
*
* @throws IllegalArgumentException in case any pre-defined key, as per {@link ConfigKey}, for the encryption
* options is duplicated in the parameterized keys.
*/
private void prepareSslContextFactoryParameterizedKeys(Map<String,Object> sslContextFactoryParameters)
{
if (ssl_context_factory.parameters != null)
{
Set<String> configKeys = ConfigKey.asSet();
for (Map.Entry<String, String> entry : ssl_context_factory.parameters.entrySet())
{
if(configKeys.contains(entry.getKey().toLowerCase()))
{
throw new IllegalArgumentException("SslContextFactory "+ssl_context_factory.class_name+" should " +
"configure '"+entry.getKey()+"' as encryption_options instead of" +
" parameterized keys");
}
sslContextFactoryParameters.put(entry.getKey(),entry.getValue());
}
}
}
protected void fillSslContextParams(Map<String, Object> sslContextFactoryParameters)
{
/*
* Copy all configs to the Map to pass it on to the ISslContextFactory's implementation
*/
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.KEYSTORE, this.keystore);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.KEYSTORE_PASSWORD, this.keystore_password);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.TRUSTSTORE, this.truststore);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.TRUSTSTORE_PASSWORD, this.truststore_password);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.CIPHER_SUITES, this.cipher_suites);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.PROTOCOL, this.protocol);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.ACCEPTED_PROTOCOLS, this.accepted_protocols);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.ALGORITHM, this.algorithm);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.STORE_TYPE, this.store_type);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.REQUIRE_CLIENT_AUTH, this.require_client_auth);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.REQUIRE_ENDPOINT_VERIFICATION, this.require_endpoint_verification);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.ENABLED, this.enabled);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.OPTIONAL, this.optional);
}
private void initializeSslContextFactory()
{
Map<String, Object> sslContextFactoryParameters = new HashMap<>();
prepareSslContextFactoryParameterizedKeys(sslContextFactoryParameters);
fillSslContextParams(sslContextFactoryParameters);
if (CassandraRelevantProperties.TEST_JVM_DTEST_DISABLE_SSL.getBoolean())
{
sslContextFactoryInstance = new DisableSslContextFactory();
}
else
{
sslContextFactoryInstance = FBUtilities.newSslContextFactory(ssl_context_factory.class_name,
sslContextFactoryParameters);
}
}
protected static void putSslContextFactoryParameter(Map<String, Object> existingParameters, ConfigKey configKey, Object value)
{
if (value != null) {
existingParameters.put(configKey.getKeyName(), value);
}
}
private void ensureConfigApplied()
{
if (isEnabled == null || isOptional == null)
throw new IllegalStateException("EncryptionOptions.applyConfig must be called first");
}
private void ensureConfigNotApplied()
{
if (isEnabled != null || isOptional != null)
throw new IllegalStateException("EncryptionOptions cannot be changed after configuration applied");
}
/**
* Indicates if the channel should be encrypted. Client and Server uses different logic to determine this
*
* @return if the channel should be encrypted
*/
public Boolean getEnabled()
{
ensureConfigApplied();
return isEnabled;
}
/**
* Sets if encryption should be enabled for this channel. Note that this should only be called by
* the configuration parser or tests. It is public only for that purpose, mutating enabled state
* is probably a bad idea.
* @param enabled value to set
*/
public void setEnabled(Boolean enabled)
{
ensureConfigNotApplied();
this.enabled = enabled;
}
/**
* Indicates if the channel may be encrypted (but is not required to be).
* Explicitly providing a value in the configuration take precedent.
* If no optional value is set and !isEnabled(), then optional connections are allowed
* if a keystore exists. Without it, it would be impossible to establish the connections.
*
* Return type is Boolean even though it can never be null so that snakeyaml can find it
* @return if the channel may be encrypted
*/
public Boolean getOptional()
{
ensureConfigApplied();
return isOptional;
}
/**
* Sets if encryption should be optional for this channel. Note that this should only be called by
* the configuration parser or tests. It is public only for that purpose, mutating enabled state
* is probably a bad idea.
* @param optional value to set
*/
public void setOptional(Boolean optional)
{
ensureConfigNotApplied();
this.optional = optional;
}
/**
* Sets accepted TLS protocol for this channel. Note that this should only be called by
* the configuration parser or tests. It is public only for that purpose, mutating protocol state
* is probably a bad idea.
* @param protocol value to set
*/
@VisibleForTesting
public void setProtocol(String protocol)
{
this.protocol = protocol;
}
public String getProtocol()
{
return protocol;
}
/**
* Sets accepted TLS protocols for this channel. Note that this should only be called by
* the configuration parser or tests. It is public only for that purpose, mutating protocol state
* is probably a bad idea. The function casing is required for snakeyaml to find this setter for the protected field.
* @param accepted_protocols value to set
*/
public void setAcceptedProtocols(List<String> accepted_protocols)
{
this.accepted_protocols = accepted_protocols == null ? null : ImmutableList.copyOf(accepted_protocols);
}
public List<String> getAcceptedProtocols()
{
return sslContextFactoryInstance == null ? null : sslContextFactoryInstance.getAcceptedProtocols();
}
public String[] acceptedProtocolsArray()
{
List<String> ap = getAcceptedProtocols();
return ap == null ? new String[0] : ap.toArray(new String[0]);
}
public TlsEncryptionPolicy tlsEncryptionPolicy()
{
if (getOptional())
{
return TlsEncryptionPolicy.OPTIONAL;
}
else if (getEnabled())
{
return TlsEncryptionPolicy.ENCRYPTED;
}
else
{
return TlsEncryptionPolicy.UNENCRYPTED;
}
}
public EncryptionOptions withSslContextFactory(ParameterizedClass sslContextFactoryClass)
{
return new EncryptionOptions(sslContextFactoryClass, keystore, keystore_password, truststore,
truststore_password, cipher_suites,protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification,enabled,
optional).applyConfig();
}
public EncryptionOptions withKeyStore(String keystore)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites,protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
public EncryptionOptions withKeyStorePassword(String keystore_password)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites,protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
public EncryptionOptions withTrustStore(String truststore)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
public EncryptionOptions withTrustStorePassword(String truststore_password)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
public EncryptionOptions withCipherSuites(List<String> cipher_suites)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
public EncryptionOptions withCipherSuites(String ... cipher_suites)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, ImmutableList.copyOf(cipher_suites), protocol,
accepted_protocols, algorithm, store_type, require_client_auth,
require_endpoint_verification, enabled, optional).applyConfig();
}
public EncryptionOptions withProtocol(String protocol)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
public EncryptionOptions withAcceptedProtocols(List<String> accepted_protocols)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites,protocol, accepted_protocols == null ? null :
ImmutableList.copyOf(accepted_protocols),
algorithm, store_type, require_client_auth, require_endpoint_verification,
enabled, optional).applyConfig();
}
public EncryptionOptions withAlgorithm(String algorithm)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
public EncryptionOptions withStoreType(String store_type)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
public EncryptionOptions withRequireClientAuth(boolean require_client_auth)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
public EncryptionOptions withRequireEndpointVerification(boolean require_endpoint_verification)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
public EncryptionOptions withEnabled(boolean enabled)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
public EncryptionOptions withOptional(Boolean optional)
{
return new EncryptionOptions(ssl_context_factory, keystore, keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols, algorithm,
store_type, require_client_auth, require_endpoint_verification, enabled,
optional).applyConfig();
}
/**
* The method is being mainly used to cache SslContexts therefore, we only consider
* fields that would make a difference when the TrustStore or KeyStore files are updated
*/
@Override
public boolean equals(Object o)
{
if (o == this)
return true;
if (o == null || getClass() != o.getClass())
return false;
EncryptionOptions opt = (EncryptionOptions)o;
return enabled == opt.enabled &&
optional == opt.optional &&
require_client_auth == opt.require_client_auth &&
require_endpoint_verification == opt.require_endpoint_verification &&
Objects.equals(keystore, opt.keystore) &&
Objects.equals(keystore_password, opt.keystore_password) &&
Objects.equals(truststore, opt.truststore) &&
Objects.equals(truststore_password, opt.truststore_password) &&
Objects.equals(protocol, opt.protocol) &&
Objects.equals(accepted_protocols, opt.accepted_protocols) &&
Objects.equals(algorithm, opt.algorithm) &&
Objects.equals(store_type, opt.store_type) &&
Objects.equals(cipher_suites, opt.cipher_suites) &&
Objects.equals(ssl_context_factory, opt.ssl_context_factory);
}
/**
* The method is being mainly used to cache SslContexts therefore, we only consider
* fields that would make a difference when the TrustStore or KeyStore files are updated
*/
@Override
public int hashCode()
{
int result = 0;
result += 31 * (keystore == null ? 0 : keystore.hashCode());
result += 31 * (keystore_password == null ? 0 : keystore_password.hashCode());
result += 31 * (truststore == null ? 0 : truststore.hashCode());
result += 31 * (truststore_password == null ? 0 : truststore_password.hashCode());
result += 31 * (protocol == null ? 0 : protocol.hashCode());
result += 31 * (accepted_protocols == null ? 0 : accepted_protocols.hashCode());
result += 31 * (algorithm == null ? 0 : algorithm.hashCode());
result += 31 * (store_type == null ? 0 : store_type.hashCode());
result += 31 * (enabled == null ? 0 : Boolean.hashCode(enabled));
result += 31 * (optional == null ? 0 : Boolean.hashCode(optional));
result += 31 * (cipher_suites == null ? 0 : cipher_suites.hashCode());
result += 31 * Boolean.hashCode(require_client_auth);
result += 31 * Boolean.hashCode(require_endpoint_verification);
result += 31 * (ssl_context_factory == null ? 0 : ssl_context_factory.hashCode());
return result;
}
public static class ServerEncryptionOptions extends EncryptionOptions
{
public enum InternodeEncryption
{
all, none, dc, rack
}
public final InternodeEncryption internode_encryption;
@Replaces(oldName = "enable_legacy_ssl_storage_port", deprecated = true)
public final boolean legacy_ssl_storage_port_enabled;
public final String outbound_keystore;
@Nullable
public final String outbound_keystore_password;
public ServerEncryptionOptions()
{
this.internode_encryption = InternodeEncryption.none;
this.legacy_ssl_storage_port_enabled = false;
this.outbound_keystore = null;
this.outbound_keystore_password = null;
}
public ServerEncryptionOptions(ParameterizedClass sslContextFactoryClass, String keystore,
String keystore_password,String outbound_keystore,
String outbound_keystore_password, String truststore, String truststore_password,
List<String> cipher_suites, String protocol, List<String> accepted_protocols,
String algorithm, String store_type, boolean require_client_auth,
boolean require_endpoint_verification, Boolean optional,
InternodeEncryption internode_encryption, boolean legacy_ssl_storage_port_enabled)
{
super(sslContextFactoryClass, keystore, keystore_password, truststore, truststore_password, cipher_suites,
protocol, accepted_protocols, algorithm, store_type, require_client_auth, require_endpoint_verification,
null, optional);
this.internode_encryption = internode_encryption;
this.legacy_ssl_storage_port_enabled = legacy_ssl_storage_port_enabled;
this.outbound_keystore = outbound_keystore;
this.outbound_keystore_password = outbound_keystore_password;
}
public ServerEncryptionOptions(ServerEncryptionOptions options)
{
super(options);
this.internode_encryption = options.internode_encryption;
this.legacy_ssl_storage_port_enabled = options.legacy_ssl_storage_port_enabled;
this.outbound_keystore = options.outbound_keystore;
this.outbound_keystore_password = options.outbound_keystore_password;
}
@Override
protected void fillSslContextParams(Map<String, Object> sslContextFactoryParameters)
{
super.fillSslContextParams(sslContextFactoryParameters);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.OUTBOUND_KEYSTORE, this.outbound_keystore);
putSslContextFactoryParameter(sslContextFactoryParameters, ConfigKey.OUTBOUND_KEYSTORE_PASSWORD, this.outbound_keystore_password);
}
@Override
public EncryptionOptions applyConfig()
{
return applyConfigInternal();
}
private ServerEncryptionOptions applyConfigInternal()
{
super.applyConfig();
isEnabled = this.internode_encryption != InternodeEncryption.none;
if (this.enabled != null && this.enabled && !isEnabled)
{
logger.warn("Setting server_encryption_options.enabled has no effect, use internode_encryption");
}
if (require_client_auth && (internode_encryption == InternodeEncryption.rack || internode_encryption == InternodeEncryption.dc))
{
logger.warn("Setting require_client_auth is incompatible with 'rack' and 'dc' internode_encryption values."
+ " It is possible for an internode connection to pretend to be in the same rack/dc by spoofing"
+ " its broadcast address in the handshake and bypass authentication. To ensure that mutual TLS"
+ " authentication is not bypassed, please set internode_encryption to 'all'. Continuing with"
+ " insecure configuration.");
}
// regardless of the optional flag, if the internode encryption is set to rack or dc
// it must be optional so that unencrypted connections within the rack or dc can be established.
isOptional = super.isOptional || internode_encryption == InternodeEncryption.rack || internode_encryption == InternodeEncryption.dc;
return this;
}
public boolean shouldEncrypt(InetAddressAndPort endpoint)
{
IEndpointSnitch snitch = DatabaseDescriptor.getEndpointSnitch();
switch (internode_encryption)
{
case none:
return false; // if nothing needs to be encrypted then return immediately.
case all:
break;
case dc:
if (snitch.getDatacenter(endpoint).equals(snitch.getLocalDatacenter()))
return false;
break;
case rack:
// for rack then check if the DC's are the same.
if (snitch.getRack(endpoint).equals(snitch.getLocalRack())
&& snitch.getDatacenter(endpoint).equals(snitch.getLocalDatacenter()))
return false;
break;
}
return true;
}
/**
* {@link #isOptional} will be set to {@code true} implicitly for {@code internode_encryption}
* values of "dc" and "all". This method returns the explicit, raw value of {@link #optional}
* as set by the user (if set at all).
*/
public boolean isExplicitlyOptional()
{
return optional != null && optional;
}
public ServerEncryptionOptions withSslContextFactory(ParameterizedClass sslContextFactoryClass)
{
return new ServerEncryptionOptions(sslContextFactoryClass, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withKeyStore(String keystore)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withKeyStorePassword(String keystore_password)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withTrustStore(String truststore)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withTrustStorePassword(String truststore_password)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withCipherSuites(List<String> cipher_suites)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withCipherSuites(String... cipher_suites)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, Arrays.asList(cipher_suites), protocol,
accepted_protocols, algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withProtocol(String protocol)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withAcceptedProtocols(List<String> accepted_protocols)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withAlgorithm(String algorithm)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withStoreType(String store_type)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withRequireClientAuth(boolean require_client_auth)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withRequireEndpointVerification(boolean require_endpoint_verification)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withOptional(boolean optional)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withInternodeEncryption(InternodeEncryption internode_encryption)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withLegacySslStoragePort(boolean enable_legacy_ssl_storage_port)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
enable_legacy_ssl_storage_port).applyConfigInternal();
}
public ServerEncryptionOptions withOutboundKeystore(String outboundKeystore)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outboundKeystore, outbound_keystore_password, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
public ServerEncryptionOptions withOutboundKeystorePassword(String outboundKeystorePassword)
{
return new ServerEncryptionOptions(ssl_context_factory, keystore, keystore_password,
outbound_keystore, outboundKeystorePassword, truststore,
truststore_password, cipher_suites, protocol, accepted_protocols,
algorithm, store_type, require_client_auth,
require_endpoint_verification, optional, internode_encryption,
legacy_ssl_storage_port_enabled).applyConfigInternal();
}
}
}