]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: ONLY move AWSv4Completer from rgw_rest_s3.cc to rgw_auth_s3.cc.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Sun, 23 Apr 2017 01:27:28 +0000 (03:27 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 7 Jun 2017 10:43:18 +0000 (12:43 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_auth_s3.cc
src/rgw/rgw_auth_s3.h
src/rgw/rgw_rest_s3.cc

index 8aee844aa4b7201c733baf3f906779bd35b6c131..dd75d0fae4b898ef877bfa44870c1015423e5975 100644 (file)
@@ -6,6 +6,7 @@
 
 #include "common/armor.h"
 #include "common/utf8.h"
+#include "rgw_auth_s3.h"
 #include "rgw_common.h"
 #include "rgw_client_io.h"
 #include "rgw_rest.h"
@@ -810,6 +811,94 @@ std::string get_v4_signature(CephContext* const cct,
   return signature;
 }
 
+
+void AWSv4Completer::modify_request_state(req_state* const s_rw) const
+{
+  /* TODO(rzarzynski): switch to the dedicated filter over RestfulClient. */
+  s_rw->aws4_auth_needs_complete = aws4_auth_needs_complete;
+  s_rw->aws4_auth_streaming_mode = aws4_auth_streaming_mode;
+
+  s_rw->aws4_auth = std::unique_ptr<rgw_aws4_auth>(new rgw_aws4_auth);
+
+  s_rw->aws4_auth->date = std::move(date);
+  s_rw->aws4_auth->credential_scope = std::move(date);
+
+  /* If we're here, the provided signature has been successfully validated
+   * earlier. */
+  s_rw->aws4_auth->seed_signature = std::move(seed_signature);
+
+  if (signing_key) {
+    s_rw->aws4_auth->signing_key = std::move(*signing_key);
+  } else if (aws4_auth_streaming_mode) {
+    /* Some external authorizers (like Keystone) aren't fully compliant with
+     * AWSv4. They do not provide the secret_key which is necessary to handle
+     * the streamed upload. */
+    throw -ERR_NOT_IMPLEMENTED;
+  }
+}
+
+bool AWSv4Completer::complete()
+{
+  if (!aws4_auth_needs_complete) {
+    return true;
+  }
+
+  /* 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 = \
+    rgw::auth::s3::get_v4_exp_payload_hash(s->info);
+
+  /* The completer is only for the cases where signed payload has been
+   * requested. It won't be used, for instance, during the query string-based
+   * authentication. */
+  const auto payload_hash = AWS_AUTHv4_IO(s)->grab_aws4_sha256_hash();
+
+  /* Validate x-amz-sha256 */
+  if (payload_hash.compare(expected_request_payload_hash) == 0) {
+    return true;
+  } else {
+    ldout(s->cct, 10) << "ERROR: x-amz-content-sha256 does not match"
+                      << dendl;
+    ldout(s->cct, 10) << "ERROR:   grab_aws4_sha256_hash()="
+                      << payload_hash << dendl;
+    ldout(s->cct, 10) << "ERROR:   expected_request_payload_hash="
+                      << expected_request_payload_hash << dendl;
+    return false;
+  }
+}
+
+rgw::auth::Completer::cmplptr_t
+AWSv4Completer::create_for_single_chunk(const req_state* const s,
+                                        const boost::optional<std::string>&)
+{
+  return rgw::auth::Completer::cmplptr_t(new AWSv4Completer(s));
+}
+
+rgw::auth::Completer::cmplptr_t
+AWSv4Completer::create_for_multi_chunk(const req_state* const s,
+                                       std::string date,
+                                       std::string credential_scope,
+                                       std::string seed_signature,
+                                       const boost::optional<std::string>& secret_key)
+{
+  boost::optional<std::array<unsigned char,
+                  CEPH_CRYPTO_HMACSHA256_DIGESTSIZE>> signing_key;
+  if (secret_key) {
+    signing_key = rgw::auth::s3::get_v4_signing_key(s->cct, credential_scope,
+                                                    *secret_key);
+  }
+
+  return rgw::auth::Completer::cmplptr_t(
+    new AWSv4Completer(s,
+                       std::move(date),
+                       std::move(credential_scope),
+                       std::move(seed_signature),
+                       signing_key));
+}
+
 } /* namespace s3 */
 } /* namespace auth */
 } /* namespace rgw */
