You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@impala.apache.org by ta...@apache.org on 2017/08/17 03:14:18 UTC

[02/15] incubator-impala git commit: IMPALA-5800: Configure Squeasel's cipher suite and TLS version

IMPALA-5800: Configure Squeasel's cipher suite and TLS version

* Import Squeasel as of
  https://github.com/cloudera/squeasel/commit/1e5f611, which adds TLS
  version and cipher suite configuration.

* Plumb through --ssl_minimum_version and --ssl_cipher_list to the
  Squeasel options in webserver.cc.

Testing: manually confirm that webserver connections have desired
protocol version and cipher suite. Add two tests to webserver-test to
check that misconfiguration leads to a failure.

Change-Id: I23fb17257098992c65e50c1e83a905c9a85db6a2
Reviewed-on: http://gerrit.cloudera.org:8080/7679
Reviewed-by: Sailesh Mukil <sa...@cloudera.com>
Reviewed-by: Henry Robinson <he...@cloudera.com>
Tested-by: Impala Public Jenkins


Project: http://git-wip-us.apache.org/repos/asf/incubator-impala/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-impala/commit/51ec6071
Tree: http://git-wip-us.apache.org/repos/asf/incubator-impala/tree/51ec6071
Diff: http://git-wip-us.apache.org/repos/asf/incubator-impala/diff/51ec6071

Branch: refs/heads/master
Commit: 51ec60713980bd6e64e626f4476e843c49f5ea48
Parents: b660bd6
Author: Henry Robinson <he...@cloudera.com>
Authored: Mon Aug 14 20:49:52 2017 -0700
Committer: Impala Public Jenkins <im...@gerrit.cloudera.org>
Committed: Thu Aug 17 01:51:15 2017 +0000

----------------------------------------------------------------------
 be/src/thirdparty/squeasel/squeasel.c | 34 ++++++++++++++++++++++---
 be/src/util/webserver-test.cc         | 40 ++++++++++++++++++++++++++++++
 be/src/util/webserver.cc              |  9 +++++++
 3 files changed, 80 insertions(+), 3 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/51ec6071/be/src/thirdparty/squeasel/squeasel.c
