Skip to content

Commit

Permalink
Merge pull request scylladb#31 from dimakr/host_verification_22
Browse files Browse the repository at this point in the history
Add support for hostname verification
  • Loading branch information
CodeLieutenant authored Nov 18, 2024
2 parents dd4ba83 + 512236b commit 089f39c
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 16 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ public abstract class EncryptionOptions
public String store_type = "JKS";
public boolean require_client_auth = false;
public boolean require_endpoint_verification = false;
public boolean hostname_verification = false;

public static class ClientEncryptionOptions extends EncryptionOptions
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -121,6 +121,7 @@ public EncryptionOptions.ClientEncryptionOptions getEncryptionOptions()
encOptions.algorithm = options.alg.value();
encOptions.protocol = options.protocol.value();
encOptions.cipher_suites = options.ciphers.value().split(",");
encOptions.hostname_verification = Boolean.parseBoolean(options.hostnameVerification.value());
}
return encOptions;
}
Expand All @@ -138,11 +139,12 @@ static class TOptions extends GroupedOptions implements Serializable
final OptionSimple alg = new OptionSimple("ssl-alg=", ".*", "SunX509", "SSL: algorithm", false);
final OptionSimple storeType = new OptionSimple("store-type=", ".*", "JKS", "SSL: keystore format", false);
final OptionSimple ciphers = new OptionSimple("ssl-ciphers=", ".*", "TLS_RSA_WITH_AES_128_CBC_SHA,TLS_RSA_WITH_AES_256_CBC_SHA", "SSL: comma delimited list of encryption suites to use", false);
final OptionSimple hostnameVerification = new OptionSimple("hostname-verification=", ".*", "false", "SSL: enable hostname verification in Java Driver", false);

@Override
public List<? extends Option> options()
{
return Arrays.asList(factory, trustStore, trustStorePw, keyStore, keyStorePw, protocol, alg, storeType, ciphers);
return Arrays.asList(factory, trustStore, trustStorePw, keyStore, keyStorePw, protocol, alg, storeType, ciphers, hostnameVerification);
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,18 +18,25 @@
package org.apache.cassandra.stress.util;

import java.io.File;
import java.net.InetSocketAddress;
import java.util.List;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLHandshakeException;
import javax.net.ssl.SSLParameters;

import com.datastax.driver.core.*;
import com.datastax.driver.core.RemoteEndpointAwareJdkSSLOptions;
import com.datastax.driver.core.exceptions.NoHostAvailableException;
import com.datastax.driver.core.policies.RackAwareRoundRobinPolicy;
import com.datastax.driver.core.policies.DCAwareRoundRobinPolicy;
import com.datastax.driver.core.policies.LoadBalancingPolicy;
import com.datastax.driver.core.policies.TokenAwarePolicy;
import com.datastax.driver.core.policies.TokenAwarePolicy.ReplicaOrdering;
import com.datastax.driver.core.policies.WhiteListPolicy;
import com.datastax.shaded.netty.channel.socket.SocketChannel;
import io.netty.util.internal.logging.InternalLoggerFactory;
import io.netty.util.internal.logging.Slf4JLoggerFactory;
import org.apache.cassandra.config.EncryptionOptions;
Expand Down Expand Up @@ -165,9 +172,22 @@ public void connect(ProtocolOptions.Compression compression) throws Exception
{
SSLContext sslContext;
sslContext = SSLFactory.createSSLContext(encryptionOptions, true);
SSLOptions sslOptions = JdkSSLOptions.builder()
.withSSLContext(sslContext)
.withCipherSuites(encryptionOptions.cipher_suites).build();

RemoteEndpointAwareJdkSSLOptions sslOptions = new RemoteEndpointAwareJdkSSLOptions(sslContext, encryptionOptions.cipher_suites)
{
@Override
protected SSLEngine newSSLEngine(SocketChannel channel, InetSocketAddress remoteEndpoint)
{
SSLEngine engine = super.newSSLEngine(channel, remoteEndpoint);
if (encryptionOptions.hostname_verification) {
SSLParameters parameters = engine.getSSLParameters();
parameters.setEndpointIdentificationAlgorithm("HTTPS");
engine.setSSLParameters(parameters);
}
return engine;
}
};

clusterBuilder.withSSL(sslOptions);
}

Expand All @@ -185,20 +205,42 @@ else if (username != null)
clusterBuilder.withScyllaCloudConnectionConfig(cloudConfigFile);
}

cluster = clusterBuilder.build();
Metadata metadata = cluster.getMetadata();
System.out.printf(
"Connected to cluster: %s, max pending requests per connection %d, max connections per host %d%n",
metadata.getClusterName(),
maxPendingPerConnection,
connectionsPerHost);
for (Host host : metadata.getAllHosts())
{
System.out.printf("Datatacenter: %s; Host: %s; Rack: %s%n",
host.getDatacenter(), host.getAddress(), host.getRack());
try {
cluster = clusterBuilder.build();
Metadata metadata = cluster.getMetadata();
System.out.printf(
"Connected to cluster: %s, max pending requests per connection %d, max connections per host %d%n",
metadata.getClusterName(),
maxPendingPerConnection,
connectionsPerHost);
for (Host host : metadata.getAllHosts())
{
System.out.printf("Datatacenter: %s; Host: %s; Rack: %s%n",
host.getDatacenter(), host.getAddress(), host.getRack());
}

session = cluster.connect();
} catch (NoHostAvailableException e) {
Throwable sslException = findExceptionInErrors(e, SSLHandshakeException.class);
if (sslException != null)
System.err.println(String.format(
" Failed to connect to node due to an error during SSL handshake %s: %s",
sslException.getClass().getName(), sslException.getMessage()));
throw e;
}
}

session = cluster.connect();
private Throwable findExceptionInErrors(NoHostAvailableException e, Class<? extends Throwable> exceptionClass) {
for (Throwable error : e.getErrors().values()) {
Throwable current = error;
while (current != null) {
if (exceptionClass.isInstance(current)) {
return current;
}
current = current.getCause();
}
}
return null;
}

public Cluster getCluster()
Expand Down

0 comments on commit 089f39c

Please sign in to comment.