1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
6 #include "rgw_common.h"
11 #include "rgw_auth_keystone.h"
12 #include "rgw_auth_filters.h"
15 #define RGW_SWIFT_TOKEN_EXPIRATION (15 * 60)
21 /* TempURL: applier. */
22 class TempURLApplier
: public rgw::auth::LocalApplier
{
24 TempURLApplier(CephContext
* const cct
,
25 const RGWUserInfo
& user_info
)
26 : LocalApplier(cct
, user_info
, LocalApplier::NO_SUBUSER
, std::nullopt
, LocalApplier::NO_ACCESS_KEY
) {
29 void modify_request_state(const DoutPrefixProvider
* dpp
, req_state
* s
) const override
; /* in/out */
30 void write_ops_log_entry(rgw_log_entry
& entry
) const override
;
34 virtual aplptr_t
create_apl_turl(CephContext
* cct
,
36 const RGWUserInfo
& user_info
) const = 0;
41 class TempURLEngine
: public rgw::auth::Engine
{
42 using result_t
= rgw::auth::Engine::result_t
;
44 CephContext
* const cct
;
45 rgw::sal::Driver
* driver
;
46 const TempURLApplier::Factory
* const apl_factory
;
49 void get_owner_info(const DoutPrefixProvider
* dpp
,
51 RGWUserInfo
& owner_info
,
52 optional_yield y
) const;
53 std::string
convert_from_iso8601(std::string expires
) const;
54 bool is_applicable(const req_state
* s
) const noexcept
;
55 bool is_expired(const std::string
& expires
) const;
56 bool is_disallowed_header_present(const req_info
& info
) const;
58 class SignatureHelper
;
59 class PrefixableSignatureHelper
;
62 TempURLEngine(CephContext
* const cct
,
63 rgw::sal::Driver
* _driver
,
64 const TempURLApplier::Factory
* const apl_factory
)
67 apl_factory(apl_factory
) {
70 /* Interface implementations. */
71 const char* get_name() const noexcept override
{
72 return "rgw::auth::swift::TempURLEngine";
75 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
, optional_yield y
) const override
;
80 class SignedTokenEngine
: public rgw::auth::Engine
{
81 using result_t
= rgw::auth::Engine::result_t
;
83 CephContext
* const cct
;
84 rgw::sal::Driver
* driver
;
85 const rgw::auth::TokenExtractor
* const extractor
;
86 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
88 bool is_applicable(const std::string
& token
) const noexcept
;
89 using rgw::auth::Engine::authenticate
;
90 result_t
authenticate(const DoutPrefixProvider
* dpp
,
91 const std::string
& token
,
92 const req_state
* s
) const;
95 SignedTokenEngine(CephContext
* const cct
,
96 rgw::sal::Driver
* _driver
,
97 const rgw::auth::TokenExtractor
* const extractor
,
98 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
101 extractor(extractor
),
102 apl_factory(apl_factory
) {
105 const char* get_name() const noexcept override
{
106 return "rgw::auth::swift::SignedTokenEngine";
109 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
,
110 optional_yield y
) const override
{
111 return authenticate(dpp
, extractor
->get_token(s
), s
);
117 class ExternalTokenEngine
: public rgw::auth::Engine
{
118 using result_t
= rgw::auth::Engine::result_t
;
120 CephContext
* const cct
;
121 rgw::sal::Driver
* driver
;
122 const rgw::auth::TokenExtractor
* const extractor
;
123 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
125 bool is_applicable(const std::string
& token
) const noexcept
;
126 result_t
authenticate(const DoutPrefixProvider
* dpp
,
127 const std::string
& token
,
128 const req_state
* s
, optional_yield y
) const;
131 ExternalTokenEngine(CephContext
* const cct
,
132 rgw::sal::Driver
* _driver
,
133 const rgw::auth::TokenExtractor
* const extractor
,
134 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
137 extractor(extractor
),
138 apl_factory(apl_factory
) {
141 const char* get_name() const noexcept override
{
142 return "rgw::auth::swift::ExternalTokenEngine";
145 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
,
146 optional_yield y
) const override
{
147 return authenticate(dpp
, extractor
->get_token(s
), s
, y
);
151 /* SwiftAnonymous: applier. */
152 class SwiftAnonymousApplier
: public rgw::auth::LocalApplier
{
154 SwiftAnonymousApplier(CephContext
* const cct
,
155 const RGWUserInfo
& user_info
)
156 : LocalApplier(cct
, user_info
, LocalApplier::NO_SUBUSER
, std::nullopt
, LocalApplier::NO_ACCESS_KEY
) {
158 bool is_admin_of(const rgw_user
& uid
) const {return false;}
159 bool is_owner_of(const rgw_user
& uid
) const {return uid
.id
.compare(RGW_USER_ANON_ID
) == 0;}
162 class SwiftAnonymousEngine
: public rgw::auth::AnonymousEngine
{
163 const rgw::auth::TokenExtractor
* const extractor
;
165 bool is_applicable(const req_state
* s
) const noexcept override
{
166 return extractor
->get_token(s
).empty();
170 SwiftAnonymousEngine(CephContext
* const cct
,
171 const SwiftAnonymousApplier::Factory
* const apl_factory
,
172 const rgw::auth::TokenExtractor
* const extractor
)
173 : AnonymousEngine(cct
, apl_factory
),
174 extractor(extractor
) {
177 const char* get_name() const noexcept override
{
178 return "rgw::auth::swift::SwiftAnonymousEngine";
183 class DefaultStrategy
: public rgw::auth::Strategy
,
184 public rgw::auth::RemoteApplier::Factory
,
185 public rgw::auth::LocalApplier::Factory
,
186 public rgw::auth::swift::TempURLApplier::Factory
{
187 rgw::sal::Driver
* driver
;
188 const ImplicitTenants
& implicit_tenant_context
;
191 const rgw::auth::swift::TempURLEngine tempurl_engine
;
192 const rgw::auth::swift::SignedTokenEngine signed_engine
;
193 boost::optional
<const rgw::auth::keystone::TokenEngine
> keystone_engine
;
194 const rgw::auth::swift::ExternalTokenEngine external_engine
;
195 const rgw::auth::swift::SwiftAnonymousEngine anon_engine
;
197 using keystone_config_t
= rgw::keystone::CephCtxConfig
;
198 using keystone_cache_t
= rgw::keystone::TokenCache
;
199 using aplptr_t
= rgw::auth::IdentityApplier::aplptr_t
;
200 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
202 /* The method implements TokenExtractor for X-Auth-Token present in req_state. */
203 struct AuthTokenExtractor
: rgw::auth::TokenExtractor
{
204 std::string
get_token(const req_state
* const s
) const override
{
205 /* Returning a reference here would end in GCC complaining about a reference
207 return s
->info
.env
->get("HTTP_X_AUTH_TOKEN", "");
209 } auth_token_extractor
;
211 /* The method implements TokenExtractor for X-Service-Token present in req_state. */
212 struct ServiceTokenExtractor
: rgw::auth::TokenExtractor
{
213 std::string
get_token(const req_state
* const s
) const override
{
214 return s
->info
.env
->get("HTTP_X_SERVICE_TOKEN", "");
216 } service_token_extractor
;
218 aplptr_t
create_apl_remote(CephContext
* const cct
,
219 const req_state
* const s
,
220 acl_strategy_t
&& extra_acl_strategy
,
221 const rgw::auth::RemoteApplier::AuthInfo
&info
) const override
{
223 rgw::auth::add_3rdparty(driver
, rgw_user(s
->account_name
),
224 rgw::auth::add_sysreq(cct
, driver
, s
,
225 rgw::auth::RemoteApplier(cct
, driver
, std::move(extra_acl_strategy
), info
,
226 implicit_tenant_context
,
227 rgw::auth::ImplicitTenants::IMPLICIT_TENANTS_SWIFT
)));
228 /* TODO(rzarzynski): replace with static_ptr. */
229 return aplptr_t(new decltype(apl
)(std::move(apl
)));
232 aplptr_t
create_apl_local(CephContext
* const cct
,
233 const req_state
* const s
,
234 const RGWUserInfo
& user_info
,
235 const std::string
& subuser
,
236 const std::optional
<uint32_t>& perm_mask
,
237 const std::string
& access_key_id
) const override
{
239 rgw::auth::add_3rdparty(driver
, rgw_user(s
->account_name
),
240 rgw::auth::add_sysreq(cct
, driver
, s
,
241 rgw::auth::LocalApplier(cct
, user_info
, subuser
, perm_mask
, access_key_id
)));
242 /* TODO(rzarzynski): replace with static_ptr. */
243 return aplptr_t(new decltype(apl
)(std::move(apl
)));
246 aplptr_t
create_apl_turl(CephContext
* const cct
,
247 const req_state
* const s
,
248 const RGWUserInfo
& user_info
) const override
{
249 /* TempURL doesn't need any user account override. It's a Swift-specific
250 * mechanism that requires account name internally, so there is no
251 * business with delegating the responsibility outside. */
252 return aplptr_t(new rgw::auth::swift::TempURLApplier(cct
, user_info
));
256 DefaultStrategy(CephContext
* const cct
,
257 const ImplicitTenants
& implicit_tenant_context
,
258 rgw::sal::Driver
* _driver
)
260 implicit_tenant_context(implicit_tenant_context
),
263 static_cast<rgw::auth::swift::TempURLApplier::Factory
*>(this)),
266 static_cast<rgw::auth::TokenExtractor
*>(&auth_token_extractor
),
267 static_cast<rgw::auth::LocalApplier::Factory
*>(this)),
270 static_cast<rgw::auth::TokenExtractor
*>(&auth_token_extractor
),
271 static_cast<rgw::auth::LocalApplier::Factory
*>(this)),
273 static_cast<SwiftAnonymousApplier::Factory
*>(this),
274 static_cast<rgw::auth::TokenExtractor
*>(&auth_token_extractor
)) {
275 /* When the constructor's body is being executed, all member engines
276 * should be initialized. Thus, we can safely add them. */
277 using Control
= rgw::auth::Strategy::Control
;
279 add_engine(Control::SUFFICIENT
, tempurl_engine
);
280 add_engine(Control::SUFFICIENT
, signed_engine
);
282 /* The auth strategy is responsible for deciding whether a parcular
283 * engine is disabled or not. */
284 if (! cct
->_conf
->rgw_keystone_url
.empty()) {
285 keystone_engine
.emplace(cct
,
286 static_cast<rgw::auth::TokenExtractor
*>(&auth_token_extractor
),
287 static_cast<rgw::auth::TokenExtractor
*>(&service_token_extractor
),
288 static_cast<rgw::auth::RemoteApplier::Factory
*>(this),
289 keystone_config_t::get_instance(),
290 keystone_cache_t::get_instance
<keystone_config_t
>());
292 add_engine(Control::SUFFICIENT
, *keystone_engine
);
294 if (! cct
->_conf
->rgw_swift_auth_url
.empty()) {
295 add_engine(Control::SUFFICIENT
, external_engine
);
298 add_engine(Control::SUFFICIENT
, anon_engine
);
301 const char* get_name() const noexcept override
{
302 return "rgw::auth::swift::DefaultStrategy";
306 } /* namespace swift */
307 } /* namespace auth */
308 } /* namespace rgw */
311 class RGW_SWIFT_Auth_Get
: public RGWOp
{
313 RGW_SWIFT_Auth_Get() {}
314 ~RGW_SWIFT_Auth_Get() override
{}
316 int verify_permission(optional_yield
) override
{ return 0; }
317 void execute(optional_yield y
) override
;
318 const char* name() const override
{ return "swift_auth_get"; }
319 dmc::client_id
dmclock_client() override
{ return dmc::client_id::auth
; }
322 class RGWHandler_SWIFT_Auth
: public RGWHandler_REST
{
324 RGWHandler_SWIFT_Auth() {}
325 ~RGWHandler_SWIFT_Auth() override
{}
326 RGWOp
*op_get() override
;
328 int init(rgw::sal::Driver
* driver
, req_state
*state
, rgw::io::BasicClient
*cio
) override
;
329 int authorize(const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
330 int postauth_init(optional_yield
) override
{ return 0; }
331 int read_permissions(RGWOp
*op
, optional_yield
) override
{ return 0; }
333 virtual RGWAccessControlPolicy
*alloc_policy() { return NULL
; }
334 virtual void free_policy(RGWAccessControlPolicy
*policy
) {}
337 class RGWRESTMgr_SWIFT_Auth
: public RGWRESTMgr
{
339 RGWRESTMgr_SWIFT_Auth() = default;
340 ~RGWRESTMgr_SWIFT_Auth() override
= default;
342 RGWRESTMgr
*get_resource_mgr(req_state
* const s
,
343 const std::string
& uri
,
344 std::string
* const out_uri
) override
{
348 RGWHandler_REST
* get_handler(rgw::sal::Driver
* driver
,
350 const rgw::auth::StrategyRegistry
&,
351 const std::string
&) override
{
352 return new RGWHandler_SWIFT_Auth
;