]> 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)
committerEnming Zhang <enming.zhang@umcloud.com>
Mon, 30 Oct 2017 17:30:29 +0000 (01:30 +0800)
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>
src/rgw/rgw_op.cc
src/rgw/rgw_op.h

index ca9a6f40f70c506878812997c889bcd8f1149790..fa4cac616f851c58bc58a69e1b0e859fbf5e62e3 100644 (file)
@@ -4843,6 +4843,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;
@@ -4854,6 +4873,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 5d3067916b255343f26aad4f2874016001bdaecb..3d644f4f0c1ce131a81c59ad941716c235480bd4 100644 (file)
@@ -1412,12 +1412,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);