You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@drill.apache.org by vo...@apache.org on 2020/06/20 12:51:24 UTC
[drill] branch master updated: DRILL-7750: Drill fails to read
KeyStore password from Credential provider (#2088)
This is an automated email from the ASF dual-hosted git repository.
volodymyr pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/drill.git
The following commit(s) were added to refs/heads/master by this push:
new 1b95c0a DRILL-7750: Drill fails to read KeyStore password from Credential provider (#2088)
1b95c0a is described below
commit 1b95c0a8cfce23e11596353a821a5216fd1a983d
Author: Bohdan Kazydub <38...@users.noreply.github.com>
AuthorDate: Sat Jun 20 15:51:14 2020 +0300
DRILL-7750: Drill fails to read KeyStore password from Credential provider (#2088)
---
.../java/org/apache/drill/exec/ssl/SSLConfig.java | 32 +++++++++++++++++++--
.../apache/drill/exec/ssl/SSLConfigBuilder.java | 6 ++--
.../org/apache/drill/exec/ssl/SSLConfigClient.java | 33 ++++++++++++++++++----
.../org/apache/drill/exec/ssl/SSLConfigServer.java | 22 +++++++++++----
.../drill/exec/ssl/SSLCredentialsProvider.java | 22 ++++++++++-----
5 files changed, 91 insertions(+), 24 deletions(-)
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfig.java b/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfig.java
index c3ff0c5..e82bbdf 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfig.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfig.java
@@ -22,18 +22,23 @@ import io.netty.handler.ssl.SslProvider;
import io.netty.handler.ssl.util.InsecureTrustManagerFactory;
import org.apache.drill.common.exceptions.DrillException;
import org.apache.drill.exec.memory.BufferAllocator;
+import org.apache.hadoop.conf.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManagerFactory;
import java.io.FileInputStream;
+import java.io.IOException;
import java.io.InputStream;
import java.security.KeyStore;
+import java.text.MessageFormat;
public abstract class SSLConfig {
- private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SSLConfig.class);
+ private static final Logger logger = LoggerFactory.getLogger(SSLConfig.class);
public static final String DEFAULT_SSL_PROVIDER = "JDK"; // JDK or OPENSSL
public static final String DEFAULT_SSL_PROTOCOL = "TLSv1.2";
@@ -60,8 +65,7 @@ public abstract class SSLConfig {
// copy of Hadoop's SSLFactory.Mode. Done so that we do not
// need to include hadoop-common as a dependency in
// jdbc-all-jar.
- public enum Mode { CLIENT, SERVER };
-
+ public enum Mode { CLIENT, SERVER }
public SSLConfig() {
}
@@ -230,6 +234,28 @@ public abstract class SSLConfig {
return engine;
}
+ abstract Configuration getHadoopConfig();
+
+ String getPassword(String hadoopName) {
+ String value = null;
+ if (getHadoopConfig() != null) {
+ try {
+ char[] password = getHadoopConfig().getPassword(hadoopName);
+ if (password != null) {
+ value = String.valueOf(password);
+ }
+ } catch (IOException e) {
+ logger.warn("Unable to obtain password {} from CredentialProvider API: {}", hadoopName, e.getMessage());
+ // fallthrough
+ }
+ }
+ return value;
+ }
+
+ String resolveHadoopPropertyName(String nameTemplate, Mode mode) {
+ return MessageFormat.format(nameTemplate, mode.toString().toLowerCase());
+ }
+
@Override
public String toString() {
StringBuilder sb = new StringBuilder();
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigBuilder.java b/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigBuilder.java
index 7571e6b..f11b04b 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigBuilder.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigBuilder.java
@@ -42,12 +42,12 @@ public class SSLConfigBuilder {
if (mode == SSLConfig.Mode.SERVER) {
sslConfig = new SSLConfigServer(config, hadoopConfig);
} else {
- sslConfig = new SSLConfigClient(properties);
+ sslConfig = new SSLConfigClient(properties, hadoopConfig);
}
- if(validateKeyStore){
+ if (validateKeyStore) {
sslConfig.validateKeyStore();
}
- if(initializeSSLContext){
+ if (initializeSSLContext) {
sslConfig.initContext();
}
return sslConfig;
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigClient.java b/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigClient.java
index 417f5ae..3b4f12b 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigClient.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigClient.java
@@ -23,6 +23,9 @@ 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 org.apache.hadoop.conf.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
@@ -32,9 +35,10 @@ import java.util.Properties;
public class SSLConfigClient extends SSLConfig {
- private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SSLConfigClient.class);
+ private static final Logger logger = LoggerFactory.getLogger(SSLConfigClient.class);
private final Properties properties;
+ private final Configuration hadoopConfig;
private final boolean userSslEnabled;
private final String trustStoreType;
private final String trustStorePath;
@@ -46,19 +50,22 @@ public class SSLConfigClient extends SSLConfig {
private final int handshakeTimeout;
private final String provider;
- private final String emptyString = new String();
+ private final String emptyString = "";
- public SSLConfigClient(Properties properties) throws DrillException {
+ public SSLConfigClient(Properties properties, Configuration hadoopConfig) throws DrillException {
this.properties = properties;
+ this.hadoopConfig = hadoopConfig;
userSslEnabled = getBooleanProperty(DrillProperties.ENABLE_TLS);
SSLCredentialsProvider credentialsProvider = SSLCredentialsProvider.getSSLCredentialsProvider(
this::getStringProperty,
- Mode.CLIENT,
+ this::getPasswordStringProperty,
+ getMode(),
getBooleanProperty(DrillProperties.USE_MAPR_SSL_CONFIG)
);
trustStoreType = credentialsProvider.getTrustStoreType(DrillProperties.TRUSTSTORE_TYPE, "JKS");
trustStorePath = credentialsProvider.getTrustStoreLocation(DrillProperties.TRUSTSTORE_PATH, "");
- trustStorePassword = credentialsProvider.getTrustStorePassword(DrillProperties.TRUSTSTORE_PASSWORD, "");
+ trustStorePassword = credentialsProvider.getTrustStorePassword(DrillProperties.TRUSTSTORE_PASSWORD,
+ resolveHadoopPropertyName(HADOOP_SSL_TRUSTSTORE_PASSWORD_TPL_KEY, getMode()));
disableHostVerification = getBooleanProperty(DrillProperties.DISABLE_HOST_VERIFICATION);
disableCertificateVerification = getBooleanProperty(DrillProperties.DISABLE_CERT_VERIFICATION);
useSystemTrustStore = getBooleanProperty(DrillProperties.USE_SYSTEM_TRUSTSTORE);
@@ -96,6 +103,15 @@ public class SSLConfigClient extends SSLConfig {
return value;
}
+ private String getPasswordStringProperty(String name, String hadoopName) {
+ String value = getPassword(hadoopName);
+
+ if (value == null) {
+ value = getStringProperty(name, "");
+ }
+ return value;
+ }
+
private int getIntProperty(String name, int defaultValue) {
int value = defaultValue;
if (properties != null) {
@@ -107,8 +123,8 @@ public class SSLConfigClient extends SSLConfig {
return value;
}
+ @Override
public void validateKeyStore() throws DrillException {
-
}
@Override
@@ -279,8 +295,13 @@ public class SSLConfigClient extends SSLConfig {
return useSystemTrustStore;
}
+ @Override
public boolean isSslValid() {
return true;
}
+ @Override
+ Configuration getHadoopConfig() {
+ return hadoopConfig;
+ }
}
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigServer.java b/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigServer.java
index 04fb3b6..e184a91 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigServer.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLConfigServer.java
@@ -26,16 +26,17 @@ import org.apache.drill.common.exceptions.DrillException;
import org.apache.drill.exec.ExecConstants;
import org.apache.drill.exec.memory.BufferAllocator;
import org.apache.hadoop.conf.Configuration;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLEngine;
import javax.net.ssl.TrustManagerFactory;
-import java.text.MessageFormat;
public class SSLConfigServer extends SSLConfig {
- private static final org.slf4j.Logger logger = org.slf4j.LoggerFactory.getLogger(SSLConfigServer.class);
+ private static final Logger logger = LoggerFactory.getLogger(SSLConfigServer.class);
private final DrillConfig config;
private final Configuration hadoopConfig;
@@ -76,6 +77,7 @@ public class SSLConfigServer extends SSLConfig {
config.hasPath(ExecConstants.USER_SSL_ENABLED) && config.getBoolean(ExecConstants.USER_SSL_ENABLED);
SSLCredentialsProvider credentialsProvider = SSLCredentialsProvider.getSSLCredentialsProvider(
this::getConfigParam,
+ this::getPasswordConfigParam,
Mode.SERVER,
config.getBoolean(ExecConstants.SSL_USE_MAPR_CONFIG));
trustStoreType = credentialsProvider.getTrustStoreType(
@@ -106,6 +108,7 @@ public class SSLConfigServer extends SSLConfig {
provider = config.getString(ExecConstants.SSL_PROVIDER);
}
+ @Override
public void validateKeyStore() throws DrillException {
//HTTPS validates the keystore is not empty. User Server SSL context initialization also validates keystore, but
// much more strictly. User Client context initialization does not validate keystore.
@@ -226,11 +229,15 @@ public class SSLConfigServer extends SSLConfig {
return value;
}
- private String resolveHadoopPropertyName(String nameTemplate, Mode mode) {
- return MessageFormat.format(nameTemplate, mode.toString().toLowerCase());
- }
+ private String getPasswordConfigParam(String name, String hadoopName) {
+ String value = getPassword(hadoopName);
+ if (value == null) {
+ value = getConfigParam(name, hadoopName);
+ }
+ return value;
+ }
@Override
public boolean isUserSslEnabled() {
@@ -322,8 +329,13 @@ public class SSLConfigServer extends SSLConfig {
return false; // Client only, notsupported by the server
}
+ @Override
public boolean isSslValid() {
return !keyStorePath.isEmpty() && !keyStorePassword.isEmpty();
}
+ @Override
+ Configuration getHadoopConfig() {
+ return hadoopConfig;
+ }
}
diff --git a/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLCredentialsProvider.java b/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLCredentialsProvider.java
index fd536f6..e2d0ced 100644
--- a/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLCredentialsProvider.java
+++ b/exec/java-exec/src/main/java/org/apache/drill/exec/ssl/SSLCredentialsProvider.java
@@ -43,14 +43,19 @@ abstract class SSLCredentialsProvider {
* <li>String parameter2 - default value</li>
* <li>returns the property value or default value</li>
* </ul>
+ * @param getPasswordPropertyMethod the same as {@code getPropertyMethod} but used to
+ * retrieve sensible data, such as keystore password,
+ * using Hadoop's CredentialProvider API with fallback
+ * to standard means as is used for {@code getPropertyMethod}
* @param mode CLIENT or SERVER
* @param useMapRSSLConfig use a MapR credential provider
* @return concrete implementation of SSLCredentialsProvider
*/
- static SSLCredentialsProvider getSSLCredentialsProvider(BiFunction<String, String, String> getPropertyMethod, SSLConfig.Mode mode, boolean useMapRSSLConfig) {
+ static SSLCredentialsProvider getSSLCredentialsProvider(BiFunction<String, String, String> getPropertyMethod,
+ BiFunction<String, String, String> getPasswordPropertyMethod, SSLConfig.Mode mode, boolean useMapRSSLConfig) {
return useMapRSSLConfig ? getMaprCredentialsProvider(mode)
- .orElseGet(() -> new SSLCredentialsProviderImpl(getPropertyMethod)) :
- new SSLCredentialsProviderImpl(getPropertyMethod);
+ .orElseGet(() -> new SSLCredentialsProviderImpl(getPropertyMethod, getPasswordPropertyMethod)) :
+ new SSLCredentialsProviderImpl(getPropertyMethod, getPasswordPropertyMethod);
}
private static Optional<SSLCredentialsProvider> getMaprCredentialsProvider(SSLConfig.Mode mode) {
@@ -95,9 +100,12 @@ abstract class SSLCredentialsProvider {
private static class SSLCredentialsProviderImpl extends SSLCredentialsProvider {
private final BiFunction<String, String, String> getPropertyMethod;
+ private final BiFunction<String, String, String> getPasswordPropertyMethod;
- private SSLCredentialsProviderImpl(BiFunction<String, String, String> getPropertyMethod) {
+ private SSLCredentialsProviderImpl(BiFunction<String, String, String> getPropertyMethod,
+ BiFunction<String, String, String> getPasswordPropertyMethod) {
this.getPropertyMethod = getPropertyMethod;
+ this.getPasswordPropertyMethod = getPasswordPropertyMethod;
}
@Override
@@ -112,7 +120,7 @@ abstract class SSLCredentialsProvider {
@Override
String getTrustStorePassword(String propertyName, String defaultValue) {
- return getPropertyMethod.apply(propertyName, defaultValue);
+ return getPasswordPropertyMethod.apply(propertyName, defaultValue);
}
@Override
@@ -127,12 +135,12 @@ abstract class SSLCredentialsProvider {
@Override
String getKeyStorePassword(String propertyName, String defaultValue) {
- return getPropertyMethod.apply(propertyName, defaultValue);
+ return getPasswordPropertyMethod.apply(propertyName, defaultValue);
}
@Override
String getKeyPassword(String propertyName, String defaultValue) {
- return getPropertyMethod.apply(propertyName, defaultValue);
+ return getPasswordPropertyMethod.apply(propertyName, defaultValue);
}
}
}