]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: suppress logs that can leak customer key
authorAdam Kupczyk <akupczyk@mirantis.com>
Fri, 3 Mar 2017 15:08:32 +0000 (16:08 +0100)
committerAdam Kupczyk <akupczyk@mirantis.com>
Wed, 5 Apr 2017 16:31:58 +0000 (18:31 +0200)
Signed-off-by: Adam Kupczyk <akupczyk@mirantis.com>
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
12 files changed:
src/common/config_opts.h
src/rgw/CMakeLists.txt
src/rgw/rgw_civetweb_log.cc
src/rgw/rgw_client_io.cc
src/rgw/rgw_common.cc
src/rgw/rgw_crypt.h
src/rgw/rgw_crypt_sanitize.cc [new file with mode: 0644]
src/rgw/rgw_crypt_sanitize.h [new file with mode: 0644]
src/rgw/rgw_env.cc
src/rgw/rgw_policy_s3.cc
src/rgw/rgw_rest_client.cc
src/rgw/rgw_rest_s3.cc

index bed890bf8c04a262e15738113c384b96826ac24d..0e89c15021fee2921a391a876ae935a91d7aa41e 100644 (file)
@@ -1661,7 +1661,7 @@ OPTION(rgw_crypt_require_ssl, OPT_BOOL, true) // requests including encryption k
 OPTION(rgw_crypt_default_encryption_key, OPT_STR, "") // base64 encoded key for encryption of rgw objects
 OPTION(rgw_crypt_s3_kms_encryption_keys, OPT_STR, "") // extra keys that may be used for aws:kms
                                                       // defined as map "key1=YmluCmJvb3N0CmJvb3N0LQ== key2=b3V0CnNyYwpUZXN0aW5nCg=="
-
+OPTION(rgw_crypt_suppress_logs, OPT_BOOL, true)   // suppress logs that might print customer key
 OPTION(rgw_list_bucket_min_readahead, OPT_INT, 1000) // minimum number of entries to read from rados for bucket listing
 
 OPTION(rgw_rest_getusage_op_compat, OPT_BOOL, false) // dump description of total stats for s3 GetUsage API
index e0fd6213b0d7ac306eb1155ce3e596a6f4bc2a8d..583b3531cdbcefc35df34acbe38637a00b13e7d6 100644 (file)
@@ -102,7 +102,8 @@ set(rgw_a_srcs
   rgw_xml.cc
   rgw_xml_enc.cc
   rgw_torrent.cc
-  rgw_crypt.cc)
+  rgw_crypt.cc
+  rgw_crypt_sanitize.cc)
 
 if (WITH_RADOSGW_FCGI_FRONTEND)
   list(APPEND rgw_a_srcs rgw_fcgi.cc)
index a01094d5c9766b519f3506f5a6f48949dc36b832..2c2e9ccfdd351da1aa65192999825ff7bd0e20a6 100644 (file)
@@ -2,18 +2,19 @@
 #include "rgw_common.h"
 
 #include "civetweb/civetweb.h"
+#include "rgw_crypt_sanitize.h"
 
 #define dout_subsys ceph_subsys_civetweb
 
 
 #define dout_context g_ceph_context
 int rgw_civetweb_log_callback(const struct mg_connection *conn, const char *buf) {
-  dout(0) << "civetweb: " << (void *)conn << ": " << buf << dendl;
+  dout(0) << "civetweb: " << (void *)conn << ": " << rgw::crypt_sanitize::log_content(buf) << dendl;
   return 0;
 }
 
 int rgw_civetweb_log_access_callback(const struct mg_connection *conn, const char *buf) {
-  dout(1) << "civetweb: " << (void *)conn << ": " << buf << dendl;
+  dout(1) << "civetweb: " << (void *)conn << ": " << rgw::crypt_sanitize::log_content(buf) << dendl;
   return 0;
 }
 
index e1dcb02e94fe522b446a17ed30fc33c6e0a44f3d..8eaaa58b21a7122d002bd6dfca9b82272ba5e355 100644 (file)
@@ -6,7 +6,8 @@
 #include <stdarg.h>
 
 #include "rgw_client_io.h"
