From: Enming Zhang Date: Tue, 24 Oct 2017 18:36:47 +0000 (+0800) Subject: rgw: lc support Content-MD5 in request headers X-Git-Tag: v12.2.3~212^2~2 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=5e44bedf293beffb6823ae866373314a3675c431;p=ceph.git 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 (cherry picked from commit 9c0abe6d638c92f1f29798afa846f8a80fa64814) --- diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 8bd1f4ea82d0..52ac44b1c37b 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -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(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 68b83a45f133..998dc3a3f7ac 100644 --- a/src/rgw/rgw_op.h +++ b/src/rgw/rgw_op.h @@ -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);