You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@hive.apache.org by ga...@apache.org on 2014/11/05 01:44:36 UTC

svn commit: r1636787 - in /hive/trunk: common/src/java/org/apache/hadoop/hive/conf/ itests/hive-unit/src/main/java/org/apache/hive/jdbc/miniHS2/ itests/hive-unit/src/test/java/org/apache/hive/jdbc/ service/src/java/org/apache/hive/service/auth/ service...

Author: gates
Date: Wed Nov  5 00:44:35 2014
New Revision: 1636787

URL: http://svn.apache.org/r1636787
Log:
HIVE-8765 Increase thrift server protocol test coverage (Brock Noland, reviewed by Alan Gates)

Modified:
    hive/trunk/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
    hive/trunk/itests/hive-unit/src/main/java/org/apache/hive/jdbc/miniHS2/AbstractHiveService.java
    hive/trunk/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestSSL.java
    hive/trunk/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java
    hive/trunk/service/src/java/org/apache/hive/service/cli/thrift/ThriftBinaryCLIService.java
    hive/trunk/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpCLIService.java

Modified: hive/trunk/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java
URL: http://svn.apache.org/viewvc/hive/trunk/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java?rev=1636787&r1=1636786&r2=1636787&view=diff
==============================================================================
--- hive/trunk/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java (original)
+++ hive/trunk/common/src/java/org/apache/hadoop/hive/conf/HiveConf.java Wed Nov  5 00:44:35 2014
@@ -1589,6 +1589,9 @@ public class HiveConf extends Configurat
         "table. From 0.12 onwards, they are displayed separately. This flag will let you\n" +
         "get old behavior, if desired. See, test-case in patch for HIVE-6689."),
 
+    HIVE_SSL_PROTOCOL_BLACKLIST("hive.ssl.protocol.blacklist", "SSLv2,SSLv2Hello,SSLv3",
+        "SSL Versions to disable for all Hive Servers"),
+
      // HiveServer2 specific configs
     HIVE_SERVER2_MAX_START_ATTEMPTS("hive.server2.max.start.attempts", 30L, new RangeValidator(0L, null),
         "Number of times HiveServer2 will attempt to start before exiting, sleeping 60 seconds " +

Modified: hive/trunk/itests/hive-unit/src/main/java/org/apache/hive/jdbc/miniHS2/AbstractHiveService.java
URL: http://svn.apache.org/viewvc/hive/trunk/itests/hive-unit/src/main/java/org/apache/hive/jdbc/miniHS2/AbstractHiveService.java?rev=1636787&r1=1636786&r2=1636787&view=diff
==============================================================================
--- hive/trunk/itests/hive-unit/src/main/java/org/apache/hive/jdbc/miniHS2/AbstractHiveService.java (original)
+++ hive/trunk/itests/hive-unit/src/main/java/org/apache/hive/jdbc/miniHS2/AbstractHiveService.java Wed Nov  5 00:44:35 2014
@@ -106,7 +106,7 @@ public abstract class AbstractHiveServic
   }
 
   // get service host
-  protected String getHost() {
+  public String getHost() {
     return hostname;
   }
 
@@ -127,12 +127,12 @@ public abstract class AbstractHiveServic
   }
 
   // Get binary service port #
