From 9c0abe6d638c92f1f29798afa846f8a80fa64814 Mon Sep 17 00:00:00 2001 From: Enming Zhang Date: Wed, 25 Oct 2017 02:36:47 +0800 Subject: [PATCH] rgw: lc support Content-MD5 in request headers 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 --- src/rgw/rgw_op.cc | 34 ++++++++++++++++++++++++++++++++++ src/rgw/rgw_op.h | 4 +++- 2 files changed, 37 insertions(+), 1 deletion(-) diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index ca9a6f40f70..fa4cac616f8 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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(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; diff --git a/src/rgw/rgw_op.h b/src/rgw/rgw_op.h index 5d3067916b2..3d644f4f0c1 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -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); -- 2.39.5