use of org.apache.cassandra.config.EncryptionOptions in project cassandra by apache.
the class PipelineConfigurator method encryptionConfig.
protected EncryptionConfig encryptionConfig() {
final EncryptionOptions encryptionOptions = DatabaseDescriptor.getNativeProtocolEncryptionOptions();
switch(tlsEncryptionPolicy) {
case UNENCRYPTED:
// if encryption is not enabled, no further steps are required after the initial setup
return channel -> {
};
case OPTIONAL:
// If optional, install a handler which detects whether or not the client is sending
// encrypted bytes. If so, on receipt of the next bytes, replace that handler with
// an SSL Handler, otherwise just remove it and proceed with an unencrypted channel.
logger.debug("Enabling optionally encrypted CQL connections between client and server");
return channel -> {
SslContext sslContext = SSLFactory.getOrCreateSslContext(encryptionOptions, encryptionOptions.require_client_auth, ISslContextFactory.SocketType.SERVER);
channel.pipeline().addFirst(SSL_HANDLER, new ByteToMessageDecoder() {
@Override
protected void decode(ChannelHandlerContext channelHandlerContext, ByteBuf byteBuf, List<Object> list) throws Exception {
if (byteBuf.readableBytes() < 5) {
// once more bytes a ready.
return;
}
if (SslHandler.isEncrypted(byteBuf)) {
// Connection uses SSL/TLS, replace the detection handler with a SslHandler and so use
// encryption.
SslHandler sslHandler = sslContext.newHandler(channel.alloc());
channelHandlerContext.pipeline().replace(SSL_HANDLER, SSL_HANDLER, sslHandler);
} else {
// Connection use no TLS/SSL encryption, just remove the detection handler and continue without
// SslHandler in the pipeline.
channelHandlerContext.pipeline().remove(SSL_HANDLER);
}
}
});
};
case ENCRYPTED:
logger.debug("Enabling encrypted CQL connections between client and server");
return channel -> {
SslContext sslContext = SSLFactory.getOrCreateSslContext(encryptionOptions, encryptionOptions.require_client_auth, ISslContextFactory.SocketType.SERVER);
channel.pipeline().addFirst(SSL_HANDLER, sslContext.newHandler(channel.alloc()));
};
default:
throw new IllegalStateException("Unrecognized TLS encryption policy: " + this.tlsEncryptionPolicy);
}
}
use of org.apache.cassandra.config.EncryptionOptions in project cassandra by apache.
the class SimpleClientBurnTest method test.
@Test
public void test() throws Throwable {
SizeCaps smallMessageCap = new SizeCaps(5, 10, 5, 5);
SizeCaps largeMessageCap = new SizeCaps(1000, 2000, 5, 150);
int largeMessageFrequency = 1000;
CQLConnectionTest.AllocationObserver allocationObserver = new CQLConnectionTest.AllocationObserver();
PipelineConfigurator configurator = new PipelineConfigurator(NativeTransportService.useEpoll(), false, false, UNENCRYPTED) {
protected ClientResourceLimits.ResourceProvider resourceProvider(ClientResourceLimits.Allocator allocator) {
return BurnTestUtil.observableResourceProvider(allocationObserver).apply(allocator);
}
};
Server server = new Server.Builder().withHost(address).withPort(port).withPipelineConfigurator(configurator).build();
ClientMetrics.instance.init(Collections.singleton(server));
server.start();
Message.Type.QUERY.unsafeSetCodec(new Message.Codec<QueryMessage>() {
public QueryMessage decode(ByteBuf body, ProtocolVersion version) {
QueryMessage queryMessage = QueryMessage.codec.decode(body, version);
return new QueryMessage(queryMessage.query, queryMessage.options) {
protected Message.Response execute(QueryState state, long queryStartNanoTime, boolean traceRequest) {
int idx = Integer.parseInt(queryMessage.query);
SizeCaps caps = idx % largeMessageFrequency == 0 ? largeMessageCap : smallMessageCap;
return generateRows(idx, caps);
}
};
}
public void encode(QueryMessage queryMessage, ByteBuf dest, ProtocolVersion version) {
QueryMessage.codec.encode(queryMessage, dest, version);
}
public int encodedSize(QueryMessage queryMessage, ProtocolVersion version) {
return QueryMessage.codec.encodedSize(queryMessage, version);
}
});
List<AssertUtil.ThrowingSupplier<SimpleClient>> suppliers = Arrays.asList(() -> new SimpleClient(address.getHostAddress(), port, ProtocolVersion.V5, true, new EncryptionOptions()).connect(false), () -> new SimpleClient(address.getHostAddress(), port, ProtocolVersion.V4, false, new EncryptionOptions()).connect(false));
int threads = 3;
ExecutorService executor = Executors.newFixedThreadPool(threads);
AtomicReference<Throwable> error = new AtomicReference<>();
CountDownLatch signal = new CountDownLatch(1);
// TODO: exercise client -> server large messages
for (int t = 0; t < threads; t++) {
int threadId = t;
executor.execute(() -> {
try (SimpleClient client = suppliers.get(threadId % suppliers.size()).get()) {
int counter = 0;
while (!executor.isShutdown() && error.get() == null) {
if (counter % 100 == 0)
System.out.println("idx = " + counter);
List<Message.Request> messages = new ArrayList<>();
for (int j = 0; j < 10; j++) {
int descriptor = counter + j * 100 + threadId * 10000;
SizeCaps caps = descriptor % largeMessageFrequency == 0 ? largeMessageCap : smallMessageCap;
QueryMessage query = generateQueryMessage(descriptor, caps, client.connection.getVersion());
messages.add(query);
}
Map<Message.Request, Message.Response> responses = client.execute(messages);
for (Map.Entry<Message.Request, Message.Response> entry : responses.entrySet()) {
int idx = Integer.parseInt(((QueryMessage) entry.getKey()).query);
SizeCaps caps = idx % largeMessageFrequency == 0 ? largeMessageCap : smallMessageCap;
ResultMessage.Rows actual = ((ResultMessage.Rows) entry.getValue());
ResultMessage.Rows expected = generateRows(idx, caps);
Assert.assertEquals(expected.result.rows.size(), actual.result.rows.size());
for (int i = 0; i < expected.result.rows.size(); i++) {
List<ByteBuffer> expectedRow = expected.result.rows.get(i);
List<ByteBuffer> actualRow = actual.result.rows.get(i);
Assert.assertEquals(expectedRow.size(), actualRow.size());
for (int col = 0; col < expectedRow.size(); col++) Assert.assertEquals(expectedRow.get(col), actualRow.get(col));
}
}
counter++;
// try to trigger leak detector
System.gc();
}
} catch (Throwable e) {
e.printStackTrace();
error.set(e);
signal.countDown();
}
});
}
Assert.assertFalse(signal.await(120, TimeUnit.SECONDS));
executor.shutdown();
executor.awaitTermination(10, TimeUnit.SECONDS);
assertThat(allocationObserver.endpointAllocationTotal()).isEqualTo(allocationObserver.endpointReleaseTotal());
assertThat(allocationObserver.globalAllocationTotal()).isEqualTo(allocationObserver.globalReleaseTotal());
server.stop();
}
use of org.apache.cassandra.config.EncryptionOptions in project cassandra by apache.
the class MessagePayloadTest method testMessagePayloadBeta.
@Test
public void testMessagePayloadBeta() throws Throwable {
QueryHandler queryHandler = (QueryHandler) cqlQueryHandlerField.get(null);
cqlQueryHandlerField.set(null, new TestQueryHandler());
try {
requireNetwork();
Assert.assertSame(TestQueryHandler.class, ClientState.getCQLQueryHandler().getClass());
SimpleClient client = new SimpleClient(nativeAddr.getHostAddress(), nativePort, ProtocolVersion.V5, true, new EncryptionOptions());
try {
client.connect(false);
Map<String, ByteBuffer> reqMap;
Map<String, ByteBuffer> respMap;
QueryOptions queryOptions = QueryOptions.create(QueryOptions.DEFAULT.getConsistency(), QueryOptions.DEFAULT.getValues(), QueryOptions.DEFAULT.skipMetadata(), QueryOptions.DEFAULT.getPageSize(), QueryOptions.DEFAULT.getPagingState(), QueryOptions.DEFAULT.getSerialConsistency(), ProtocolVersion.V5, KEYSPACE);
QueryMessage queryMessage = new QueryMessage("CREATE TABLE atable (pk int PRIMARY KEY, v text)", queryOptions);
PrepareMessage prepareMessage = new PrepareMessage("SELECT * FROM atable", KEYSPACE);
reqMap = Collections.singletonMap("foo", bytes(42));
responsePayload = respMap = Collections.singletonMap("bar", bytes(42));
queryMessage.setCustomPayload(reqMap);
Message.Response queryResponse = client.execute(queryMessage);
payloadEquals(reqMap, requestPayload);
payloadEquals(respMap, queryResponse.getCustomPayload());
reqMap = Collections.singletonMap("foo", bytes(43));
responsePayload = respMap = Collections.singletonMap("bar", bytes(43));
prepareMessage.setCustomPayload(reqMap);
ResultMessage.Prepared prepareResponse = (ResultMessage.Prepared) client.execute(prepareMessage);
payloadEquals(reqMap, requestPayload);
payloadEquals(respMap, prepareResponse.getCustomPayload());
ExecuteMessage executeMessage = new ExecuteMessage(prepareResponse.statementId, prepareResponse.resultMetadataId, QueryOptions.DEFAULT);
reqMap = Collections.singletonMap("foo", bytes(44));
responsePayload = respMap = Collections.singletonMap("bar", bytes(44));
executeMessage.setCustomPayload(reqMap);
Message.Response executeResponse = client.execute(executeMessage);
payloadEquals(reqMap, requestPayload);
payloadEquals(respMap, executeResponse.getCustomPayload());
BatchMessage batchMessage = new BatchMessage(BatchStatement.Type.UNLOGGED, Collections.<Object>singletonList("INSERT INTO " + KEYSPACE + ".atable (pk,v) VALUES (1, 'foo')"), Collections.singletonList(Collections.<ByteBuffer>emptyList()), queryOptions);
reqMap = Collections.singletonMap("foo", bytes(45));
responsePayload = respMap = Collections.singletonMap("bar", bytes(45));
batchMessage.setCustomPayload(reqMap);
Message.Response batchResponse = client.execute(batchMessage);
payloadEquals(reqMap, requestPayload);
payloadEquals(respMap, batchResponse.getCustomPayload());
} finally {
client.close();
}
} finally {
cqlQueryHandlerField.set(null, queryHandler);
}
}
use of org.apache.cassandra.config.EncryptionOptions in project cassandra by apache.
the class StressSettings method getJavaDriverClient.
public JavaDriverClient getJavaDriverClient(String keyspace) {
if (client != null)
return client;
synchronized (this) {
if (numFailures >= MAX_NUM_FAILURES)
throw new RuntimeException("Failed to create client too many times");
try {
String currentNode = node.randomNode();
if (client != null)
return client;
EncryptionOptions encOptions = transport.getEncryptionOptions();
JavaDriverClient c = new JavaDriverClient(this, currentNode, port.nativePort, encOptions);
c.connect(mode.compression());
if (keyspace != null)
c.execute("USE \"" + keyspace + "\";", org.apache.cassandra.db.ConsistencyLevel.ONE);
return client = c;
} catch (Exception e) {
numFailures += 1;
throw new RuntimeException(e);
}
}
}
use of org.apache.cassandra.config.EncryptionOptions in project cassandra by apache.
the class SSLFactoryTest method getSslContext_ParamChanges.
@Test
public void getSslContext_ParamChanges() throws IOException {
EncryptionOptions options = addKeystoreOptions(encryptionOptions).withEnabled(true).withCipherSuites("TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256");
SslContext ctx1 = SSLFactory.getOrCreateSslContext(options, true, ISslContextFactory.SocketType.SERVER);
Assert.assertTrue(ctx1.isServer());
Assert.assertEquals(ctx1.cipherSuites(), options.cipher_suites);
options = options.withCipherSuites("TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256");
SslContext ctx2 = SSLFactory.getOrCreateSslContext(options, true, ISslContextFactory.SocketType.CLIENT);
Assert.assertTrue(ctx2.isClient());
Assert.assertEquals(ctx2.cipherSuites(), options.cipher_suites);
}
Aggregations