-  protected int getBinaryPort() {
+  public int getBinaryPort() {
     return binaryPort;
   }
 
   // Get http service port #
-  protected int getHttpPort() {
+  public int getHttpPort() {
     return httpPort;
   }
 

Modified: hive/trunk/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestSSL.java
URL: http://svn.apache.org/viewvc/hive/trunk/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestSSL.java?rev=1636787&r1=1636786&r2=1636787&view=diff
==============================================================================
--- hive/trunk/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestSSL.java (original)
+++ hive/trunk/itests/hive-unit/src/test/java/org/apache/hive/jdbc/TestSSL.java Wed Nov  5 00:44:35 2014
@@ -31,15 +31,21 @@ import java.util.HashMap;
 import java.util.Map;
 
 import org.apache.hadoop.fs.Path;
+import org.apache.hadoop.util.Shell;
 import org.apache.hadoop.hive.conf.HiveConf;
 import org.apache.hadoop.hive.conf.HiveConf.ConfVars;
 import org.apache.hive.jdbc.miniHS2.MiniHS2;
 import org.junit.After;
+import org.junit.Assert;
+import org.junit.Assume;
 import org.junit.Before;
 import org.junit.BeforeClass;
 import org.junit.Test;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 public class TestSSL {
+  private static final Logger LOG = LoggerFactory.getLogger(TestSSL.class);
   private static final String KEY_STORE_NAME = "keystore.jks";
   private static final String TRUST_STORE_NAME = "truststore.jks";
   private static final String KEY_STORE_PASSWORD = "HiveJdbc";
@@ -87,6 +93,73 @@ public class TestSSL {
     System.clearProperty(JAVA_TRUST_STORE_PASS_PROP);
   }
 
+  private int execCommand(String cmd) throws Exception {
+    int exitCode;
+    try {
+      String output = Shell.execCommand("bash", "-c", cmd);
+      LOG.info("Output from '" + cmd + "': " + output) ;
+      exitCode = 0;
+    } catch (Shell.ExitCodeException e) {
+      exitCode = e.getExitCode();
+      LOG.info("Error executing '" + cmd + "', exitCode = " + exitCode, e);
+    }
+    return exitCode;
+  }
+
+  /***
+   * Tests to ensure SSLv2 and SSLv3 are disabled
+   */
+  @Test
+  public void testSSLVersion() throws Exception {
+    Assume.assumeTrue(execCommand("which openssl") == 0); // we need openssl
+    Assume.assumeTrue(System.getProperty("os.name").toLowerCase()
+      .contains("linux")); // we depend on linux openssl exit codes
+
+    setSslConfOverlay(confOverlay);
+    // Test in binary mode
+    setBinaryConfOverlay(confOverlay);
+    // Start HS2 with SSL
+    miniHS2.start(confOverlay);
+
+    // make SSL connection
+    hs2Conn = DriverManager.getConnection(miniHS2.getJdbcURL() + ";ssl=true;sslTrustStore=" +
+        dataFileDir + File.separator + TRUST_STORE_NAME + ";trustStorePassword=" +
+        KEY_STORE_PASSWORD, System.getProperty("user.name"), "bar");
+    hs2Conn.close();
+    Assert.assertEquals("Expected exit code of 1", 1,
+      execCommand("openssl s_client -connect " + miniHS2.getHost() + ":" + miniHS2.getBinaryPort()
+      + " -ssl2 < /dev/null"));
+    Assert.assertEquals("Expected exit code of 1", 1,
+      execCommand("openssl s_client -connect " + miniHS2.getHost() + ":" + miniHS2.getBinaryPort()
+      + " -ssl3 < /dev/null"));
+    miniHS2.stop();
+
+    // Test in http mode
+    setHttpConfOverlay(confOverlay);
+    miniHS2.start(confOverlay);
+    // make SSL connection
+    try {
+      hs2Conn = DriverManager.getConnection(miniHS2.getJdbcURL() +
+          ";ssl=true;sslTrustStore=" + dataFileDir + File.separator +
+          TRUST_STORE_NAME + ";trustStorePassword=" + KEY_STORE_PASSWORD +
+          "?hive.server2.transport.mode=" + HS2_HTTP_MODE +
+          ";hive.server2.thrift.http.path=" + HS2_HTTP_ENDPOINT,
+          System.getProperty("user.name"), "bar");
+      Assert.fail("Expected SQLException during connect");
+    } catch (SQLException e) {
+      LOG.info("Expected exception: " + e, e);
+      Assert.assertEquals("08S01", e.getSQLState().trim());
+      Throwable cause = e.getCause();
+      Assert.assertNotNull(cause);
+      while (cause.getCause() != null) {
+        cause = cause.getCause();
+      }
+      Assert.assertEquals("org.apache.http.NoHttpResponseException", cause.getClass().getName());
+      Assert.assertEquals("The target server failed to respond", cause.getMessage());
+    }
+    miniHS2.stop();
+  }
+
   /***
    * Test SSL client with non-SSL server fails
    * @throws Exception

Modified: hive/trunk/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java
URL: http://svn.apache.org/viewvc/hive/trunk/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java?rev=1636787&r1=1636786&r2=1636787&view=diff
==============================================================================
--- hive/trunk/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java (original)
+++ hive/trunk/service/src/java/org/apache/hive/service/auth/HiveAuthFactory.java Wed Nov  5 00:44:35 2014
@@ -21,9 +21,13 @@ import java.io.IOException;
 import java.net.InetAddress;
 import java.net.InetSocketAddress;
 import java.net.UnknownHostException;
+import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.HashMap;
+import java.util.List;
 import java.util.Map;
 
+import javax.net.ssl.SSLServerSocket;
 import javax.security.auth.login.LoginException;
 import javax.security.sasl.Sasl;
 
@@ -43,12 +47,16 @@ import org.apache.thrift.transport.TSock
 import org.apache.thrift.transport.TTransport;
 import org.apache.thrift.transport.TTransportException;
 import org.apache.thrift.transport.TTransportFactory;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
 
 /**
  * This class helps in some aspects of authentication. It creates the proper Thrift classes for the
  * given configuration as well as helps with authenticating requests.
  */
 public class HiveAuthFactory {
+  private static final Logger LOG = LoggerFactory.getLogger(HiveAuthFactory.class);
+
 
   public enum AuthTypes {
     NOSASL("NOSASL"),
@@ -218,7 +226,8 @@ public class HiveAuthFactory {
   }
 
   public static TServerSocket getServerSSLSocket(String hiveHost, int portNum, String keyStorePath,
-    String keyStorePassWord) throws TTransportException, UnknownHostException {
+    String keyStorePassWord,  List<String> sslVersionBlacklist)
+      throws TTransportException, UnknownHostException {
     TSSLTransportFactory.TSSLTransportParameters params =
       new TSSLTransportFactory.TSSLTransportParameters();
     params.setKeyStore(keyStorePath, keyStorePassWord);
@@ -229,7 +238,25 @@ public class HiveAuthFactory {
     } else {
       serverAddress = InetAddress.getByName(hiveHost);
     }
-    return TSSLTransportFactory.getServerSocket(portNum, 0, serverAddress, params);
+    TServerSocket thriftServerSocket = TSSLTransportFactory.getServerSocket(portNum, 0, serverAddress, params);
+    if (thriftServerSocket.getServerSocket() instanceof SSLServerSocket) {
+      List<String> sslVersionBlacklistLocal = new ArrayList<String>();
+      for (String sslVersion : sslVersionBlacklist) {
+        sslVersionBlacklistLocal.add(sslVersion.trim().toLowerCase());
+      }
+      SSLServerSocket sslServerSocket = (SSLServerSocket)thriftServerSocket.getServerSocket();
+      List<String> enabledProtocols = new ArrayList<String>();
+      for (String protocol : sslServerSocket.getEnabledProtocols()) {
+        if (sslVersionBlacklistLocal.contains(protocol.toLowerCase())) {
+          LOG.debug("Disabling SSL Protocol: " + protocol);
+        } else {
+          enabledProtocols.add(protocol);
+        }
+      }
+      sslServerSocket.setEnabledProtocols(enabledProtocols.toArray(new String[0]));
+      LOG.info("SSL Server Socket Enabled Protocols: " + Arrays.toString(sslServerSocket.getEnabledProtocols()));
+    }
+    return thriftServerSocket;
   }
 
   // retrieve delegation token for the given user

Modified: hive/trunk/service/src/java/org/apache/hive/service/cli/thrift/ThriftBinaryCLIService.java
URL: http://svn.apache.org/viewvc/hive/trunk/service/src/java/org/apache/hive/service/cli/thrift/ThriftBinaryCLIService.java?rev=1636787&r1=1636786&r2=1636787&view=diff
==============================================================================
--- hive/trunk/service/src/java/org/apache/hive/service/cli/thrift/ThriftBinaryCLIService.java (original)
+++ hive/trunk/service/src/java/org/apache/hive/service/cli/thrift/ThriftBinaryCLIService.java Wed Nov  5 00:44:35 2014
@@ -18,6 +18,8 @@
 
 package org.apache.hive.service.cli.thrift;
 
+import java.util.ArrayList;
+import java.util.List;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.SynchronousQueue;
 import java.util.concurrent.ThreadPoolExecutor;
@@ -56,6 +58,10 @@ public class ThriftBinaryCLIService exte
       TTransportFactory transportFactory = hiveAuthFactory.getAuthTransFactory();
       TProcessorFactory processorFactory = hiveAuthFactory.getAuthProcFactory(this);
       TServerSocket serverSocket = null;
+      List<String> sslVersionBlacklist = new ArrayList<String>();
+      for (String sslVersion : hiveConf.getVar(ConfVars.HIVE_SSL_PROTOCOL_BLACKLIST).split(",")) {
+        sslVersionBlacklist.add(sslVersion);
+      }
       if (!hiveConf.getBoolVar(ConfVars.HIVE_SERVER2_USE_SSL)) {
         serverSocket = HiveAuthFactory.getServerSocket(hiveHost, portNum);
       } else {
@@ -67,7 +73,7 @@ public class ThriftBinaryCLIService exte
         String keyStorePassword = ShimLoader.getHadoopShims().getPassword(hiveConf,
             HiveConf.ConfVars.HIVE_SERVER2_SSL_KEYSTORE_PASSWORD.varname);
         serverSocket = HiveAuthFactory.getServerSSLSocket(hiveHost, portNum, keyStorePath,
-            keyStorePassword);
+            keyStorePassword, sslVersionBlacklist);
       }
 
       // Server args

Modified: hive/trunk/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpCLIService.java
URL: http://svn.apache.org/viewvc/hive/trunk/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpCLIService.java?rev=1636787&r1=1636786&r2=1636787&view=diff
==============================================================================
--- hive/trunk/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpCLIService.java (original)
+++ hive/trunk/service/src/java/org/apache/hive/service/cli/thrift/ThriftHttpCLIService.java Wed Nov  5 00:44:35 2014
@@ -18,6 +18,7 @@
 
 package org.apache.hive.service.cli.thrift;
 
+import java.util.Arrays;
 import java.util.concurrent.ExecutorService;
 import java.util.concurrent.LinkedBlockingQueue;
 import java.util.concurrent.ThreadPoolExecutor;
@@ -83,6 +84,11 @@ public class ThriftHttpCLIService extend
               + " Not configured for SSL connection");
         }
         SslContextFactory sslContextFactory = new SslContextFactory();
+        String[] excludedProtocols = hiveConf.getVar(ConfVars.HIVE_SSL_PROTOCOL_BLACKLIST).split(",");
+        LOG.info("HTTP Server SSL: adding excluded protocols: " + Arrays.toString(excludedProtocols));
+        sslContextFactory.addExcludeProtocols(excludedProtocols);
+        LOG.info("HTTP Server SSL: SslContextFactory.getExcludeProtocols = " +
+          Arrays.toString(sslContextFactory.getExcludeProtocols()));
         sslContextFactory.setKeyStorePath(keyStorePath);
         sslContextFactory.setKeyStorePassword(keyStorePassword);
         connector = new SslSelectChannelConnector(sslContextFactory);