Repository: hive Updated Branches: refs/heads/branch-1.2 6a4a75680 -> ba641c15c
HIVE-10447 : Beeline JDBC Driver to support 2 way SSL (Hari Sankar Sivarama Subramaniyan via Thejas Nair) Project: http://git-wip-us.apache.org/repos/asf/hive/repo Commit: http://git-wip-us.apache.org/repos/asf/hive/commit/ba641c15 Tree: http://git-wip-us.apache.org/repos/asf/hive/tree/ba641c15 Diff: http://git-wip-us.apache.org/repos/asf/hive/diff/ba641c15 Branch: refs/heads/branch-1.2 Commit: ba641c15c4fd4a4d77b913d266ab7ddf55f99600 Parents: 6a4a756 Author: Thejas Nair <[email protected]> Authored: Mon Apr 27 11:03:44 2015 -0700 Committer: Thejas Nair <[email protected]> Committed: Mon Apr 27 11:05:06 2015 -0700 ---------------------------------------------------------------------- .../org/apache/hive/jdbc/HiveConnection.java | 61 ++++++++++++++++++-- jdbc/src/java/org/apache/hive/jdbc/Utils.java | 11 ++++ 2 files changed, 68 insertions(+), 4 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/hive/blob/ba641c15/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java ---------------------------------------------------------------------- diff --git a/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java b/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java index 7a674ab..2b4be7f 100644 --- a/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java +++ b/jdbc/src/java/org/apache/hive/jdbc/HiveConnection.java @@ -21,6 +21,7 @@ package org.apache.hive.jdbc; import java.io.FileInputStream; import java.io.IOException; import java.security.KeyStore; +import java.security.SecureRandom; import java.sql.Array; import java.sql.Blob; import java.sql.CallableStatement; @@ -47,6 +48,9 @@ import java.util.Properties; import java.util.concurrent.Executor; import java.util.concurrent.TimeUnit; +import javax.net.ssl.KeyManagerFactory; +import javax.net.ssl.SSLContext; +import javax.net.ssl.TrustManagerFactory; import javax.security.sasl.Sasl; import javax.security.sasl.SaslException; @@ -348,11 +352,13 @@ public class HiveConnection implements java.sql.Connection { httpClientBuilder.addInterceptorFirst(requestInterceptor); // Configure http client for SSL if (useSsl) { + String useTwoWaySSL = sessConfMap.get(JdbcConnectionParams.USE_TWO_WAY_SSL); String sslTrustStorePath = sessConfMap.get(JdbcConnectionParams.SSL_TRUST_STORE); String sslTrustStorePassword = sessConfMap.get( JdbcConnectionParams.SSL_TRUST_STORE_PASSWORD); KeyStore sslTrustStore; SSLSocketFactory socketFactory; + /** * The code within the try block throws: * 1. SSLInitializationException @@ -366,11 +372,13 @@ public class HiveConnection implements java.sql.Connection { * and throw a SQLException. */ try { - if (sslTrustStorePath == null || sslTrustStorePath.isEmpty()) { + if (useTwoWaySSL != null && + useTwoWaySSL.equalsIgnoreCase(JdbcConnectionParams.TRUE)) { + socketFactory = getTwoWaySSLSocketFactory(); + } else if (sslTrustStorePath == null || sslTrustStorePath.isEmpty()) { // Create a default socket factory based on standard JSSE trust material socketFactory = SSLSocketFactory.getSocketFactory(); - } - else { + } else { // Pick trust store config from the given path sslTrustStore = KeyStore.getInstance(JdbcConnectionParams.SSL_TRUST_STORE_TYPE); sslTrustStore.load(new FileInputStream(sslTrustStorePath), @@ -451,7 +459,9 @@ public class HiveConnection implements java.sql.Connection { if (isSslConnection()) { // get SSL socket String sslTrustStore = sessConfMap.get(JdbcConnectionParams.SSL_TRUST_STORE); - String sslTrustStorePassword = sessConfMap.get(JdbcConnectionParams.SSL_TRUST_STORE_PASSWORD); + String sslTrustStorePassword = sessConfMap.get( + JdbcConnectionParams.SSL_TRUST_STORE_PASSWORD); + if (sslTrustStore == null || sslTrustStore.isEmpty()) { transport = HiveAuthFactory.getSSLSocket(host, port, loginTimeout); } else { @@ -477,6 +487,49 @@ public class HiveConnection implements java.sql.Connection { return transport; } + SSLSocketFactory getTwoWaySSLSocketFactory() throws SQLException { + SSLSocketFactory socketFactory = null; + + try { + KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance( + JdbcConnectionParams.SUNX509_ALGORITHM_STRING, + JdbcConnectionParams.SUNJSSE_ALGORITHM_STRING); + String keyStorePath = sessConfMap.get(JdbcConnectionParams.SSL_KEY_STORE); + String keyStorePassword = sessConfMap.get(JdbcConnectionParams.SSL_KEY_STORE_PASSWORD); + KeyStore sslKeyStore = KeyStore.getInstance(JdbcConnectionParams.SSL_KEY_STORE_TYPE); + + if (keyStorePath == null || keyStorePath.isEmpty()) { + throw new IllegalArgumentException(JdbcConnectionParams.SSL_KEY_STORE + + " Not configured for 2 way SSL connection, keyStorePath param is empty"); + } + sslKeyStore.load(new FileInputStream(keyStorePath), + keyStorePassword.toCharArray()); + keyManagerFactory.init(sslKeyStore, keyStorePassword.toCharArray()); + + TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance( + JdbcConnectionParams.SUNX509_ALGORITHM_STRING); + String trustStorePath = sessConfMap.get(JdbcConnectionParams.SSL_TRUST_STORE); + String trustStorePassword = sessConfMap.get( + JdbcConnectionParams.SSL_TRUST_STORE_PASSWORD); + KeyStore sslTrustStore = KeyStore.getInstance(JdbcConnectionParams.SSL_TRUST_STORE_TYPE); + + if (trustStorePath == null || trustStorePath.isEmpty()) { + throw new IllegalArgumentException(JdbcConnectionParams.SSL_TRUST_STORE + + " Not configured for 2 way SSL connection"); + } + sslTrustStore.load(new FileInputStream(trustStorePath), + trustStorePassword.toCharArray()); + trustManagerFactory.init(sslTrustStore); + SSLContext context = SSLContext.getInstance("TLS"); + context.init(keyManagerFactory.getKeyManagers(), + trustManagerFactory.getTrustManagers(), new SecureRandom()); + socketFactory = new SSLSocketFactory(context); + } catch (Exception e) { + throw new SQLException("Error while initializing 2 way ssl socket factory ", e); + } + return socketFactory; + } + // Lookup the delegation token. First in the connection URL, then Configuration private String getClientDelegationToken(Map<String, String> jdbcConnConf) throws SQLException { http://git-wip-us.apache.org/repos/asf/hive/blob/ba641c15/jdbc/src/java/org/apache/hive/jdbc/Utils.java ---------------------------------------------------------------------- diff --git a/jdbc/src/java/org/apache/hive/jdbc/Utils.java b/jdbc/src/java/org/apache/hive/jdbc/Utils.java index 04bba06..0e4693b 100644 --- a/jdbc/src/java/org/apache/hive/jdbc/Utils.java +++ b/jdbc/src/java/org/apache/hive/jdbc/Utils.java @@ -113,6 +113,17 @@ public class Utils { // The http header prefix for additional headers which have to be appended to the request static final String HTTP_HEADER_PREFIX = "http.header."; + // --------------- Begin 2 way ssl options ------------------------- + // Use two way ssl. This param will take effect only when ssl=true + static final String USE_TWO_WAY_SSL = "twoWay"; + static final String TRUE = "true"; + static final String SSL_KEY_STORE = "sslKeyStore"; + static final String SSL_KEY_STORE_PASSWORD = "keyStorePassword"; + static final String SSL_KEY_STORE_TYPE = "JKS"; + static final String SUNX509_ALGORITHM_STRING = "SunX509"; + static final String SUNJSSE_ALGORITHM_STRING = "SunJSSE"; + // --------------- End 2 way ssl options ---------------------------- + // Non-configurable params: // Currently supports JKS keystore format static final String SSL_TRUST_STORE_TYPE = "JKS";
