]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: introduce basement for all S3 auth engines.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Thu, 5 Jan 2017 18:00:27 +0000 (19:00 +0100)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Fri, 24 Mar 2017 15:55:22 +0000 (16:55 +0100)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_rest_s3.cc
src/rgw/rgw_rest_s3.h

index 2ee7df8e9e59a112fe06a802b7336b586ac2784f..84e8cca3fcbb8c85de9f6af1731805f517a390f2 100644 (file)
@@ -4390,6 +4390,39 @@ RGWOp* RGWHandler_REST_Service_S3Website::get_obj_op(bool get_data)
 rgw::LDAPHelper* RGWLDAPAuthEngine::ldh = nullptr;
 std::mutex RGWLDAPAuthEngine::mtx;
 
+namespace rgw {
+namespace auth {
+namespace s3 {
+
+std::tuple<Version2ndEngine::Extractor::access_key_id_t,
+           Version2ndEngine::Extractor::signature_t,
+           Version2ndEngine::Extractor::expires_t,
+           Version2ndEngine::Extractor::qsr_t>
+rgw::auth::s3::RGWS3V2Extractor::get_auth_data(const req_state* const s) const
+{
+  if (! s->http_auth || s->http_auth[0] == '\0') {
+    return std::make_tuple(s->info.args.get("AWSAccessKeyId"),
+                           s->info.args.get("Signature"),
+                           s->info.args.get("Expires"),
+                           true);
+  } else {
+    const std::string auth_str(s->http_auth + strlen("AWS "));
+    const size_t pos = auth_str.rfind(':');
+    if (pos != std::string::npos) {
+      return std::make_tuple(auth_str.substr(0, pos),
+                             auth_str.substr(pos + 1),
+                             std::string(), false);
+    }
+  }
+
+  return std::make_tuple("", "", "", false);
+}
+
+} /* namespace s3 */
+} /* namespace auth */
+} /* namespace rgw */
+
+
 void RGWLDAPAuthEngine::init(CephContext* const cct)
 {
   if (! ldh) {
index 19c2cac3eaece4c95468cb11104031e4a1d95ddc..572cc02278f3f4e4bf3d3ceade28df6af582b26d 100644 (file)
@@ -763,4 +763,104 @@ public:
           store, acct_override));
     }
 };
+
+
+namespace rgw {
+namespace auth {
+namespace s3 {
+
+class Version2ndEngine : public rgw::auth::Engine {
+public:
+  class Extractor {
+  public:
+    virtual ~Extractor() {};
+
+    using access_key_id_t = std::string;
+    using signature_t = std::string;
+    using expires_t = std::string;
+    using qsr_t = bool;
+
+    virtual std::tuple<access_key_id_t,
+                       signature_t,
+                       expires_t,
+                       qsr_t> get_auth_data(const req_state* s) const = 0;
+  };
+
+protected:
+  CephContext* cct;
+  const Extractor& extractor;
+
+  Version2ndEngine(CephContext* const cct, const Extractor& extractor)
+    : cct(cct),
+      extractor(extractor) {
+  }
+
+  using result_t = rgw::auth::Engine::result_t;
+
+  virtual result_t authenticate(std::string access_key_id,
+                                std::string signature,
+                                std::string expires,
+                                bool qsr,
+                                const req_info& info) const = 0;
+
+public:
+  result_t authenticate(const req_state* const s) const final {
+    std::string access_key_id;
+    std::string signature;
+    std::string expires;
+    bool qsr;
+
+    std::tie(access_key_id, signature, expires, qsr) = \
+      extractor.get_auth_data(s);
+
+    if (access_key_id.empty() || signature.empty()) {
+      return std::make_pair(nullptr, nullptr);
+    } else {
+      return authenticate(std::move(access_key_id), std::move(signature),
+                          std::move(expires), qsr, s->info);
+    }
+  }
+};
+
+class RGWS3V2Extractor : public Version2ndEngine::Extractor {
+public:
+  std::tuple<access_key_id_t,
+             signature_t,
+             expires_t,
+             qsr_t> get_auth_data(const req_state* s) const override;
+};
+
+
+class S3AuthFactory : public rgw::auth::RemoteApplier::Factory,
+                      public rgw::auth::LocalApplier::Factory {
+  typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t;
+  RGWRados* const store;
+
+public:
+  S3AuthFactory(RGWRados* const store)
+    : store(store) {
+  }
+
+  aplptr_t create_apl_remote(CephContext* const cct,
+                             rgw::auth::RemoteApplier::acl_strategy_t&& acl_alg,
+                             const rgw::auth::RemoteApplier::AuthInfo info
+                            ) const override {
+    return aplptr_t(
+      new rgw::auth::RemoteApplier(cct, store, std::move(acl_alg), info));
+  }
+
+  aplptr_t create_apl_local(CephContext* const cct,
+                            const RGWUserInfo& user_info,
+                            const std::string& subuser) const override {
+      return aplptr_t(
+        new rgw::auth::LocalApplier(cct, user_info, subuser));
+  }
+};
+
+
+} /* namespace s3 */
+} /* namespace auth */
+} /* namespace rgw */
+
+
 #endif /* CEPH_RGW_REST_S3_H */