-
+#include "rgw_crypt.h"
+#include "rgw_crypt_sanitize.h"
 #define dout_subsys ceph_subsys_rgw
 
 namespace rgw {
@@ -19,7 +20,8 @@ void BasicClient::init(CephContext *cct) {
     const auto& env_map = get_env().get_map();
 
     for (const auto& iter: env_map) {
-      ldout(cct, 20) << iter.first << "=" << iter.second << dendl;
+      rgw::crypt_sanitize::env x{iter->first, iter->second};
+      ldout(cct, 20) << iter->first << "=" << (x) << dendl;
     }
   }
 }
index d4888374a1c3e8235e8ab39680571489b26e2967..72422f7991459b07abeb064f51fedfcf9cb90830 100644 (file)
@@ -25,6 +25,7 @@
 #include "common/strtol.h"
 #include "include/str_list.h"
 #include "auth/Crypto.h"
+#include "rgw_crypt_sanitize.h"
 
 #include <sstream>
 
@@ -288,7 +289,7 @@ void req_info::init_meta_info(bool *found_bad_meta)
     }
   }
   for (iter = x_meta_map.begin(); iter != x_meta_map.end(); ++iter) {
-    dout(10) << "x>> " << iter->first << ":" << iter->second << dendl;
+    dout(10) << "x>> " << iter->first << ":" << rgw::crypt_sanitize::x_meta_map{iter->first, iter->second} << dendl;
   }
 }
 
index 666b98db4e6daa537942003ac0dabaa1ccdbcf76..2ea22f08da4eaed5f58846d6565aae42c7bd0ff0 100644 (file)
@@ -9,6 +9,7 @@
 #include <rgw/rgw_op.h>
 #include <rgw/rgw_rest_s3.h>
 #include <boost/utility/string_ref.hpp>
