1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
4 #ifndef CEPH_RGW_SWIFT_AUTH_H
5 #define CEPH_RGW_SWIFT_AUTH_H
7 #include "rgw_common.h"
12 #include "rgw_auth_keystone.h"
13 #include "rgw_auth_filters.h"
16 #define RGW_SWIFT_TOKEN_EXPIRATION (15 * 60)
22 /* TempURL: applier. */
23 class TempURLApplier
: public rgw::auth::LocalApplier
{
25 TempURLApplier(CephContext
* const cct
,
26 const RGWUserInfo
& user_info
)
27 : LocalApplier(cct
, user_info
, LocalApplier::NO_SUBUSER
, std::nullopt
, LocalApplier::NO_ACCESS_KEY
) {
30 void modify_request_state(const DoutPrefixProvider
* dpp
, req_state
* s
) const override
; /* in/out */
31 void write_ops_log_entry(rgw_log_entry
& entry
) const override
;
35 virtual aplptr_t
create_apl_turl(CephContext
* cct
,
37 const RGWUserInfo
& user_info
) const = 0;
42 class TempURLEngine
: public rgw::auth::Engine
{
43 using result_t
= rgw::auth::Engine::result_t
;
45 CephContext
* const cct
;
46 rgw::sal::Store
* store
;
47 const TempURLApplier::Factory
* const apl_factory
;
50 void get_owner_info(const DoutPrefixProvider
* dpp
,
52 RGWUserInfo
& owner_info
,
53 optional_yield y
) const;
54 std::string
convert_from_iso8601(std::string expires
) const;
55 bool is_applicable(const req_state
* s
) const noexcept
;
56 bool is_expired(const std::string
& expires
) const;
57 bool is_disallowed_header_present(const req_info
& info
) const;
59 class SignatureHelper
;
60 class PrefixableSignatureHelper
;
63 TempURLEngine(CephContext
* const cct
,
64 rgw::sal::Store
* _store
,
65 const TempURLApplier::Factory
* const apl_factory
)
68 apl_factory(apl_factory
) {
71 /* Interface implementations. */
72 const char* get_name() const noexcept override
{
73 return "rgw::auth::swift::TempURLEngine";
76 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
, optional_yield y
) const override
;
81 class SignedTokenEngine
: public rgw::auth::Engine
{
82 using result_t
= rgw::auth::Engine::result_t
;
84 CephContext
* const cct
;
85 rgw::sal::Store
* store
;
86 const rgw::auth::TokenExtractor
* const extractor
;
87 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
89 bool is_applicable(const std::string
& token
) const noexcept
;
90 using rgw::auth::Engine::authenticate
;
91 result_t
authenticate(const DoutPrefixProvider
* dpp
,
92 const std::string
& token
,
93 const req_state
* s
) const;
96 SignedTokenEngine(CephContext
* const cct
,
97 rgw::sal::Store
* _store
,
98 const rgw::auth::TokenExtractor
* const extractor
,
99 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
102 extractor(extractor
),
103 apl_factory(apl_factory
) {
106 const char* get_name() const noexcept override
{
107 return "rgw::auth::swift::SignedTokenEngine";
110 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
,
111 optional_yield y
) const override
{
112 return authenticate(dpp
, extractor
->get_token(s
), s
);
118 class ExternalTokenEngine
: public rgw::auth::Engine
{
119 using result_t
= rgw::auth::Engine::result_t
;
121 CephContext
* const cct
;
122 rgw::sal::Store
* store
;
123 const rgw::auth::TokenExtractor
* const extractor
;
124 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
126 bool is_applicable(const std::string
& token
) const noexcept
;
127 result_t
authenticate(const DoutPrefixProvider
* dpp
,
128 const std::string
& token
,
129 const req_state
* s
, optional_yield y
) const;
132 ExternalTokenEngine(CephContext
* const cct
,
133 rgw::sal::Store
* _store
,
134 const rgw::auth::TokenExtractor
* const extractor
,
135 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
138 extractor(extractor
),
139 apl_factory(apl_factory
) {
142 const char* get_name() const noexcept override
{
143 return "rgw::auth::swift::ExternalTokenEngine";
146 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
,
147 optional_yield y
) const override
{
148 return authenticate(dpp
, extractor
->get_token(s
), s
, y
);
152 /* SwiftAnonymous: applier. */
153 class SwiftAnonymousApplier
: public rgw::auth::LocalApplier
{
155 SwiftAnonymousApplier(CephContext
* const cct
,
156 const RGWUserInfo
& user_info
)
157 : LocalApplier(cct
, user_info
, LocalApplier::NO_SUBUSER
, std::nullopt
, LocalApplier::NO_ACCESS_KEY
) {
159 bool is_admin_of(const rgw_user
& uid
) const {return false;}
160 bool is_owner_of(const rgw_user
& uid
) const {return uid
.id
.compare(RGW_USER_ANON_ID
) == 0;}
163 class SwiftAnonymousEngine
: public rgw::auth::AnonymousEngine
{
164 const rgw::auth::TokenExtractor
* const extractor
;
166 bool is_applicable(const req_state
* s
) const noexcept override
{
167 return extractor
->get_token(s
).empty();
171 SwiftAnonymousEngine(CephContext
* const cct
,
172 const SwiftAnonymousApplier::Factory
* const apl_factory
,
173 const rgw::auth::TokenExtractor
* const extractor
)
174 : AnonymousEngine(cct
, apl_factory
),
175 extractor(extractor
) {
178 const char* get_name() const noexcept override
{
179 return "rgw::auth::swift::SwiftAnonymousEngine";
184 class DefaultStrategy
: public rgw::auth::Strategy
,
185 public rgw::auth::TokenExtractor
,
186 public rgw::auth::RemoteApplier::Factory
,
187 public rgw::auth::LocalApplier::Factory
,
188 public rgw::auth::swift::TempURLApplier::Factory
{
189 rgw::sal::Store
* store
;
190 ImplicitTenants
& implicit_tenant_context
;
193 const rgw::auth::swift::TempURLEngine tempurl_engine
;
194 const rgw::auth::swift::SignedTokenEngine signed_engine
;
195 boost::optional
<const rgw::auth::keystone::TokenEngine
> keystone_engine
;
196 const rgw::auth::swift::ExternalTokenEngine external_engine
;
197 const rgw::auth::swift::SwiftAnonymousEngine anon_engine
;
199 using keystone_config_t
= rgw::keystone::CephCtxConfig
;
200 using keystone_cache_t
= rgw::keystone::TokenCache
;
201 using aplptr_t
= rgw::auth::IdentityApplier::aplptr_t
;
202 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
204 /* The method implements TokenExtractor for X-Auth-Token present in req_state. */
205 std::string
get_token(const req_state
* const s
) const override
{
206 /* Returning a reference here would end in GCC complaining about a reference
208 return s
->info
.env
->get("HTTP_X_AUTH_TOKEN", "");
211 aplptr_t
create_apl_remote(CephContext
* const cct
,
212 const req_state
* const s
,
213 acl_strategy_t
&& extra_acl_strategy
,
214 const rgw::auth::RemoteApplier::AuthInfo
&info
) const override
{
216 rgw::auth::add_3rdparty(store
, rgw_user(s
->account_name
),
217 rgw::auth::add_sysreq(cct
, store
, s
,
218 rgw::auth::RemoteApplier(cct
, store
, std::move(extra_acl_strategy
), info
,
219 implicit_tenant_context
,
220 rgw::auth::ImplicitTenants::IMPLICIT_TENANTS_SWIFT
)));
221 /* TODO(rzarzynski): replace with static_ptr. */
222 return aplptr_t(new decltype(apl
)(std::move(apl
)));
225 aplptr_t
create_apl_local(CephContext
* const cct
,
226 const req_state
* const s
,
227 const RGWUserInfo
& user_info
,
228 const std::string
& subuser
,
229 const std::optional
<uint32_t>& perm_mask
,
230 const std::string
& access_key_id
) const override
{
232 rgw::auth::add_3rdparty(store
, rgw_user(s
->account_name
),
233 rgw::auth::add_sysreq(cct
, store
, s
,
234 rgw::auth::LocalApplier(cct
, user_info
, subuser
, perm_mask
, access_key_id
)));
235 /* TODO(rzarzynski): replace with static_ptr. */
236 return aplptr_t(new decltype(apl
)(std::move(apl
)));
239 aplptr_t
create_apl_turl(CephContext
* const cct
,
240 const req_state
* const s
,
241 const RGWUserInfo
& user_info
) const override
{
242 /* TempURL doesn't need any user account override. It's a Swift-specific
243 * mechanism that requires account name internally, so there is no
244 * business with delegating the responsibility outside. */
245 return aplptr_t(new rgw::auth::swift::TempURLApplier(cct
, user_info
));
249 DefaultStrategy(CephContext
* const cct
,
250 ImplicitTenants
& implicit_tenant_context
,
251 rgw::sal::Store
* _store
)
253 implicit_tenant_context(implicit_tenant_context
),
256 static_cast<rgw::auth::swift::TempURLApplier::Factory
*>(this)),
259 static_cast<rgw::auth::TokenExtractor
*>(this),
260 static_cast<rgw::auth::LocalApplier::Factory
*>(this)),
263 static_cast<rgw::auth::TokenExtractor
*>(this),
264 static_cast<rgw::auth::LocalApplier::Factory
*>(this)),
266 static_cast<SwiftAnonymousApplier::Factory
*>(this),
267 static_cast<rgw::auth::TokenExtractor
*>(this)) {
268 /* When the constructor's body is being executed, all member engines
269 * should be initialized. Thus, we can safely add them. */
270 using Control
= rgw::auth::Strategy::Control
;
272 add_engine(Control::SUFFICIENT
, tempurl_engine
);
273 add_engine(Control::SUFFICIENT
, signed_engine
);
275 /* The auth strategy is responsible for deciding whether a parcular
276 * engine is disabled or not. */
277 if (! cct
->_conf
->rgw_keystone_url
.empty()) {
278 keystone_engine
.emplace(cct
,
279 static_cast<rgw::auth::TokenExtractor
*>(this),
280 static_cast<rgw::auth::RemoteApplier::Factory
*>(this),
281 keystone_config_t::get_instance(),
282 keystone_cache_t::get_instance
<keystone_config_t
>());
284 add_engine(Control::SUFFICIENT
, *keystone_engine
);
286 if (! cct
->_conf
->rgw_swift_auth_url
.empty()) {
287 add_engine(Control::SUFFICIENT
, external_engine
);
290 add_engine(Control::SUFFICIENT
, anon_engine
);
293 const char* get_name() const noexcept override
{
294 return "rgw::auth::swift::DefaultStrategy";
298 } /* namespace swift */
299 } /* namespace auth */
300 } /* namespace rgw */
303 class RGW_SWIFT_Auth_Get
: public RGWOp
{
305 RGW_SWIFT_Auth_Get() {}
306 ~RGW_SWIFT_Auth_Get() override
{}
308 int verify_permission(optional_yield
) override
{ return 0; }
309 void execute(optional_yield y
) override
;
310 const char* name() const override
{ return "swift_auth_get"; }
311 dmc::client_id
dmclock_client() override
{ return dmc::client_id::auth
; }
314 class RGWHandler_SWIFT_Auth
: public RGWHandler_REST
{
316 RGWHandler_SWIFT_Auth() {}
317 ~RGWHandler_SWIFT_Auth() override
{}
318 RGWOp
*op_get() override
;
320 int init(rgw::sal::Store
* store
, struct req_state
*state
, rgw::io::BasicClient
*cio
) override
;
321 int authorize(const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
322 int postauth_init(optional_yield
) override
{ return 0; }
323 int read_permissions(RGWOp
*op
, optional_yield
) override
{ return 0; }
325 virtual RGWAccessControlPolicy
*alloc_policy() { return NULL
; }
326 virtual void free_policy(RGWAccessControlPolicy
*policy
) {}
329 class RGWRESTMgr_SWIFT_Auth
: public RGWRESTMgr
{
331 RGWRESTMgr_SWIFT_Auth() = default;
332 ~RGWRESTMgr_SWIFT_Auth() override
= default;
334 RGWRESTMgr
*get_resource_mgr(struct req_state
* const s
,
335 const std::string
& uri
,
336 std::string
* const out_uri
) override
{
340 RGWHandler_REST
* get_handler(rgw::sal::Store
* store
,
342 const rgw::auth::StrategyRegistry
&,
343 const std::string
&) override
{
344 return new RGWHandler_SWIFT_Auth
;