----------------------------------------------------------------------
diff --git a/be/src/thirdparty/squeasel/squeasel.c b/be/src/thirdparty/squeasel/squeasel.c
index 3d27d2d..3f957de 100644
--- a/be/src/thirdparty/squeasel/squeasel.c
+++ b/be/src/thirdparty/squeasel/squeasel.c
@@ -212,7 +212,7 @@ enum {
   GLOBAL_PASSWORDS_FILE, INDEX_FILES, ENABLE_KEEP_ALIVE, ACCESS_CONTROL_LIST,
   EXTRA_MIME_TYPES, LISTENING_PORTS, DOCUMENT_ROOT, SSL_CERTIFICATE, SSL_PRIVATE_KEY,
   SSL_PRIVATE_KEY_PASSWORD, SSL_GLOBAL_INIT, NUM_THREADS, RUN_AS_USER, REWRITE,
-  HIDE_FILES, REQUEST_TIMEOUT, NUM_OPTIONS
+  HIDE_FILES, REQUEST_TIMEOUT, SSL_VERSION, SSL_CIPHERS, NUM_OPTIONS
 };
 
 static const char *config_options[] = {
@@ -244,6 +244,8 @@ static const char *config_options[] = {
   "url_rewrite_patterns", NULL,
   "hide_files_patterns", NULL,
   "request_timeout_ms", "30000",
+  "ssl_min_version", "tlsv1",
+  "ssl_ciphers", NULL,
   NULL
 };
 
@@ -4139,6 +4141,9 @@ static int set_uid_option(struct sq_context *ctx) {
 }
 
 #if !defined(NO_SSL)
+
+#define OPENSSL_VERSION_HAS_TLS_1_1 0x10001000L
+
 static pthread_mutex_t *ssl_mutexes;
 
 static int sslize(struct sq_connection *conn, SSL_CTX *s, int (*func)(SSL *)) {
@@ -4215,7 +4220,23 @@ static int set_ssl_option(struct sq_context *ctx) {
     CRYPTO_set_id_callback(&ssl_id_callback);
   }
 
-  if ((ctx->ssl_ctx = SSL_CTX_new(SSLv23_server_method())) == NULL) {
+  char* ssl_version = ctx->config[SSL_VERSION];
+  int options = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
+  if (sq_strcasecmp(ssl_version, "tlsv1") == 0) {
+    // No-op - don't exclude any TLS protocols.
+#if OPENSSL_VERSION_NUMBER >= OPENSSL_VERSION_HAS_TLS_1_1
+  } else if (sq_strcasecmp(ssl_version, "tlsv1_1") == 0) {
+    options |= SSL_OP_NO_TLSv1;
+  } else if (sq_strcasecmp(ssl_version, "tlsv1_2") == 0) {
+    options |= (SSL_OP_NO_TLSv1 | SSL_OP_NO_TLSv1_1);
+#endif
+  } else {
+    cry(fc(ctx), "%s: unknown SSL version: %s", __func__, ssl_version);
+    return 0;
+  }
+
+  ctx->ssl_ctx = SSL_CTX_new(SSLv23_method());
+  if (ctx->ssl_ctx == NULL) {
     unsigned long err_code = ERR_peek_error();
     // If it looks like the error is due to SSL not being initialized,
     // provide a better error.
@@ -4230,7 +4251,7 @@ static int set_ssl_option(struct sq_context *ctx) {
     return 0;
   }
 
-  SSL_CTX_set_options(ctx->ssl_ctx, SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3);
+  SSL_CTX_set_options(ctx->ssl_ctx, options);
 
   if (ctx->config[SSL_PRIVATE_KEY_PASSWORD] != NULL) {
     SSL_CTX_set_default_passwd_cb(ctx->ssl_ctx, ssl_password_callback);
@@ -4251,6 +4272,13 @@ static int set_ssl_option(struct sq_context *ctx) {
     (void) SSL_CTX_use_certificate_chain_file(ctx->ssl_ctx, pem);
   }
 
+  if (ctx->config[SSL_CIPHERS] != NULL) {
+    if (SSL_CTX_set_cipher_list(ctx->ssl_ctx, ctx->config[SSL_CIPHERS]) == 0) {
+      cry(fc(ctx), "SSL_CTX_set_cipher_list: error setting ciphers (%s): %s",
+          ctx->config[SSL_CIPHERS], ssl_error());
+      return 0;
+    }
+  }
 
   return 1;
 }

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/51ec6071/be/src/util/webserver-test.cc
----------------------------------------------------------------------
diff --git a/be/src/util/webserver-test.cc b/be/src/util/webserver-test.cc
index 1abbe42..7abaa37 100644
--- a/be/src/util/webserver-test.cc
+++ b/be/src/util/webserver-test.cc
@@ -33,6 +33,8 @@ DECLARE_string(webserver_certificate_file);
 DECLARE_string(webserver_private_key_file);
 DECLARE_string(webserver_private_key_password_cmd);
 DECLARE_string(webserver_x_frame_options);
+DECLARE_string(ssl_cipher_list);
+DECLARE_string(ssl_minimum_version);
 
 #include "common/names.h"
 
@@ -246,6 +248,44 @@ TEST(Webserver, SslBadPrivateKeyPasswordTest) {
   ASSERT_FALSE(webserver.Start().ok());
 }
 
+TEST(Webserver, SslCipherSuite) {
+  auto cert = ScopedFlagSetter<string>::Make(&FLAGS_webserver_certificate_file,
+      Substitute("$0/be/src/testutil/server-cert.pem", getenv("IMPALA_HOME")));
+  auto key = ScopedFlagSetter<string>::Make(&FLAGS_webserver_private_key_file,
+      Substitute("$0/be/src/testutil/server-key-password.pem", getenv("IMPALA_HOME")));
+  auto cmd = ScopedFlagSetter<string>::Make(
+      &FLAGS_webserver_private_key_password_cmd, "echo password");
+
+  {
+    auto ciphers = ScopedFlagSetter<string>::Make(
+        &FLAGS_ssl_cipher_list, "not_a_cipher");
+    Webserver webserver(FLAGS_webserver_port);
+    ASSERT_FALSE(webserver.Start().ok());
+  }
+
+  {
+    auto ciphers = ScopedFlagSetter<string>::Make(
+        &FLAGS_ssl_cipher_list, "RC4-SHA");
+    Webserver webserver(FLAGS_webserver_port);
+    ASSERT_OK(webserver.Start());
+  }
+}
+
+TEST(Webserver, SslBadTlsVersion) {
+  auto cert = ScopedFlagSetter<string>::Make(&FLAGS_webserver_certificate_file,
+      Substitute("$0/be/src/testutil/server-cert.pem", getenv("IMPALA_HOME")));
+  auto key = ScopedFlagSetter<string>::Make(&FLAGS_webserver_private_key_file,
+      Substitute("$0/be/src/testutil/server-key-password.pem", getenv("IMPALA_HOME")));
+  auto cmd = ScopedFlagSetter<string>::Make(
+      &FLAGS_webserver_private_key_password_cmd, "echo password");
+
+  auto ssl_version = ScopedFlagSetter<string>::Make(
+      &FLAGS_ssl_minimum_version, "not_a_version");
+
+  Webserver webserver(FLAGS_webserver_port);
+  ASSERT_FALSE(webserver.Start().ok());
+}
+
 TEST(Webserver, StartWithPasswordFileTest) {
   stringstream password_file;
   password_file << getenv("IMPALA_HOME") << "/be/src/testutil/htpasswd";

http://git-wip-us.apache.org/repos/asf/incubator-impala/blob/51ec6071/be/src/util/webserver.cc
----------------------------------------------------------------------
diff --git a/be/src/util/webserver.cc b/be/src/util/webserver.cc
index ef96181..ea0a6e9 100644
--- a/be/src/util/webserver.cc
+++ b/be/src/util/webserver.cc
@@ -101,6 +101,8 @@ DEFINE_string(webserver_x_frame_options, "DENY",
     "webserver will add X-Frame-Options HTTP header with this value");
 
 DECLARE_bool(is_coordinator);
+DECLARE_string(ssl_minimum_version);
+DECLARE_string(ssl_cipher_list);
 
 static const char* DOC_FOLDER = "/www/";
 static const int DOC_FOLDER_LEN = strlen(DOC_FOLDER);
@@ -261,6 +263,13 @@ Status Webserver::Start() {
         options.push_back(key_password.c_str());
       }
     }
+
+    options.push_back("ssl_min_version");
+    options.push_back(FLAGS_ssl_minimum_version.c_str());
+    if (!FLAGS_ssl_cipher_list.empty()) {
+      options.push_back("ssl_ciphers");
+      options.push_back(FLAGS_ssl_cipher_list.c_str());
+    }
   }
 
   if (!FLAGS_webserver_authentication_domain.empty()) {