]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: lc support Content-MD5 in request headers
authorEnming Zhang <enming.zhang@umcloud.com>
Tue, 24 Oct 2017 18:36:47 +0000 (02:36 +0800)
committerNathan Cutler <ncutler@suse.com>
Mon, 6 Nov 2017 12:32:48 +0000 (13:32 +0100)
According to AWS S3, this header must be used
as a message integrity check to verify that
the request body was not corrupted in transit.

Content-MD5 is the base64-encoded 128-bit MD5
digest of the data

Signed-off-by: Enming Zhang <enming.zhang@umcloud.com>
(cherry picked from commit 9c0abe6d638c92f1f29798afa846f8a80fa64814)

src/rgw/rgw_op.cc
src/rgw/rgw_op.h

index 8bd1f4ea82d0516f2c70bf8498cf8ebcae18b86b..52ac44b1c37b5ffa0071fc628edc005cca0a4ab2 100644 (file)
@@ -4828,6 +4828,25 @@ void RGWPutLC::execute()
   RGWLCXMLParser_S3 parser(s->cct);
   RGWLifecycleConfiguration_S3 new_config(s->cct);
 
+  content_md5 = s->info.env->get("HTTP_CONTENT_MD5");
+  if (content_md5 == nullptr) {
+    op_ret = -ERR_INVALID_REQUEST;
+    s->err.message = "Missing required header for this request: Content-MD5";
+    ldout(s->cct, 5) << s->err.message << dendl;
+    return;
+  }
+
+  std::string content_md5_bin;
+  try {
+    content_md5_bin = rgw::from_base64(boost::string_view(content_md5));
+  } catch (...) {
+    s->err.message = "Request header Content-MD5 contains character "
+                     "that is not base64 encoded.";
+    ldout(s->cct, 5) << s->err.message << dendl;
+    op_ret = -ERR_BAD_DIGEST;
+    return;
+  }
+
   if (!parser.init()) {
     op_ret = -EINVAL;
     return;
@@ -4839,6 +4858,21 @@ void RGWPutLC::execute()
 
   ldout(s->cct, 15) << "read len=" << len << " data=" << (data ? data : "") << dendl;
 
+  MD5 data_hash;
+  unsigned char data_hash_res[CEPH_CRYPTO_MD5_DIGESTSIZE];
+  data_hash.Update(reinterpret_cast<const byte*>(data), len);
+  data_hash.Final(data_hash_res);
+
+  if (memcmp(data_hash_res, content_md5_bin.c_str(), CEPH_CRYPTO_MD5_DIGESTSIZE) != 0) {
+    op_ret = -ERR_BAD_DIGEST;
+    s->err.message = "The Content-MD5 you specified did not match what we received.";
+    ldout(s->cct, 5) << s->err.message
+                     << " Specified content md5: " << content_md5
+                     << ", calculated content md5: " << data_hash_res
+                     << dendl;
+    return;
+  }
+
   if (!parser.parse(data, len, 1)) {
     op_ret = -ERR_MALFORMED_XML;
     return;
index 68b83a45f13388d6d3e7bba5cc6406d882a6914a..998dc3a3f7ac684a59fe8d7fbcddbb726c8e523b 100644 (file)
@@ -1406,12 +1406,14 @@ class RGWPutLC : public RGWOp {
 protected:
   int len;
   char *data;
+  const char *content_md5;
   string cookie;
 
 public:
   RGWPutLC() {
     len = 0;
-    data = NULL;
+    data = nullptr;
+    content_md5 = nullptr;
   }
   ~RGWPutLC() override {
     free(data);