index 14ae5ae2f38781b56802a184f025ab07e0dc48b9..3a1de854523b306bd802e343731250735b870412 100644 (file)
@@ -126,6 +126,66 @@ public:
   }
 };
 
+
+/* TODO(rzarzynski): make the completer to be additionally a decorator over
+ * rgw::io::RestfulClient (see rgw::io::DecoratedRestfulClient). This would
+ * allow to eradicate req_state::aws4 and friends. */
+class AWSv4Completer : public rgw::auth::Completer {
+private:
+  const bool aws4_auth_needs_complete = true;
+  const bool aws4_auth_streaming_mode = false;
+
+  /* TODO(rzarzynski): move to boost::string_ref. This should be just fine
+   * as (all?) parameters here are actually views over req_info. */
+  std::string date;
+  std::string credential_scope;
+  std::string seed_signature;
+  boost::optional<std::array<unsigned char,
+                  CEPH_CRYPTO_HMACSHA256_DIGESTSIZE>> signing_key;
+  ceph::bufferlist bl;
+
+  /* TODO(rzarzynski): this won't be necessary after moving to filter-over-
+   * rgw::io::RestfulClient. */
+  const req_state* const s;
+
+  using signing_key_t = boost::optional<std::array<unsigned char,
+                                        CEPH_CRYPTO_HMACSHA256_DIGESTSIZE>>;
+  AWSv4Completer(const req_state* const s,
+                 std::string date,
+                 std::string credential_scope,
+                 std::string seed_signature,
+                 const signing_key_t& signing_key)
+    : aws4_auth_needs_complete(false),
+      aws4_auth_streaming_mode(true),
+      date(std::move(date)),
+      credential_scope(std::move(credential_scope)),
+      seed_signature(std::move(seed_signature)),
+      signing_key(signing_key),
+      s(s) {
+  }
+
+  AWSv4Completer(const req_state* const s)
+    : s(s) {
+  }
+
+public:
+  void modify_request_state(req_state* s) const override;
+  bool complete() override;
+
+  /* Factories. */
+  static cmplptr_t
+  create_for_single_chunk(const req_state* s,
+                          const boost::optional<std::string>&);
+
+  static cmplptr_t
+  create_for_multi_chunk(const req_state* s,
+                         std::string date,
+                         std::string credential_scope,
+                         std::string seed_signature,
+                         const boost::optional<std::string>& secret_key);
+
+};
+
 } /* namespace s3 */
 } /* namespace auth */
 } /* namespace rgw */
index 4849d0bf1f487260624244fae31d6ad012559b4e..65959ba4372db94a9789c6d57a8ab50cffd0ef66 100644 (file)
@@ -3748,152 +3748,6 @@ null_completer_factory(const boost::optional<std::string>& secret_key)
   return nullptr;
 }
 
