From 19fcec84d8d7d21e796c7624e521b60d28ee21ed Mon Sep 17 00:00:00 2001 From: Daniel Baumann Date: Sun, 7 Apr 2024 20:45:59 +0200 Subject: Adding upstream version 16.2.11+ds. Signed-off-by: Daniel Baumann --- src/rgw/rgw_swift_auth.h | 349 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 349 insertions(+) create mode 100644 src/rgw/rgw_swift_auth.h (limited to 'src/rgw/rgw_swift_auth.h') diff --git a/src/rgw/rgw_swift_auth.h b/src/rgw/rgw_swift_auth.h new file mode 100644 index 000000000..2aa89caf5 --- /dev/null +++ b/src/rgw/rgw_swift_auth.h @@ -0,0 +1,349 @@ +// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- +// vim: ts=8 sw=2 smarttab ft=cpp + +#ifndef CEPH_RGW_SWIFT_AUTH_H +#define CEPH_RGW_SWIFT_AUTH_H + +#include "rgw_common.h" +#include "rgw_user.h" +#include "rgw_op.h" +#include "rgw_rest.h" +#include "rgw_auth.h" +#include "rgw_auth_keystone.h" +#include "rgw_auth_filters.h" +#include "rgw_sal.h" + +#define RGW_SWIFT_TOKEN_EXPIRATION (15 * 60) + +namespace rgw { +namespace auth { +namespace swift { + +/* TempURL: applier. */ +class TempURLApplier : public rgw::auth::LocalApplier { +public: + TempURLApplier(CephContext* const cct, + const RGWUserInfo& user_info) + : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, boost::none, LocalApplier::NO_ACCESS_KEY) { + }; + + void modify_request_state(const DoutPrefixProvider* dpp, req_state * s) const override; /* in/out */ + void write_ops_log_entry(rgw_log_entry& entry) const override; + + struct Factory { + virtual ~Factory() {} + virtual aplptr_t create_apl_turl(CephContext* cct, + const req_state* s, + const RGWUserInfo& user_info) const = 0; + }; +}; + +/* TempURL: engine */ +class TempURLEngine : public rgw::auth::Engine { + using result_t = rgw::auth::Engine::result_t; + + CephContext* const cct; + /* const */ RGWCtl* const ctl; + const TempURLApplier::Factory* const apl_factory; + + /* Helper methods. */ + void get_owner_info(const DoutPrefixProvider* dpp, + const req_state* s, + RGWUserInfo& owner_info, + optional_yield y) const; + std::string convert_from_iso8601(std::string expires) const; + bool is_applicable(const req_state* s) const noexcept; + bool is_expired(const std::string& expires) const; + bool is_disallowed_header_present(const req_info& info) const; + + class SignatureHelper; + class PrefixableSignatureHelper; + +public: + TempURLEngine(CephContext* const cct, + /*const*/ RGWCtl* const ctl, + const TempURLApplier::Factory* const apl_factory) + : cct(cct), + ctl(ctl), + apl_factory(apl_factory) { + } + + /* Interface implementations. */ + const char* get_name() const noexcept override { + return "rgw::auth::swift::TempURLEngine"; + } + + result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s, optional_yield y) const override; +}; + + +/* AUTH_rgwtk */ +class SignedTokenEngine : public rgw::auth::Engine { + using result_t = rgw::auth::Engine::result_t; + + CephContext* const cct; + RGWCtl* const ctl; + const rgw::auth::TokenExtractor* const extractor; + const rgw::auth::LocalApplier::Factory* const apl_factory; + + bool is_applicable(const std::string& token) const noexcept; + using rgw::auth::Engine::authenticate; + result_t authenticate(const DoutPrefixProvider* dpp, + const std::string& token, + const req_state* s) const; + +public: + SignedTokenEngine(CephContext* const cct, + /* const */RGWCtl* const ctl, + const rgw::auth::TokenExtractor* const extractor, + const rgw::auth::LocalApplier::Factory* const apl_factory) + : cct(cct), + ctl(ctl), + extractor(extractor), + apl_factory(apl_factory) { + } + + const char* get_name() const noexcept override { + return "rgw::auth::swift::SignedTokenEngine"; + } + + result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s, + optional_yield y) const override { + return authenticate(dpp, extractor->get_token(s), s); + } +}; + + +/* External token */ +class ExternalTokenEngine : public rgw::auth::Engine { + using result_t = rgw::auth::Engine::result_t; + + CephContext* const cct; + RGWCtl* const ctl; + const rgw::auth::TokenExtractor* const extractor; + const rgw::auth::LocalApplier::Factory* const apl_factory; + + bool is_applicable(const std::string& token) const noexcept; + result_t authenticate(const DoutPrefixProvider* dpp, + const std::string& token, + const req_state* s, optional_yield y) const; + +public: + ExternalTokenEngine(CephContext* const cct, + /* const */RGWCtl* const ctl, + const rgw::auth::TokenExtractor* const extractor, + const rgw::auth::LocalApplier::Factory* const apl_factory) + : cct(cct), + ctl(ctl), + extractor(extractor), + apl_factory(apl_factory) { + } + + const char* get_name() const noexcept override { + return "rgw::auth::swift::ExternalTokenEngine"; + } + + result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s, + optional_yield y) const override { + return authenticate(dpp, extractor->get_token(s), s, y); + } +}; + +/* SwiftAnonymous: applier. */ +class SwiftAnonymousApplier : public rgw::auth::LocalApplier { + public: + SwiftAnonymousApplier(CephContext* const cct, + const RGWUserInfo& user_info) + : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, boost::none, LocalApplier::NO_ACCESS_KEY) { + }; + bool is_admin_of(const rgw_user& uid) const {return false;} + bool is_owner_of(const rgw_user& uid) const {return uid.id.compare(RGW_USER_ANON_ID) == 0;} +}; + +class SwiftAnonymousEngine : public rgw::auth::AnonymousEngine { + const rgw::auth::TokenExtractor* const extractor; + + bool is_applicable(const req_state* s) const noexcept override { + return extractor->get_token(s).empty(); + } + +public: + SwiftAnonymousEngine(CephContext* const cct, + const SwiftAnonymousApplier::Factory* const apl_factory, + const rgw::auth::TokenExtractor* const extractor) + : AnonymousEngine(cct, apl_factory), + extractor(extractor) { + } + + const char* get_name() const noexcept override { + return "rgw::auth::swift::SwiftAnonymousEngine"; + } +}; + + +class DefaultStrategy : public rgw::auth::Strategy, + public rgw::auth::TokenExtractor, + public rgw::auth::RemoteApplier::Factory, + public rgw::auth::LocalApplier::Factory, + public rgw::auth::swift::TempURLApplier::Factory { + RGWCtl* const ctl; + ImplicitTenants& implicit_tenant_context; + + /* The engines. */ + const rgw::auth::swift::TempURLEngine tempurl_engine; + const rgw::auth::swift::SignedTokenEngine signed_engine; + boost::optional keystone_engine; + const rgw::auth::swift::ExternalTokenEngine external_engine; + const rgw::auth::swift::SwiftAnonymousEngine anon_engine; + + using keystone_config_t = rgw::keystone::CephCtxConfig; + using keystone_cache_t = rgw::keystone::TokenCache; + using aplptr_t = rgw::auth::IdentityApplier::aplptr_t; + using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t; + + /* The method implements TokenExtractor for X-Auth-Token present in req_state. */ + std::string get_token(const req_state* const s) const override { + /* Returning a reference here would end in GCC complaining about a reference + * to temporary. */ + return s->info.env->get("HTTP_X_AUTH_TOKEN", ""); + } + + aplptr_t create_apl_remote(CephContext* const cct, + const req_state* const s, + acl_strategy_t&& extra_acl_strategy, + const rgw::auth::RemoteApplier::AuthInfo &info) const override { + auto apl = \ + rgw::auth::add_3rdparty(ctl, rgw_user(s->account_name), + rgw::auth::add_sysreq(cct, ctl, s, + rgw::auth::RemoteApplier(cct, ctl, std::move(extra_acl_strategy), info, + implicit_tenant_context, + rgw::auth::ImplicitTenants::IMPLICIT_TENANTS_SWIFT))); + /* TODO(rzarzynski): replace with static_ptr. */ + return aplptr_t(new decltype(apl)(std::move(apl))); + } + + aplptr_t create_apl_local(CephContext* const cct, + const req_state* const s, + const RGWUserInfo& user_info, + const std::string& subuser, + const boost::optional& perm_mask, + const std::string& access_key_id) const override { + auto apl = \ + rgw::auth::add_3rdparty(ctl, rgw_user(s->account_name), + rgw::auth::add_sysreq(cct, ctl, s, + rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask, access_key_id))); + /* TODO(rzarzynski): replace with static_ptr. */ + return aplptr_t(new decltype(apl)(std::move(apl))); + } + + aplptr_t create_apl_turl(CephContext* const cct, + const req_state* const s, + const RGWUserInfo& user_info) const override { + /* TempURL doesn't need any user account override. It's a Swift-specific + * mechanism that requires account name internally, so there is no + * business with delegating the responsibility outside. */ + return aplptr_t(new rgw::auth::swift::TempURLApplier(cct, user_info)); + } + +public: + DefaultStrategy(CephContext* const cct, + ImplicitTenants& implicit_tenant_context, + RGWCtl* const ctl) + : ctl(ctl), + implicit_tenant_context(implicit_tenant_context), + tempurl_engine(cct, + ctl, + static_cast(this)), + signed_engine(cct, + ctl, + static_cast(this), + static_cast(this)), + external_engine(cct, + ctl, + static_cast(this), + static_cast(this)), + anon_engine(cct, + static_cast(this), + static_cast(this)) { + /* When the constructor's body is being executed, all member engines + * should be initialized. Thus, we can safely add them. */ + using Control = rgw::auth::Strategy::Control; + + add_engine(Control::SUFFICIENT, tempurl_engine); + add_engine(Control::SUFFICIENT, signed_engine); + + /* The auth strategy is responsible for deciding whether a parcular + * engine is disabled or not. */ + if (! cct->_conf->rgw_keystone_url.empty()) { + keystone_engine.emplace(cct, + static_cast(this), + static_cast(this), + keystone_config_t::get_instance(), + keystone_cache_t::get_instance()); + + add_engine(Control::SUFFICIENT, *keystone_engine); + } + if (! cct->_conf->rgw_swift_auth_url.empty()) { + add_engine(Control::SUFFICIENT, external_engine); + } + + add_engine(Control::SUFFICIENT, anon_engine); + } + + const char* get_name() const noexcept override { + return "rgw::auth::swift::DefaultStrategy"; + } +}; + +} /* namespace swift */ +} /* namespace auth */ +} /* namespace rgw */ + + +class RGW_SWIFT_Auth_Get : public RGWOp { +public: + RGW_SWIFT_Auth_Get() {} + ~RGW_SWIFT_Auth_Get() override {} + + int verify_permission(optional_yield) override { return 0; } + void execute(optional_yield y) override; + const char* name() const override { return "swift_auth_get"; } + dmc::client_id dmclock_client() override { return dmc::client_id::auth; } +}; + +class RGWHandler_SWIFT_Auth : public RGWHandler_REST { +public: + RGWHandler_SWIFT_Auth() {} + ~RGWHandler_SWIFT_Auth() override {} + RGWOp *op_get() override; + + int init(rgw::sal::RGWRadosStore *store, struct req_state *state, rgw::io::BasicClient *cio) override; + int authorize(const DoutPrefixProvider *dpp, optional_yield y) override; + int postauth_init(optional_yield) override { return 0; } + int read_permissions(RGWOp *op, optional_yield) override { return 0; } + + virtual RGWAccessControlPolicy *alloc_policy() { return NULL; } + virtual void free_policy(RGWAccessControlPolicy *policy) {} +}; + +class RGWRESTMgr_SWIFT_Auth : public RGWRESTMgr { +public: + RGWRESTMgr_SWIFT_Auth() = default; + ~RGWRESTMgr_SWIFT_Auth() override = default; + + RGWRESTMgr *get_resource_mgr(struct req_state* const s, + const std::string& uri, + std::string* const out_uri) override { + return this; + } + + RGWHandler_REST* get_handler(rgw::sal::RGWRadosStore *store, + struct req_state*, + const rgw::auth::StrategyRegistry&, + const std::string&) override { + return new RGWHandler_SWIFT_Auth; + } +}; + + +#endif -- cgit v1.2.3