+
 /**
  * \brief Interface for block encryption methods
  *
diff --git a/src/rgw/rgw_crypt_sanitize.cc b/src/rgw/rgw_crypt_sanitize.cc
new file mode 100644 (file)
index 0000000..402c563
--- /dev/null
@@ -0,0 +1,89 @@
+/*
+ * rgw_crypt_sanitize.cc
+ *
+ *  Created on: Mar 3, 2017
+ *      Author: adam
+ */
+
+#include "rgw_common.h"
+#include "rgw_crypt_sanitize.h"
+#include "boost/algorithm/string/predicate.hpp"
+
+namespace rgw {
+namespace crypt_sanitize {
+const char* HTTP_X_AMZ_SERVER_SIDE_ENCRYPTION_CUSTOMER_KEY = "HTTP_X_AMZ_SERVER_SIDE_ENCRYPTION_CUSTOMER_KEY";
+const char* x_amz_server_side_encryption_customer_key = "x-amz-server-side-encryption-customer-key";
+const char* dollar_x_amz_server_side_encryption_customer_key = "$x-amz-server-side-encryption-customer-key";
+const char* suppression_message = "=suppressed due to key presence=";
+}
+}
+
+namespace std {
+std::ostream& operator<<(std::ostream& out, const rgw::crypt_sanitize::env& e) {
+  if (g_ceph_context->_conf->rgw_crypt_suppress_logs) {
+    if (boost::algorithm::iequals(
+        e.name,
+        rgw::crypt_sanitize::HTTP_X_AMZ_SERVER_SIDE_ENCRYPTION_CUSTOMER_KEY))
+    {
+      out << rgw::crypt_sanitize::suppression_message;
+      return out;
+    }
+    if (boost::algorithm::iequals(e.name, "QUERY_STRING") &&
+        boost::algorithm::ifind_first(
+            e.value,
+            rgw::crypt_sanitize::x_amz_server_side_encryption_customer_key))
+    {
+      out << rgw::crypt_sanitize::suppression_message;
+      return out;
+    }
+  }
+  out << e.value;
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const rgw::crypt_sanitize::x_meta_map& x) {
+  if (g_ceph_context->_conf->rgw_crypt_suppress_logs &&
+      boost::algorithm::iequals(x.name, rgw::crypt_sanitize::x_amz_server_side_encryption_customer_key))
+  {
+    out << rgw::crypt_sanitize::suppression_message;
+    return out;
+  }
+  out << x.value;
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const rgw::crypt_sanitize::s3_policy& x) {
+  if (g_ceph_context->_conf->rgw_crypt_suppress_logs &&
+      boost::algorithm::iequals(x.name, rgw::crypt_sanitize::dollar_x_amz_server_side_encryption_customer_key))
+  {
+    out << rgw::crypt_sanitize::suppression_message;
+    return out;
+  }
+  out << x.value;
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const rgw::crypt_sanitize::auth& x) {
+  if (g_ceph_context->_conf->rgw_crypt_suppress_logs &&
+      x.s->info.env->get(rgw::crypt_sanitize::HTTP_X_AMZ_SERVER_SIDE_ENCRYPTION_CUSTOMER_KEY, nullptr) != nullptr)
+  {
+    out << rgw::crypt_sanitize::suppression_message;
+    return out;
+  }
+  out << x.value;
+  return out;
+}
+
+std::ostream& operator<<(std::ostream& out, const rgw::crypt_sanitize::log_content& x) {
+  if (g_ceph_context->_conf->rgw_crypt_suppress_logs &&
+       strstr(x.buf, rgw::crypt_sanitize::x_amz_server_side_encryption_customer_key) != nullptr) {
+    out << rgw::crypt_sanitize::suppression_message;
+    return out;
+  }
+  out << x.buf;
+  return out;
+}
+
+
+
+}
diff --git a/src/rgw/rgw_crypt_sanitize.h b/src/rgw/rgw_crypt_sanitize.h
new file mode 100644 (file)
index 0000000..095b934
--- /dev/null
@@ -0,0 +1,58 @@
+// -*- mode:C; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
+// vim: ts=8 sw=2 smarttab
+
+#ifndef RGW_RGW_CRYPT_SANITIZE_H_
+#define RGW_RGW_CRYPT_SANITIZE_H_
+
+#include "rgw_common.h"
+
+namespace rgw {
+namespace crypt_sanitize {
+
+
+struct env {
+  boost::string_ref name;
+  boost::string_ref value;
+
+  env(boost::string_ref name, boost::string_ref value)
+  : name(name), value(value) {}
+};
+
+struct x_meta_map {
+  boost::string_ref name;
+  boost::string_ref value;
+  x_meta_map(boost::string_ref name, boost::string_ref value)
+  : name(name), value(value) {}
+};
+
+struct s3_policy {
+  boost::string_ref name;
+  boost::string_ref value;
+  s3_policy(boost::string_ref name, boost::string_ref value)
+  : name(name), value(value) {}
+};
+
+struct auth {
+  const req_state* const s;
+  boost::string_ref value;
+  auth(const req_state* const s, boost::string_ref value)
+  : s(s), value(value) {}
+};
+
+struct log_content {
+  const char* buf;
+  log_content(const char* buf)
+  : buf(buf) {}
+};
+
+}
+}
+
+namespace std {
+std::ostream& operator<<(std::ostream& out, const rgw::crypt_sanitize::env& e);
+std::ostream& operator<<(std::ostream& out, const rgw::crypt_sanitize::x_meta_map& x);
+std::ostream& operator<<(std::ostream& out, const rgw::crypt_sanitize::s3_policy& x);
+std::ostream& operator<<(std::ostream& out, const rgw::crypt_sanitize::auth& x);
+std::ostream& operator<<(std::ostream& out, const rgw::crypt_sanitize::log_content& x);
+}
+#endif /* RGW_RGW_CRYPT_SANITIZE_H_ */
index 183ce6a63fc5ee2b6915ec048ccae4630a19e930..737cda4cc975af9691966fe160ea78a6fd7910e9 100644 (file)
@@ -7,6 +7,7 @@
 #include <string>
 #include <map>
 #include "include/assert.h"
