org.apache.drill.exec.ssl.SSLConfigClient.java Source code

Java tutorial

Introduction

Here is the source code for org.apache.drill.exec.ssl.SSLConfigClient.java

Source

/*
 * 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.drill.exec.ssl;

import io.netty.handler.ssl.SslContext;
import io.netty.handler.ssl.SslContextBuilder;
import io.netty.handler.ssl.SslProvider;
import org.apache.drill.common.config.DrillProperties;
import org.apache.drill.common.exceptions.DrillException;
import org.apache.drill.exec.memory.BufferAllocator;

import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.SSLParameters;
import javax.net.ssl.TrustManagerFactory;
import java.util.Properties;

public class SSLConfigClient extends SSLConfig {

    private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SSLConfigClient.class);

    private final Properties properties;
    private final boolean userSslEnabled;
    private final String trustStoreType;
    private final String trustStorePath;
    private final String trustStorePassword;
    private final boolean disableHostVerification;
    private final boolean disableCertificateVerification;
    private final boolean useSystemTrustStore;
    private final String protocol;
    private final int handshakeTimeout;
    private final String provider;

    private final String emptyString = new String();

    public SSLConfigClient(Properties properties) throws DrillException {
        this.properties = properties;
        userSslEnabled = getBooleanProperty(DrillProperties.ENABLE_TLS);
        trustStoreType = getStringProperty(DrillProperties.TRUSTSTORE_TYPE, "JKS");
        trustStorePath = getStringProperty(DrillProperties.TRUSTSTORE_PATH, "");
        trustStorePassword = getStringProperty(DrillProperties.TRUSTSTORE_PASSWORD, "");
        disableHostVerification = getBooleanProperty(DrillProperties.DISABLE_HOST_VERIFICATION);
        disableCertificateVerification = getBooleanProperty(DrillProperties.DISABLE_CERT_VERIFICATION);
        useSystemTrustStore = getBooleanProperty(DrillProperties.USE_SYSTEM_TRUSTSTORE);
        protocol = getStringProperty(DrillProperties.TLS_PROTOCOL, DEFAULT_SSL_PROTOCOL);
        int hsTimeout = getIntProperty(DrillProperties.TLS_HANDSHAKE_TIMEOUT, DEFAULT_SSL_HANDSHAKE_TIMEOUT_MS);
        if (hsTimeout <= 0) {
            hsTimeout = DEFAULT_SSL_HANDSHAKE_TIMEOUT_MS;
        }
        handshakeTimeout = hsTimeout;
        // If provider is OPENSSL then to debug or run this code in an IDE, you will need to enable
        // the dependency on netty-tcnative with the correct classifier for the platform you use.
        // This can be done by enabling the openssl profile.
        // If the IDE is Eclipse, it requires you to install an additional Eclipse plugin available here:
        // http://repo1.maven.org/maven2/kr/motd/maven/os-maven-plugin/1.6.1/os-maven-plugin-1.6.1.jar
        // or from your local maven repository:
        // ~/.m2/repository/kr/motd/maven/os-maven-plugin/1.6.1/os-maven-plugin-1.6.1.jar
        // Note that installing this plugin may require you to start with a new workspace
        provider = getStringProperty(DrillProperties.TLS_PROVIDER, DEFAULT_SSL_PROVIDER);
    }

    private boolean getBooleanProperty(String propName) {
        return (properties != null) && (properties.containsKey(propName))
                && (properties.getProperty(propName).compareToIgnoreCase("true") == 0);
    }

    private String getStringProperty(String name, String defaultValue) {
        String value = "";
        if ((properties != null) && (properties.containsKey(name))) {
            value = properties.getProperty(name);
        }
        if (value.isEmpty()) {
            value = defaultValue;
        }
        value = value.trim();
        return value;
    }

    private int getIntProperty(String name, int defaultValue) {
        int value = defaultValue;
        if (properties != null) {
            String property = properties.getProperty(name);
            if (property != null && property.length() > 0) {
                value = Integer.decode(property);
            }
        }
        return value;
    }

    public void validateKeyStore() throws DrillException {

    }

    @Override
    public SslContext initNettySslContext() throws DrillException {
        final SslContext sslCtx;

        if (!userSslEnabled) {
            return null;
        }

        TrustManagerFactory tmf;
        try {
            tmf = initializeTrustManagerFactory();
            sslCtx = SslContextBuilder.forClient().sslProvider(getProvider()).trustManager(tmf).protocols(protocol)
                    .build();
        } catch (Exception e) {
            // Catch any SSL initialization Exceptions here and abort.
            throw new DrillException(new StringBuilder()
                    .append("SSL is enabled but cannot be initialized due to the following exception: ")
                    .append("[ ").append(e.getMessage()).append("]. ").toString());
        }
        this.nettySslContext = sslCtx;
        return sslCtx;
    }

    @Override
    public SSLContext initJDKSSLContext() throws DrillException {
        final SSLContext sslCtx;

        if (!userSslEnabled) {
            return null;
        }

        TrustManagerFactory tmf;
        try {
            tmf = initializeTrustManagerFactory();
            sslCtx = SSLContext.getInstance(protocol);
            sslCtx.init(null, tmf.getTrustManagers(), null);
        } catch (Exception e) {
            // Catch any SSL initialization Exceptions here and abort.
            throw new DrillException(new StringBuilder()
                    .append("SSL is enabled but cannot be initialized due to the following exception: ")
                    .append("[ ").append(e.getMessage()).append("]. ").toString());
        }
        this.jdkSSlContext = sslCtx;
        return sslCtx;
    }

    @Override
    public SSLEngine createSSLEngine(BufferAllocator allocator, String peerHost, int peerPort) {
        SSLEngine engine = super.createSSLEngine(allocator, peerHost, peerPort);

        if (!this.disableHostVerification()) {
            SSLParameters sslParameters = engine.getSSLParameters();
            // only available since Java 7
            sslParameters.setEndpointIdentificationAlgorithm("HTTPS");
            engine.setSSLParameters(sslParameters);
        }

        engine.setUseClientMode(true);

        try {
            engine.setEnableSessionCreation(true);
        } catch (Exception e) {
            // Openssl implementation may throw this.
            logger.debug("Session creation not enabled. Exception: {}", e.getMessage());
        }

        return engine;
    }

    @Override
    public boolean isUserSslEnabled() {
        return userSslEnabled;
    }

    @Override
    public boolean isHttpsEnabled() {
        return false;
    }

    @Override
    public String getKeyStoreType() {
        return emptyString;
    }

    @Override
    public String getKeyStorePath() {
        return emptyString;
    }

    @Override
    public String getKeyStorePassword() {
        return emptyString;
    }

    @Override
    public String getKeyPassword() {
        return emptyString;
    }

    @Override
    public String getTrustStoreType() {
        return trustStoreType;
    }

    @Override
    public boolean hasTrustStorePath() {
        return !trustStorePath.isEmpty();
    }

    @Override
    public String getTrustStorePath() {
        return trustStorePath;
    }

    @Override
    public boolean hasTrustStorePassword() {
        return !trustStorePassword.isEmpty();
    }

    @Override
    public String getTrustStorePassword() {
        return trustStorePassword;
    }

    @Override
    public String getProtocol() {
        return protocol;
    }

    @Override
    public SslProvider getProvider() {
        return provider.equalsIgnoreCase("JDK") ? SslProvider.JDK : SslProvider.OPENSSL;
    }

    @Override
    public int getHandshakeTimeout() {
        return handshakeTimeout;
    }

    @Override
    public Mode getMode() {
        return Mode.CLIENT;
    }

    @Override
    public boolean disableHostVerification() {
        return disableHostVerification;
    }

    @Override
    public boolean disableCertificateVerification() {
        return disableCertificateVerification;
    }

    @Override
    public boolean useSystemTrustStore() {
        return useSystemTrustStore;
    }

    public boolean isSslValid() {
        return true;
    }

}