From 1f7a802ef15daf2dbed14990efe3c59c2711fbbe Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Tue, 13 Dec 2016 15:28:10 +0100 Subject: [PATCH] rgw: implement rgw::auth::swift::DefaultStrategy. Signed-off-by: Radoslaw Zarzynski --- src/rgw/rgw_rest_swift.cc | 38 ++++++++++++++ src/rgw/rgw_rest_swift.h | 1 + src/rgw/rgw_swift_auth.h | 103 ++++++++++++++++++++++++++++++++++++++ 3 files changed, 142 insertions(+) diff --git a/src/rgw/rgw_rest_swift.cc b/src/rgw/rgw_rest_swift.cc index 1af9612e888..99ab54653c0 100644 --- a/src/rgw/rgw_rest_swift.cc +++ b/src/rgw/rgw_rest_swift.cc @@ -2077,6 +2077,44 @@ int RGWHandler_REST_SWIFT::authorize() } } aplfact(store, s->account_name); + + auto strategy = rgw::auth::swift::DefaultStrategy::get_instance(); + rgw::auth::Applier::aplptr_t applier; + rgw::auth::Completer::cmplptr_t completer; + + std::tie(applier, completer) = strategy.authenticate(s); + + try { + if (! applier) { + /* Access denied is acknowledged by returning a std::unique_ptr with + * nullptr inside. */ + ldout(s->cct, 5) << "auth engine refused to authenicate" << dendl; + return -EPERM; + } + + try { + /* Account used by a given RGWOp is decoupled from identity employed + * in the authorization phase (RGWOp::verify_permissions). */ + applier->load_acct_info(*s->user); + //s->perm_mask = applier->get_perm_mask(); + + /* This is the signle place where we pass req_state as a pointer + * to non-const and thus its modification is allowed. In the time + * of writing only RGWTempURLEngine needed that feature. */ + applier->modify_request_state(s); + + // FIXME + //applier->load_identity(); + //s->auth_identity = std::move(applier); + } catch (int err) { + ldout(s->cct, 5) << "applier throwed err=" << err << dendl; + return err; + } + } catch (int err) { + ldout(s->cct, 5) << "auth engine throwed err=" << err << dendl; + return err; + } + /* Extractors. */ RGWXAuthTokenExtractor token_extr(s); diff --git a/src/rgw/rgw_rest_swift.h b/src/rgw/rgw_rest_swift.h index f8713be5a17..c5c5e335965 100644 --- a/src/rgw/rgw_rest_swift.h +++ b/src/rgw/rgw_rest_swift.h @@ -10,6 +10,7 @@ #include "rgw_op.h" #include "rgw_rest.h" +#include "rgw_swift_auth.h" class RGWGetObj_ObjStore_SWIFT : public RGWGetObj_ObjStore { int custom_http_ret = 0; diff --git a/src/rgw/rgw_swift_auth.h b/src/rgw/rgw_swift_auth.h index 1619d9bb7c5..3a0d950f098 100644 --- a/src/rgw/rgw_swift_auth.h +++ b/src/rgw/rgw_swift_auth.h @@ -7,6 +7,7 @@ #include "rgw_op.h" #include "rgw_rest.h" #include "rgw_auth.h" +#include "rgw_auth_keystone.h" #define RGW_SWIFT_TOKEN_EXPIRATION (15 * 60) @@ -124,6 +125,108 @@ public: }; +namespace rgw { +namespace auth { +namespace swift { + +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 { + RGWRados* const store; + + /* The engines. */ + const rgw::auth::swift::TempURLEngine tempurl_engine; + const rgw::auth::swift::SignedTokenEngine signed_engine; + const rgw::auth::keystone::TokenEngine keystone_engine; + const rgw::auth::swift::ExternalTokenEngine external_engine; + const rgw::auth::AnonymousEngine 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, + acl_strategy_t&& extra_acl_strategy, + const rgw::auth::RemoteApplier::AuthInfo info) const override { + return aplptr_t( + new rgw::auth::RemoteApplier(cct, store, std::move(extra_acl_strategy), 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)); + } + + aplptr_t create_apl_turl(CephContext* const cct, + 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, + RGWRados* const store) + : store(store), + tempurl_engine(cct, + store, + static_cast(this)), + signed_engine(cct, + store, + static_cast(this), + static_cast(this)), + keystone_engine(cct, + static_cast(this), + static_cast(this), + keystone_config_t::get_instance(), + keystone_cache_t::get_instance()), + external_engine(cct, + store, + static_cast(this), + static_cast(this)), + anon_engine(cct, + 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()) { + 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() {}