From c7de0827d52d2bc61488280b7ed96ba1b9de1354 Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Thu, 5 Jan 2017 19:00:27 +0100 Subject: [PATCH] rgw: introduce basement for all S3 auth engines. Signed-off-by: Radoslaw Zarzynski --- src/rgw/rgw_rest_s3.cc | 33 ++++++++++++++ src/rgw/rgw_rest_s3.h | 100 +++++++++++++++++++++++++++++++++++++++++ 2 files changed, 133 insertions(+) diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 2ee7df8e9e59a..84e8cca3fcbb8 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -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 +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) { diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 19c2cac3eaece..572cc02278f3f 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -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 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 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 */ -- 2.39.5