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
, boost::none
) {
30 void modify_request_state(const DoutPrefixProvider
* dpp
, req_state
* s
) const override
; /* in/out */
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 /* const */ RGWCtl
* const ctl
;
46 const TempURLApplier::Factory
* const apl_factory
;
49 void get_owner_info(const DoutPrefixProvider
* dpp
,
51 RGWUserInfo
& owner_info
) const;
52 std::string
convert_from_iso8601(std::string expires
) const;
53 bool is_applicable(const req_state
* s
) const noexcept
;
54 bool is_expired(const std::string
& expires
) const;
55 bool is_disallowed_header_present(const req_info
& info
) const;
57 class SignatureHelper
;
58 class PrefixableSignatureHelper
;
61 TempURLEngine(CephContext
* const cct
,
62 /*const*/ RGWCtl
* const ctl
,
63 const TempURLApplier::Factory
* const apl_factory
)
66 apl_factory(apl_factory
) {
69 /* Interface implementations. */
70 const char* get_name() const noexcept override
{
71 return "rgw::auth::swift::TempURLEngine";
74 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
) const override
;
79 class SignedTokenEngine
: public rgw::auth::Engine
{
80 using result_t
= rgw::auth::Engine::result_t
;
82 CephContext
* const cct
;
84 const rgw::auth::TokenExtractor
* const extractor
;
85 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
87 bool is_applicable(const std::string
& token
) const noexcept
;
88 result_t
authenticate(const DoutPrefixProvider
* dpp
,
89 const std::string
& token
,
90 const req_state
* s
) const;
93 SignedTokenEngine(CephContext
* const cct
,
94 /* const */RGWCtl
* const ctl
,
95 const rgw::auth::TokenExtractor
* const extractor
,
96 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
100 apl_factory(apl_factory
) {
103 const char* get_name() const noexcept override
{
104 return "rgw::auth::swift::SignedTokenEngine";
107 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
) const override
{
108 return authenticate(dpp
, extractor
->get_token(s
), s
);
114 class ExternalTokenEngine
: public rgw::auth::Engine
{
115 using result_t
= rgw::auth::Engine::result_t
;
117 CephContext
* const cct
;
119 const rgw::auth::TokenExtractor
* const extractor
;
120 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
122 bool is_applicable(const std::string
& token
) const noexcept
;
123 result_t
authenticate(const DoutPrefixProvider
* dpp
,
124 const std::string
& token
,
125 const req_state
* s
) const;
128 ExternalTokenEngine(CephContext
* const cct
,
129 /* const */RGWCtl
* const ctl
,
130 const rgw::auth::TokenExtractor
* const extractor
,
131 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
134 extractor(extractor
),
135 apl_factory(apl_factory
) {
138 const char* get_name() const noexcept override
{
139 return "rgw::auth::swift::ExternalTokenEngine";
142 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
) const override
{
143 return authenticate(dpp
, extractor
->get_token(s
), s
);
147 /* SwiftAnonymous: applier. */
148 class SwiftAnonymousApplier
: public rgw::auth::LocalApplier
{
150 SwiftAnonymousApplier(CephContext
* const cct
,
151 const RGWUserInfo
& user_info
)
152 : LocalApplier(cct
, user_info
, LocalApplier::NO_SUBUSER
, boost::none
) {
154 bool is_admin_of(const rgw_user
& uid
) const {return false;}
155 bool is_owner_of(const rgw_user
& uid
) const {return false;}
158 class SwiftAnonymousEngine
: public rgw::auth::AnonymousEngine
{
159 const rgw::auth::TokenExtractor
* const extractor
;
161 bool is_applicable(const req_state
* s
) const noexcept override
{
162 return extractor
->get_token(s
).empty();
166 SwiftAnonymousEngine(CephContext
* const cct
,
167 const SwiftAnonymousApplier::Factory
* const apl_factory
,
168 const rgw::auth::TokenExtractor
* const extractor
)
169 : AnonymousEngine(cct
, apl_factory
),
170 extractor(extractor
) {
173 const char* get_name() const noexcept override
{
174 return "rgw::auth::swift::SwiftAnonymousEngine";
179 class DefaultStrategy
: public rgw::auth::Strategy
,
180 public rgw::auth::TokenExtractor
,
181 public rgw::auth::RemoteApplier::Factory
,
182 public rgw::auth::LocalApplier::Factory
,
183 public rgw::auth::swift::TempURLApplier::Factory
{
185 ImplicitTenants
& implicit_tenant_context
;
188 const rgw::auth::swift::TempURLEngine tempurl_engine
;
189 const rgw::auth::swift::SignedTokenEngine signed_engine
;
190 boost::optional
<const rgw::auth::keystone::TokenEngine
> keystone_engine
;
191 const rgw::auth::swift::ExternalTokenEngine external_engine
;
192 const rgw::auth::swift::SwiftAnonymousEngine anon_engine
;
194 using keystone_config_t
= rgw::keystone::CephCtxConfig
;
195 using keystone_cache_t
= rgw::keystone::TokenCache
;
196 using aplptr_t
= rgw::auth::IdentityApplier::aplptr_t
;
197 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
199 /* The method implements TokenExtractor for X-Auth-Token present in req_state. */
200 std::string
get_token(const req_state
* const s
) const override
{
201 /* Returning a reference here would end in GCC complaining about a reference
203 return s
->info
.env
->get("HTTP_X_AUTH_TOKEN", "");
206 aplptr_t
create_apl_remote(CephContext
* const cct
,
207 const req_state
* const s
,
208 acl_strategy_t
&& extra_acl_strategy
,
209 const rgw::auth::RemoteApplier::AuthInfo
&info
) const override
{
210 rgw_user
user(s
->account_name
);
212 user
= rgw_user(RGW_USER_ANON_ID
);
214 rgw::auth::add_3rdparty(ctl
, user
,
215 rgw::auth::add_sysreq(cct
, ctl
, s
,
216 rgw::auth::RemoteApplier(cct
, ctl
, std::move(extra_acl_strategy
), info
,
217 implicit_tenant_context
,
218 rgw::auth::ImplicitTenants::IMPLICIT_TENANTS_SWIFT
)));
219 /* TODO(rzarzynski): replace with static_ptr. */
220 return aplptr_t(new decltype(apl
)(std::move(apl
)));
223 aplptr_t
create_apl_local(CephContext
* const cct
,
224 const req_state
* const s
,
225 const RGWUserInfo
& user_info
,
226 const std::string
& subuser
,
227 const boost::optional
<uint32_t>& perm_mask
) const override
{
228 rgw_user
user(s
->account_name
);
229 if (user_info
.user_id
.compare(RGW_USER_ANON_ID
) == 0)
230 user
= rgw_user(user_info
.user_id
);
232 rgw::auth::add_3rdparty(ctl
, user
,
233 rgw::auth::add_sysreq(cct
, ctl
, s
,
234 rgw::auth::LocalApplier(cct
, user_info
, subuser
, perm_mask
)));
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
,
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<rgw::auth::LocalApplier::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() override
{ return 0; }
309 void execute() 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::RGWRadosStore
*store
, struct req_state
*state
, rgw::io::BasicClient
*cio
) override
;
321 int authorize(const DoutPrefixProvider
*dpp
) override
;
322 int postauth_init() override
{ return 0; }
323 int read_permissions(RGWOp
*op
) 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(struct req_state
*,
341 const rgw::auth::StrategyRegistry
&,
342 const std::string
&) override
{
343 return new RGWHandler_SWIFT_Auth
;