]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: introduce string_to_sign_t abstraction to the AWS auth.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Tue, 6 Jun 2017 19:13:52 +0000 (21:13 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 7 Jun 2017 10:48:47 +0000 (12:48 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_auth_keystone.cc
src/rgw/rgw_auth_keystone.h
src/rgw/rgw_auth_s3.cc
src/rgw/rgw_auth_s3.h
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h

index 4a9685e92fab728eec429edf308d89caf1754a73..0b5ee41a17e4d0fffb37efa775e98fef75d9523a 100644 (file)
@@ -416,7 +416,7 @@ EC2Engine::get_creds_info(const EC2Engine::token_envelope_t& token,
 rgw::auth::Engine::result_t EC2Engine::authenticate(
   const boost::string_view& access_key_id,
   const boost::string_view& signature,
-  const std::string& string_to_sign,
+  const string_to_sign_t& string_to_sign,
   const signature_factory_t&,
   const completer_factory_t& completer_factory,
   /* Passthorugh only! */
index 18905ba64c04701b3054e79c2f68b45faa1425b5..feef469cb080be8a0073a084c3bab180d65ea6c9 100644 (file)
@@ -93,7 +93,7 @@ class EC2Engine : public rgw::auth::s3::AWSEngine {
                     const boost::string_view& signature) const;
   result_t authenticate(const boost::string_view& access_key_id,
                         const boost::string_view& signature,
-                        const std::string& string_to_sign,
+                        const string_to_sign_t& string_to_sign,
                         const signature_factory_t&,
                         const completer_factory_t& completer_factory,
                         const req_state* s) const override;
index 8c7d448902fcce1658e18148e740122193a5de81..6afe7291c274491b8fe1d87582e2647f59b19a91 100644 (file)
@@ -676,11 +676,12 @@ get_v4_canon_req_hash(CephContext* cct,
  *
  * http://docs.aws.amazon.com/general/latest/gr/sigv4-create-string-to-sign.html
  */
-std::string get_v4_string_to_sign(CephContext* const cct,
-                                  const boost::string_view& algorithm,
-                                  const boost::string_view& request_date,
-                                  const boost::string_view& credential_scope,
-                                  const sha256_digest_t& canonreq_hash)
+AWSEngine::VersionAbstractor::string_to_sign_t
+get_v4_string_to_sign(CephContext* const cct,
+                      const boost::string_view& algorithm,
+                      const boost::string_view& request_date,
+                      const boost::string_view& credential_scope,
+                      const sha256_digest_t& canonreq_hash)
 {
   const auto hexed_cr_hash = buf_to_hex(canonreq_hash);
 
@@ -750,9 +751,10 @@ transform_secret_key(const boost::string_view& secret_access_key)
 /*
  * calculate the SigningKey of AWS auth version 4
  */
-sha256_digest_t get_v4_signing_key(CephContext* const cct,
-                                   const boost::string_view& credential_scope,
-                                   const boost::string_view& secret_access_key)
+static sha256_digest_t
+get_v4_signing_key(CephContext* const cct,
+                   const boost::string_view& credential_scope,
+                   const boost::string_view& secret_access_key)
 {
   boost::string_view date, region, service;
   std::tie(date, region, service) = parse_cred_scope(credential_scope);
@@ -776,14 +778,21 @@ sha256_digest_t get_v4_signing_key(CephContext* const cct,
 
 /*
  * calculate the AWS signature version 4
-
+ *
  * http://docs.aws.amazon.com/general/latest/gr/sigv4-calculate-signature.html
+ *
+ * srv_signature_t is an alias over Ceph's basic_sstring. We're using
+ * it to keep everything within the stack boundaries instead of doing
+ * dynamic allocations.
  */
 AWSEngine::VersionAbstractor::server_signature_t
-get_v4_signature(CephContext* const cct,
-                 const sha256_digest_t& signing_key,
-                 const boost::string_view& string_to_sign)
+get_v4_signature(const boost::string_view& credential_scope,
+                 CephContext* const cct,
+                 const boost::string_view& secret_key,
+                 const AWSEngine::VersionAbstractor::string_to_sign_t& string_to_sign)
 {
+  auto signing_key = get_v4_signing_key(cct, credential_scope, secret_key);
+
   /* The server-side generated digest for comparison. */
   const auto digest = calc_hmac_sha256(signing_key, string_to_sign);
 
@@ -802,7 +811,7 @@ get_v4_signature(CephContext* const cct,
 AWSEngine::VersionAbstractor::server_signature_t
 get_v2_signature(CephContext* const cct,
                  const std::string& secret_key,
-                 const std::string& string_to_sign)
+                 const AWSEngine::VersionAbstractor::string_to_sign_t& string_to_sign)
 {
   if (secret_key.empty()) {
     throw -EINVAL;
index f30bdb2faeba45b8817ee7e99199e9a5b38ceda7..36565457018ab74e579aef57c787e659a5e846ab 100644 (file)
@@ -412,26 +412,23 @@ get_v4_canon_req_hash(CephContext* cct,
                       const boost::string_view& signed_hdrs,
                       const boost::string_view& request_payload_hash);
 
-std::string get_v4_string_to_sign(CephContext* cct,
-                                  const boost::string_view& algorithm,
-                                  const boost::string_view& request_date,
-                                  const boost::string_view& credential_scope,
-                                  const sha256_digest_t& canonreq_hash);
-
-extern sha256_digest_t
-get_v4_signing_key(CephContext* const cct,
-                   const boost::string_view& credential_scope,
-                   const boost::string_view& access_key_secret);
+AWSEngine::VersionAbstractor::string_to_sign_t
+get_v4_string_to_sign(CephContext* cct,
+                      const boost::string_view& algorithm,
+                      const boost::string_view& request_date,
+                      const boost::string_view& credential_scope,
+                      const sha256_digest_t& canonreq_hash);
 
 extern AWSEngine::VersionAbstractor::server_signature_t
-get_v4_signature(CephContext* cct,
-                 const sha256_digest_t& signing_key,
-                 const boost::string_view& string_to_sign);
+get_v4_signature(const boost::string_view& credential_scope,
+                 CephContext* const cct,
+                 const boost::string_view& secret_key,
+                 const AWSEngine::VersionAbstractor::string_to_sign_t& string_to_sign);
 
 extern AWSEngine::VersionAbstractor::server_signature_t
 get_v2_signature(CephContext*,
                  const std::string& secret_key,
-                 const std::string& string_to_sign);
+                 const AWSEngine::VersionAbstractor::string_to_sign_t& string_to_sign);
 
 } /* namespace s3 */
 } /* namespace auth */
index 1a1dc433795922790da26e930309684d7f4879d2..c79e4e7ff8c129ad64b2a20253d028148dc20641 100644 (file)
@@ -3565,25 +3565,6 @@ AWSGeneralAbstractor::get_auth_data(const req_state* const s) const
   }
 }
 
-/* srv_signature_t is an alias over Ceph's basic_sstring. We're using
- * it to keep everything within the stack boundaries instead of doing
- * dynamic allocations. */
-static inline AWSVerAbstractor::server_signature_t
-v4_signature(const boost::string_view& credential_scope,
-
-             CephContext* const cct,
-             const boost::string_view& secret_key,
-             const boost::string_view& string_to_sign)
-{
-  auto signing_key = \
-    rgw::auth::s3::get_v4_signing_key(cct, credential_scope, secret_key);
-
-  auto server_signature = \
-    rgw::auth::s3::get_v4_signature(cct, std::move(signing_key),
-                                    string_to_sign);
-  return server_signature;
-}
-
 std::tuple<AWSVerAbstractor::access_key_id_t,
            AWSVerAbstractor::client_signature_t,
            AWSVerAbstractor::string_to_sign_t,
@@ -3648,7 +3629,7 @@ AWSGeneralAbstractor::get_auth_data_v4(const req_state* const s,
                                          credential_scope,
                                          std::move(canonical_req_hash));
 
-  const auto sig_factory = std::bind(v4_signature,
+  const auto sig_factory = std::bind(rgw::auth::s3::get_v4_signature,
                                      credential_scope,
                                      std::placeholders::_1,
                                      std::placeholders::_2,
@@ -3852,7 +3833,7 @@ AWSBrowserUploadAbstractor::get_auth_data_v4(const req_state* const s) const
   const boost::string_view credential_scope = credential.substr(pos + 1);
   dout(10) << "credential scope = " << credential_scope << dendl;
 
-  const auto sig_factory = std::bind(v4_signature,
+  const auto sig_factory = std::bind(rgw::auth::s3::get_v4_signature,
                                      credential_scope,
                                      std::placeholders::_1,
                                      std::placeholders::_2,
@@ -3882,6 +3863,32 @@ AWSBrowserUploadAbstractor::get_auth_data(const req_state* const s) const
   }
 }
 
+
+AWSEngine::result_t
+AWSEngine::authenticate(const req_state* const s) const
+{
+  boost::string_view access_key_id;
+  boost::string_view signature;
+  VersionAbstractor::string_to_sign_t string_to_sign;
+
+  VersionAbstractor::signature_factory_t signature_factory;
+  VersionAbstractor::completer_factory_t completer_factory;
+
+  /* Small reminder: an ver_abstractor is allowed to throw! */
+  std::tie(access_key_id,
+           signature,
+           string_to_sign,
+           signature_factory,
+           completer_factory) = ver_abstractor.get_auth_data(s);
+
+  if (access_key_id.empty() || signature.empty()) {
+    return result_t::deny(-EINVAL);
+  } else {
+    return authenticate(access_key_id, signature, string_to_sign,
+                        signature_factory, completer_factory, s);
+  }
+}
+
 } /* namespace s3 */
 } /* namespace auth */
 } /* namespace rgw */
@@ -3939,7 +3946,7 @@ rgw::auth::Engine::result_t
 rgw::auth::s3::LDAPEngine::authenticate(
   const boost::string_view& access_key_id,
   const boost::string_view& signature,
-  const std::string& string_to_sign,
+  const string_to_sign_t& string_to_sign,
   const signature_factory_t&,
   const completer_factory_t& completer_factory,
   const req_state* const s) const
@@ -3983,7 +3990,7 @@ rgw::auth::Engine::result_t
 rgw::auth::s3::LocalEngine::authenticate(
   const boost::string_view& _access_key_id,
   const boost::string_view& signature,
-  const std::string& string_to_sign,
+  const string_to_sign_t& string_to_sign,
   const signature_factory_t& signature_factory,
   const completer_factory_t& completer_factory,
   const req_state* const s) const
index f6fdcd7b0f78394133ddb893359931644979c9e3..6586f25b5986ac4ce0a673a918bfe191060fefb5 100644 (file)
@@ -9,6 +9,7 @@
 #include <mutex>
 
 #include <boost/utility/string_view.hpp>
+#include <boost/container/static_vector.hpp>
 
 #include "common/backport14.h"
 #include "common/sstring.hh"
@@ -687,7 +688,7 @@ public:
     using signature_factory_t = \
       std::function<server_signature_t(CephContext* cct,
                                        const std::string& secret_key,
-                                       const std::string& string_to_sign)>;
+                                       const string_to_sign_t& string_to_sign)>;
 
     /* Return an instance of Completer for verifying the payload's fingerprint
      * if necessary. Otherwise caller gets nullptr. Caller may provide secret
@@ -714,6 +715,7 @@ protected:
   }
 
   using result_t = rgw::auth::Engine::result_t;
+  using string_to_sign_t = VersionAbstractor::string_to_sign_t;
   using signature_factory_t = VersionAbstractor::signature_factory_t;
   using completer_factory_t = VersionAbstractor::completer_factory_t;
 
@@ -722,36 +724,16 @@ protected:
    * Replace these thing with a simple, dedicated structure. */
   virtual result_t authenticate(const boost::string_view& access_key_id,
                                 const boost::string_view& signature,
-                                const std::string& string_to_sign,
+                                const string_to_sign_t& string_to_sign,
                                 const signature_factory_t& signature_factory,
                                 const completer_factory_t& completer_factory,
                                 const req_state* s) const = 0;
 
 public:
-  result_t authenticate(const req_state* const s) const final {
-    boost::string_view access_key_id;
-    boost::string_view signature;
-    std::string string_to_sign;
-
-    VersionAbstractor::signature_factory_t signature_factory;
-    VersionAbstractor::completer_factory_t completer_factory;
-
-    /* Small reminder: an ver_abstractor is allowed to throw! */
-    std::tie(access_key_id,
-             signature,
-             string_to_sign,
-             signature_factory,
-             completer_factory) = ver_abstractor.get_auth_data(s);
-
-    if (access_key_id.empty() || signature.empty()) {
-      return result_t::deny(-EINVAL);
-    } else {
-      return authenticate(access_key_id, signature, string_to_sign,
-                          signature_factory, completer_factory, s);
-    }
-  }
+  result_t authenticate(const req_state* const s) const final;
 };
 
+
 class AWSGeneralAbstractor : public AWSEngine::VersionAbstractor {
   CephContext* const cct;
 
@@ -833,7 +815,7 @@ protected:
 
   result_t authenticate(const boost::string_view& access_key_id,
                         const boost::string_view& signature,
-                        const std::string& string_to_sign,
+                        const string_to_sign_t& string_to_sign,
                         const signature_factory_t&,
                         const completer_factory_t& completer_factory,
                         const req_state* s) const override;
@@ -862,7 +844,7 @@ class LocalEngine : public AWSEngine {
 
   result_t authenticate(const boost::string_view& access_key_id,
                         const boost::string_view& signature,
-                        const std::string& string_to_sign,
+                        const string_to_sign_t& string_to_sign,
                         const signature_factory_t& signature_factory,
                         const completer_factory_t& completer_factory,
                         const req_state* s) const override;