]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: dissect AWSv4's expected payload extraction into a dedicated function.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Tue, 18 Apr 2017 12:48:28 +0000 (14:48 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 7 Jun 2017 10:43:17 +0000 (12:43 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_auth_s3.h
src/rgw/rgw_rest_s3.cc

index b80fad3139f1cbbb569fdaef3b53e202f9e62964..ad396996d4656478be72a07ecd27be836005500b 100644 (file)
@@ -185,6 +185,31 @@ static inline std::string get_v4_canonical_uri(const req_info& info) {
   return canonical_uri;
 }
 
+static inline const char* get_v4_exp_payload_hash(const req_info& info)
+{
+  /* In AWSv4 the hash of real, transfered payload IS NOT necessary to form
+   * a Canonical Request, and thus verify a Signature. x-amz-content-sha256
+   * header lets get the information very early -- before seeing first byte
+   * of HTTP body. As a consequence, we can decouple Signature verification
+   * from payload's fingerprint check. */
+  const char *expected_request_payload_hash = \
+    info.env->get("HTTP_X_AMZ_CONTENT_SHA256");
+
+  if (!expected_request_payload_hash) {
+    /* An HTTP client MUST send x-amz-content-sha256. The single exception
+     * is the case of using the Query Parameters where "UNSIGNED-PAYLOAD"
+     * literals are used for crafting Canonical Request:
+     *
+     *  You don't include a payload hash in the Canonical Request, because
+     *  when you create a presigned URL, you don't know the payload content
+     *  because the URL is used to upload an arbitrary payload. Instead, you
+     *  use a constant string UNSIGNED-PAYLOAD. */
+    expected_request_payload_hash = "UNSIGNED-PAYLOAD";
+  }
+
+  return expected_request_payload_hash;
+}
+
 std::string get_v4_canonical_qs(const req_info& info, bool using_qs);
 
 boost::optional<std::string> get_v4_canonical_headers(const req_info& info,
index b40754fdbebd78a6b9378aecf7adadafc8e5bc7d..2bd30f974c21963e23b8f95851ddd1762ba813a7 100644 (file)
@@ -3384,20 +3384,14 @@ int RGW_Auth_S3::authorize_aws4_auth_complete(RGWRados *store, struct req_state
 
 int RGW_Auth_S3::authorize_v4_complete(RGWRados *store, struct req_state *s, const string& request_payload, bool unsigned_payload)
 {
-  const char *expected_request_payload_hash = s->info.env->get("HTTP_X_AMZ_CONTENT_SHA256");
-  if (!expected_request_payload_hash) {
-    /* In AWSv4 the hash of real, transfered payload IS NOT necessary to form
-     * a Canonical Request, and thus verify a Signature. x-amz-content-sha256
-     * header lets get the information very early -- before seeing first byte
-     * of HTTP body. As a consequence, we can decouple Signature verification
-     * from payload's fingerprint check.
-     *
-     * An HTTP client MUST send x-amz-content-sha256. AFAIK the single exception
-     * to that is the case of using Query Parameters for doing the auth In such
-     * scenario, the "UNSIGNED-PAYLOAD" literals are used instead. */
-    expected_request_payload_hash = "UNSIGNED-PAYLOAD";
-  }
-
+  const char *expected_request_payload_hash = \
+    rgw::auth::s3::get_v4_exp_payload_hash(s->info);
+
+  /* In AWSv4 the hash of real, transfered payload IS NOT necessary to form
+   * a Canonical Request, and thus verify a Signature. x-amz-content-sha256
+   * header lets get the information very early -- before seeing first byte
+   * of HTTP body. As a consequence, we can decouple Signature verification
+   * from payload's fingerprint check. */
   std::string payload_hash;
   if (unsigned_payload) {
     payload_hash = "UNSIGNED-PAYLOAD";
@@ -3519,19 +3513,8 @@ int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s, bool force_b
     }
   }
 
-  const char *expected_request_payload_hash = s->info.env->get("HTTP_X_AMZ_CONTENT_SHA256");
-  if (!expected_request_payload_hash) {
-    /* In AWSv4 the hash of real, transfered payload IS NOT necessary to form
-     * a Canonical Request, and thus verify a Signature. x-amz-content-sha256
-     * header lets get the information very early -- before seeing first byte
-     * of HTTP body. As a consequence, we can decouple Signature verification
-     * from payload's fingerprint check.
-     *
-     * An HTTP client MUST send x-amz-content-sha256. AFAIK the single exception
-     * to that is the case of using Query Parameters for doing the auth In such
-     * scenario, the "UNSIGNED-PAYLOAD" literals are used instead. */
-    expected_request_payload_hash = "UNSIGNED-PAYLOAD";
-  }
+  /* Get the expected hash. */
+  auto exp_payload_hash = rgw::auth::s3::get_v4_exp_payload_hash(s->info);
 
   /* craft canonical request */
   std::string canonical_req_hash = \
@@ -3541,7 +3524,7 @@ int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s, bool force_b
                                          canonical_qs,
                                          *canonical_headers,
                                          signed_hdrs,
-                                         expected_request_payload_hash);
+                                         exp_payload_hash);
 
   /*
    * create a string to sign