Search in sources :

Example 1 with EncryptionOptions

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);
    }
}
Also used : LoggingHandler(io.netty.handler.logging.LoggingHandler) ISslContextFactory(org.apache.cassandra.security.ISslContextFactory) LoggerFactory(org.slf4j.LoggerFactory) EncryptionOptions(org.apache.cassandra.config.EncryptionOptions) Strings(com.google.common.base.Strings) ByteBuf(io.netty.buffer.ByteBuf) EpollServerSocketChannel(io.netty.channel.epoll.EpollServerSocketChannel) SSLFactory(org.apache.cassandra.security.SSLFactory) Map(java.util.Map) StartupMessage(org.apache.cassandra.transport.messages.StartupMessage) io.netty.channel(io.netty.channel) ByteToMessageDecoder(io.netty.handler.codec.ByteToMessageDecoder) DatabaseDescriptor(org.apache.cassandra.config.DatabaseDescriptor) Logger(org.slf4j.Logger) IdleStateEvent(io.netty.handler.timeout.IdleStateEvent) SslContext(io.netty.handler.ssl.SslContext) NioServerSocketChannel(io.netty.channel.socket.nio.NioServerSocketChannel) InetSocketAddress(java.net.InetSocketAddress) TimeUnit(java.util.concurrent.TimeUnit) IdleStateHandler(io.netty.handler.timeout.IdleStateHandler) Version(io.netty.util.Version) List(java.util.List) LogLevel(io.netty.handler.logging.LogLevel) SslHandler(io.netty.handler.ssl.SslHandler) ServerBootstrap(io.netty.bootstrap.ServerBootstrap) org.apache.cassandra.net(org.apache.cassandra.net) List(java.util.List) EncryptionOptions(org.apache.cassandra.config.EncryptionOptions) ByteToMessageDecoder(io.netty.handler.codec.ByteToMessageDecoder) ByteBuf(io.netty.buffer.ByteBuf) SslHandler(io.netty.handler.ssl.SslHandler) SslContext(io.netty.handler.ssl.SslContext)

Example 2 with EncryptionOptions

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();
}
Also used : BurnTestUtil.generateQueryMessage(org.apache.cassandra.transport.BurnTestUtil.generateQueryMessage) QueryMessage(org.apache.cassandra.transport.messages.QueryMessage) BurnTestUtil.generateQueryMessage(org.apache.cassandra.transport.BurnTestUtil.generateQueryMessage) ResultMessage(org.apache.cassandra.transport.messages.ResultMessage) QueryMessage(org.apache.cassandra.transport.messages.QueryMessage) ByteBuf(io.netty.buffer.ByteBuf) EncryptionOptions(org.apache.cassandra.config.EncryptionOptions) AtomicReference(java.util.concurrent.atomic.AtomicReference) QueryState(org.apache.cassandra.service.QueryState) SizeCaps(org.apache.cassandra.transport.BurnTestUtil.SizeCaps) ResultMessage(org.apache.cassandra.transport.messages.ResultMessage) ByteBuffer(java.nio.ByteBuffer) Test(org.junit.Test)

Example 3 with EncryptionOptions

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);
    }
}
Also used : QueryMessage(org.apache.cassandra.transport.messages.QueryMessage) QueryHandler(org.apache.cassandra.cql3.QueryHandler) BatchMessage(org.apache.cassandra.transport.messages.BatchMessage) PrepareMessage(org.apache.cassandra.transport.messages.PrepareMessage) ExecuteMessage(org.apache.cassandra.transport.messages.ExecuteMessage) ResultMessage(org.apache.cassandra.transport.messages.ResultMessage) QueryMessage(org.apache.cassandra.transport.messages.QueryMessage) ResultMessage(org.apache.cassandra.transport.messages.ResultMessage) ByteBuffer(java.nio.ByteBuffer) BatchQueryOptions(org.apache.cassandra.cql3.BatchQueryOptions) QueryOptions(org.apache.cassandra.cql3.QueryOptions) PrepareMessage(org.apache.cassandra.transport.messages.PrepareMessage) ExecuteMessage(org.apache.cassandra.transport.messages.ExecuteMessage) EncryptionOptions(org.apache.cassandra.config.EncryptionOptions) BatchMessage(org.apache.cassandra.transport.messages.BatchMessage) Test(org.junit.Test)

Example 4 with EncryptionOptions

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);
        }
    }
}
Also used : JavaDriverClient(org.apache.cassandra.stress.util.JavaDriverClient) EncryptionOptions(org.apache.cassandra.config.EncryptionOptions)

Example 5 with EncryptionOptions

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);
}
Also used : EncryptionOptions(org.apache.cassandra.config.EncryptionOptions) ServerEncryptionOptions(org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions) SslContext(io.netty.handler.ssl.SslContext) Test(org.junit.Test)

Aggregations

EncryptionOptions (org.apache.cassandra.config.EncryptionOptions)14 Test (org.junit.Test)10 QueryMessage (org.apache.cassandra.transport.messages.QueryMessage)5 SslContext (io.netty.handler.ssl.SslContext)4 ServerEncryptionOptions (org.apache.cassandra.config.EncryptionOptions.ServerEncryptionOptions)3 ParameterizedClass (org.apache.cassandra.config.ParameterizedClass)3 SimpleClient (org.apache.cassandra.transport.SimpleClient)3 ByteBuf (io.netty.buffer.ByteBuf)2 OpenSslContext (io.netty.handler.ssl.OpenSslContext)2 ByteBuffer (java.nio.ByteBuffer)2 HashMap (java.util.HashMap)2 Message (org.apache.cassandra.transport.Message)2 ResultMessage (org.apache.cassandra.transport.messages.ResultMessage)2 Strings (com.google.common.base.Strings)1 ServerBootstrap (io.netty.bootstrap.ServerBootstrap)1 io.netty.channel (io.netty.channel)1 EpollServerSocketChannel (io.netty.channel.epoll.EpollServerSocketChannel)1 NioServerSocketChannel (io.netty.channel.socket.nio.NioServerSocketChannel)1 ByteToMessageDecoder (io.netty.handler.codec.ByteToMessageDecoder)1 LogLevel (io.netty.handler.logging.LogLevel)1