+#include "rgw_crypt_sanitize.h"
 
 #define dout_context g_ceph_context
 #define dout_subsys ceph_subsys_rgw
index c2f87547edcd0f6406015573d4104c3f425067e6..130943603ab3fc2fa2b39762aff502db34b7d636 100644 (file)
@@ -6,7 +6,7 @@
 #include "common/ceph_json.h"
 #include "rgw_policy_s3.h"
 #include "rgw_common.h"
-
+#include "rgw_crypt_sanitize.h"
 
 #define dout_context g_ceph_context
 #define dout_subsys ceph_subsys_rgw
@@ -30,8 +30,11 @@ public:
      string first, second;
      env->get_value(v1, first, checked_vars);
      env->get_value(v2, second, checked_vars);
-
-     dout(1) << "policy condition check " << v1 << " [" << first << "] " << v2 << " [" << second << "]" << dendl;
+     dout(1) << "policy condition check " << v1 << " ["
+         << rgw::crypt_sanitize::s3_policy{v1, first}
+         << "] " << v2 << " ["
+         << rgw::crypt_sanitize::s3_policy{v2, second}
+         << "]" << dendl;
      bool ret = check(first, second, err_msg);
      if (!ret) {
        err_msg.append(": ");
index b7cda4df7e6522a41f28f44d50c48313e605078d..ba3363cbd0499b0f6ec63da71728e40464fe93fb 100644 (file)
@@ -11,6 +11,7 @@
 #include "common/armor.h"
 #include "common/strtol.h"
 #include "include/str_list.h"
+#include "rgw_crypt_sanitize.h"
 
 #define dout_context g_ceph_context
 #define dout_subsys ceph_subsys_rgw
@@ -219,7 +220,7 @@ int RGWRESTSimpleRequest::sign_request(RGWAccessKey& key, RGWEnv& env, req_info&
   if (cct->_conf->subsys.should_gather(ceph_subsys_rgw, 20)) {
     map<string, string>::iterator i;
     for (i = m.begin(); i != m.end(); ++i) {
-      ldout(cct, 20) << "> " << i->first << " -> " << i->second << dendl;
+      ldout(cct, 20) << "> " << i->first << " -> " << rgw::crypt_sanitize::x_meta_map{i->first, i->second} << dendl;
     }
   }
 
index 213fb9cdb0a198f7f667d5d86a9dd264fd8dca53..65815b5660f792d6bba64bb4ebcb97bb8114b0e4 100644 (file)
@@ -35,6 +35,7 @@
 #include "rgw_token.h"
 #include "rgw_rest_role.h"
 #include "rgw_crypt.h"
+#include "rgw_crypt_sanitize.h"
 
 #include "include/assert.h"
 
@@ -4423,11 +4424,12 @@ rgw::auth::s3::RGWS3V2Extractor::get_auth_data(const req_state* const s) const
   if (! rgw_create_s3_canonical_header(s->info, &header_time, string_to_sign,
         qsr)) {
     ldout(cct, 10) << "failed to create the canonized auth header\n"
-                   << string_to_sign << dendl;
+                   << rgw::crypt_sanitize::auth{s,string_to_sign} << dendl;
     throw -EPERM;
   }
 
-  ldout(cct, 10) << "string_to_sign:\n" << string_to_sign << dendl;
+  ldout(cct, 10) << "string_to_sign:\n"
+                 << rgw::crypt_sanitize::auth{s,string_to_sign} << dendl;
 
   if (! is_time_skew_ok(header_time, qsr)) {
     throw -ERR_REQUEST_TIME_SKEWED;
@@ -4553,7 +4555,6 @@ rgw::auth::s3::LocalVersion2ndEngine::authenticate(const std::string& access_key
     }
   }*/
 
-
   const auto iter = user_info.access_keys.find(access_key_id);
   if (iter == std::end(user_info.access_keys)) {
     ldout(cct, 0) << "ERROR: access key not encoded in user info" << dendl;