-/* TODO(rzarzynski): make the completer to be additionally a decorator over
- * rgw::io::RestfulClient (see rgw::io::DecoratedRestfulClient). This would
- * allow to eradicate req_state::aws4 and friends. */
-class AWSv4Completer : public rgw::auth::Completer {
-private:
-  const bool aws4_auth_needs_complete = true;
-  const bool aws4_auth_streaming_mode = false;
-
-  /* TODO(rzarzynski): move to boost::string_ref. This should be just fine
-   * as (all?) parameters here are actually views over req_info. */
-  std::string date;
-  std::string credential_scope;
-  std::string seed_signature;
-  boost::optional<std::array<unsigned char,
-                  CEPH_CRYPTO_HMACSHA256_DIGESTSIZE>> signing_key;
-  ceph::bufferlist bl;
-
-  /* TODO(rzarzynski): this won't be necessary after moving to filter-over-
-   * rgw::io::RestfulClient. */
-  const req_state* const s;
-
-  using signing_key_t = boost::optional<std::array<unsigned char,
-                                        CEPH_CRYPTO_HMACSHA256_DIGESTSIZE>>;
-  AWSv4Completer(const req_state* const s,
-                 std::string date,
-                 std::string credential_scope,
-                 std::string seed_signature,
-                 const signing_key_t& signing_key)
-    : aws4_auth_needs_complete(false),
-      aws4_auth_streaming_mode(true),
-      date(std::move(date)),
-      credential_scope(std::move(credential_scope)),
-      seed_signature(std::move(seed_signature)),
-      signing_key(signing_key),
-      s(s) {
-  }
-
-  AWSv4Completer(const req_state* const s)
-    : s(s) {
-  }
-
-public:
-  void modify_request_state(req_state* s) const override;
-  bool complete() override;
-
-  /* Factories. */
-  static cmplptr_t
-  create_for_single_chunk(const req_state* s,
-                          const boost::optional<std::string>&);
-
-  static cmplptr_t
-  create_for_multi_chunk(const req_state* s,
-                         std::string date,
-                         std::string credential_scope,
-                         std::string seed_signature,
-                         const boost::optional<std::string>& secret_key);
-
-};
-
-void AWSv4Completer::modify_request_state(req_state* const s_rw) const
-{
-  /* TODO(rzarzynski): switch to the dedicated filter over RestfulClient. */
-  s_rw->aws4_auth_needs_complete = aws4_auth_needs_complete;
-  s_rw->aws4_auth_streaming_mode = aws4_auth_streaming_mode;
-
-  s_rw->aws4_auth = std::unique_ptr<rgw_aws4_auth>(new rgw_aws4_auth);
-
-  s_rw->aws4_auth->date = std::move(date);
-  s_rw->aws4_auth->credential_scope = std::move(date);
-
-  /* If we're here, the provided signature has been successfully validated
-   * earlier. */
-  s_rw->aws4_auth->seed_signature = std::move(seed_signature);
-
-  if (signing_key) {
-    s_rw->aws4_auth->signing_key = std::move(*signing_key);
-  } else if (aws4_auth_streaming_mode) {
-    /* Some external authorizers (like Keystone) aren't fully compliant with
-     * AWSv4. They do not provide the secret_key which is necessary to handle
-     * the streamed upload. */
-    throw -ERR_NOT_IMPLEMENTED;
-  }
-}
-
-bool AWSv4Completer::complete()
-{
-  if (!aws4_auth_needs_complete) {
-    return true;
-  }
-
-  /* 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 = \
-    rgw::auth::s3::get_v4_exp_payload_hash(s->info);
-
-  /* The completer is only for the cases where signed payload has been
-   * requested. It won't be used, for instance, during the query string-based
-   * authentication. */
-  const auto payload_hash = AWS_AUTHv4_IO(s)->grab_aws4_sha256_hash();
-
-  /* Validate x-amz-sha256 */
-  if (payload_hash.compare(expected_request_payload_hash) == 0) {
-    return true;
-  } else {
-    ldout(s->cct, 10) << "ERROR: x-amz-content-sha256 does not match"
-                      << dendl;
-    ldout(s->cct, 10) << "ERROR:   grab_aws4_sha256_hash()="
-                      << payload_hash << dendl;
-    ldout(s->cct, 10) << "ERROR:   expected_request_payload_hash="
-                      << expected_request_payload_hash << dendl;
-    return false;
-  }
-}
-
-rgw::auth::Completer::cmplptr_t
-AWSv4Completer::create_for_single_chunk(const req_state* const s,
-                                        const boost::optional<std::string>&)
-{
-  return rgw::auth::Completer::cmplptr_t(new AWSv4Completer(s));
-}
-
-rgw::auth::Completer::cmplptr_t
-AWSv4Completer::create_for_multi_chunk(const req_state* const s,
-                                       std::string date,
-                                       std::string credential_scope,
-                                       std::string seed_signature,
-                                       const boost::optional<std::string>& secret_key)
-{
-  boost::optional<std::array<unsigned char,
-                  CEPH_CRYPTO_HMACSHA256_DIGESTSIZE>> signing_key;
-  if (secret_key) {
-    signing_key = rgw::auth::s3::get_v4_signing_key(s->cct, credential_scope,
-                                                    *secret_key);
-  }
-
-  return rgw::auth::Completer::cmplptr_t(
-    new AWSv4Completer(s,
-                       std::move(date),
-                       std::move(credential_scope),
-                       std::move(seed_signature),
-                       signing_key));
-}
-
 
 using AWSVerAbstractor = AWSEngine::VersionAbstractor;