From c5f8e8c8c06aec744fee39ed8a31b209ec66c960 Mon Sep 17 00:00:00 2001 From: Radoslaw Zarzynski Date: Thu, 22 Dec 2016 13:48:18 +0100 Subject: [PATCH] rgw: port Swift's Signed and External auth engines. Signed-off-by: Radoslaw Zarzynski --- src/rgw/rgw_swift_auth.cc | 72 ++++++++++++++++++++----------- src/rgw/rgw_swift_auth.h | 90 ++++++++++++++++++++------------------- 2 files changed, 93 insertions(+), 69 deletions(-) diff --git a/src/rgw/rgw_swift_auth.cc b/src/rgw/rgw_swift_auth.cc index 8ff4473a6d245..03f440120644c 100644 --- a/src/rgw/rgw_swift_auth.cc +++ b/src/rgw/rgw_swift_auth.cc @@ -271,19 +271,30 @@ RGWAuthApplier::aplptr_t RGWTempURLAuthEngine::authenticate() const } +namespace rgw { +namespace auth { +namespace swift { + /* External token */ -bool RGWExternalTokenAuthEngine::is_applicable() const noexcept +bool ExternalTokenEngine::is_applicable(const std::string& token) const noexcept { - if (false == RGWTokenBasedAuthEngine::is_applicable()) { + if (token.empty()) { + return false; + } else if (g_conf->rgw_swift_auth_url.empty()) { return false; + } else { + return true; } - - return false == g_conf->rgw_swift_auth_url.empty(); } -RGWAuthApplier::aplptr_t RGWExternalTokenAuthEngine::authenticate() const +ExternalTokenEngine::result_t +ExternalTokenEngine::authenticate(const std::string& token) const { - string auth_url = g_conf->rgw_swift_auth_url; + if (! is_applicable(token)) { + return std::make_pair(nullptr, nullptr); + } + + std::string auth_url = g_conf->rgw_swift_auth_url; if (auth_url[auth_url.length() - 1] != '/') { auth_url.append("/"); } @@ -308,17 +319,17 @@ RGWAuthApplier::aplptr_t RGWExternalTokenAuthEngine::authenticate() const ",", swift_groups); if (0 == swift_groups.size()) { - return nullptr; + return std::make_pair(nullptr, nullptr); } else { swift_user = std::move(swift_groups[0]); } } catch (std::out_of_range) { /* The X-Auth-Groups header isn't present in the response. */ - return nullptr; + return std::make_pair(nullptr, nullptr); } if (swift_user.empty()) { - return nullptr; + return std::make_pair(nullptr, nullptr); } ldout(cct, 10) << "swift user=" << swift_user << dendl; @@ -330,11 +341,11 @@ RGWAuthApplier::aplptr_t RGWExternalTokenAuthEngine::authenticate() const throw ret; } - return apl_factory->create_apl_local(cct, tmp_uinfo, - extract_swift_subuser(swift_user)); + auto apl = apl_factory->create_apl_local(cct, tmp_uinfo, + extract_swift_subuser(swift_user)); + return std::make_pair(std::move(apl), nullptr); } - static int build_token(const string& swift_user, const string& key, const uint64_t nonce, @@ -382,17 +393,22 @@ static int encode_token(CephContext *cct, string& swift_user, string& key, /* AUTH_rgwtk (signed token): engine */ -bool RGWSignedTokenAuthEngine::is_applicable() const noexcept +bool SignedTokenEngine::is_applicable(const std::string& token) const noexcept { - if (false == RGWTokenBasedAuthEngine::is_applicable()) { + if (token.empty()) { return false; + } else { + return token.compare(0, 10, "AUTH_rgwtk") == 0; } - - return token.compare(0, 10, "AUTH_rgwtk") == 0; } -RGWAuthApplier::aplptr_t RGWSignedTokenAuthEngine::authenticate() const +SignedTokenEngine::result_t +SignedTokenEngine::authenticate(const std::string& token) const { + if (! is_applicable(token)) { + return std::make_pair(nullptr, nullptr); + } + /* Effective token string is the part after the prefix. */ const std::string etoken = token.substr(strlen("AUTH_rgwtk")); const size_t etoken_len = etoken.length(); @@ -403,13 +419,13 @@ RGWAuthApplier::aplptr_t RGWSignedTokenAuthEngine::authenticate() const throw -EINVAL; } - bufferptr p(etoken_len/2); + ceph::bufferptr p(etoken_len/2); int ret = hex_to_buf(etoken.c_str(), p.c_str(), etoken_len); if (ret < 0) { throw ret; } - bufferlist tok_bl; + ceph::bufferlist tok_bl; tok_bl.append(p); uint64_t nonce; @@ -432,7 +448,7 @@ RGWAuthApplier::aplptr_t RGWSignedTokenAuthEngine::authenticate() const ldout(cct, 0) << "NOTICE: old timed out token was used now=" << now << " token.expiration=" << expiration << dendl; - return nullptr; + return std::make_pair(nullptr, nullptr); } RGWUserInfo user_info; @@ -445,7 +461,7 @@ RGWAuthApplier::aplptr_t RGWSignedTokenAuthEngine::authenticate() const const auto siter = user_info.swift_keys.find(swift_user); if (siter == std::end(user_info.swift_keys)) { - return nullptr; + return std::make_pair(nullptr, nullptr); } const auto swift_key = siter->second; @@ -461,7 +477,7 @@ RGWAuthApplier::aplptr_t RGWSignedTokenAuthEngine::authenticate() const << " tok_bl.length()=" << tok_bl.length() << " local_tok_bl.length()=" << local_tok_bl.length() << dendl; - return nullptr; + return std::make_pair(nullptr, nullptr); } if (memcmp(local_tok_bl.c_str(), tok_bl.c_str(), @@ -472,13 +488,18 @@ RGWAuthApplier::aplptr_t RGWSignedTokenAuthEngine::authenticate() const local_tok_bl.length(), buf); ldout(cct, 0) << "NOTICE: tokens mismatch tok=" << buf << dendl; - return nullptr; + return std::make_pair(nullptr, nullptr); } - return apl_factory->create_apl_local(cct, user_info, - extract_swift_subuser(swift_user)); + auto apl = apl_factory->create_apl_local(cct, user_info, + extract_swift_subuser(swift_user)); + return std::make_pair(std::move(apl), nullptr); } +} /* namespace swift */ +} /* namespace auth */ +} /* namespace rgw */ + void RGW_SWIFT_Auth_Get::execute() { @@ -577,6 +598,7 @@ void RGW_SWIFT_Auth_Get::execute() dump_header(s, "X-Storage-Url", swift_url + swift_prefix + "/v1" + tenant_path); + using rgw::auth::swift::encode_token; if ((ret = encode_token(s->cct, swift_key->id, swift_key->key, bl)) < 0) goto done; diff --git a/src/rgw/rgw_swift_auth.h b/src/rgw/rgw_swift_auth.h index 3a0d950f098a8..e12bed6d6c7b0 100644 --- a/src/rgw/rgw_swift_auth.h +++ b/src/rgw/rgw_swift_auth.h @@ -8,6 +8,7 @@ #include "rgw_rest.h" #include "rgw_auth.h" #include "rgw_auth_keystone.h" +#include "rgw_auth_filters.h" #define RGW_SWIFT_TOKEN_EXPIRATION (15 * 60) @@ -61,74 +62,75 @@ public: }; +namespace rgw { +namespace auth { +namespace swift { + /* AUTH_rgwtk */ -class RGWSignedTokenAuthEngine : public RGWTokenBasedAuthEngine { -protected: - /* const */ RGWRados * const store; - const RGWLocalAuthApplier::Factory * apl_factory; +class SignedTokenEngine : public rgw::auth::Engine { + using result_t = rgw::auth::Engine::result_t; + + CephContext* const cct; + RGWRados* const store; + 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 std::string& token) const; + public: - RGWSignedTokenAuthEngine(CephContext * const cct, - /* const */RGWRados * const store, - const Extractor& extr, - const RGWLocalAuthApplier::Factory * const apl_factory) - : RGWTokenBasedAuthEngine(cct, extr), + SignedTokenEngine(CephContext* const cct, + /* const */RGWRados* const store, + const rgw::auth::TokenExtractor* const extractor, + const rgw::auth::LocalApplier::Factory* const apl_factory) + : cct(cct), store(store), + extractor(extractor), apl_factory(apl_factory) { } const char* get_name() const noexcept override { - return "RGWSignedTokenAuthEngine"; + return "rgw::auth::swift::SignedTokenEngine"; } - bool is_applicable() const noexcept override; - RGWAuthApplier::aplptr_t authenticate() const override; + result_t authenticate(const req_state* const s) const override { + return authenticate(extractor->get_token(s)); + } }; /* External token */ -class RGWExternalTokenAuthEngine : public RGWTokenBasedAuthEngine { -protected: - /* const */ RGWRados * const store; - const RGWLocalAuthApplier::Factory * const apl_factory; +class ExternalTokenEngine : public rgw::auth::Engine { + using result_t = rgw::auth::Engine::result_t; + + CephContext* const cct; + RGWRados* const store; + 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 std::string& token) const; + public: - RGWExternalTokenAuthEngine(CephContext * const cct, - /* const */RGWRados * const store, - const Extractor& extr, - const RGWLocalAuthApplier::Factory * const apl_factory) - : RGWTokenBasedAuthEngine(cct, extr), + ExternalTokenEngine(CephContext* const cct, + /* const */RGWRados* const store, + const rgw::auth::TokenExtractor* const extractor, + const rgw::auth::LocalApplier::Factory* const apl_factory) + : cct(cct), store(store), + extractor(extractor), apl_factory(apl_factory) { } const char* get_name() const noexcept override { - return "RGWExternalTokenAuthEngine"; + return "rgw::auth::swift::ExternalTokenEngine"; } - bool is_applicable() const noexcept override; - RGWAuthApplier::aplptr_t authenticate() const override; -}; - - -/* Extractor for X-Auth-Token present in req_state. */ -class RGWXAuthTokenExtractor : public RGWTokenBasedAuthEngine::Extractor { -protected: - const req_state * const s; -public: - RGWXAuthTokenExtractor(const req_state * const s) - : s(s) { - } - std::string get_token() 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", ""); + result_t authenticate(const req_state* const s) const override { + return authenticate(extractor->get_token(s)); } }; - -namespace rgw { -namespace auth { -namespace swift { - class DefaultStrategy : public rgw::auth::Strategy, public rgw::auth::TokenExtractor, public rgw::auth::RemoteApplier::Factory, -- 2.39.5