1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_RGW_SWIFT_AUTH_H
5 #define CEPH_RGW_SWIFT_AUTH_H
10 #include "rgw_auth_keystone.h"
11 #include "rgw_auth_filters.h"
13 #define RGW_SWIFT_TOKEN_EXPIRATION (15 * 60)
19 /* TempURL: applier. */
20 class TempURLApplier
: public rgw::auth::LocalApplier
{
22 TempURLApplier(CephContext
* const cct
,
23 const RGWUserInfo
& user_info
)
24 : LocalApplier(cct
, user_info
, LocalApplier::NO_SUBUSER
) {
27 void modify_request_state(req_state
* s
) const override
; /* in/out */
31 virtual aplptr_t
create_apl_turl(CephContext
* cct
,
33 const RGWUserInfo
& user_info
) const = 0;
38 class TempURLEngine
: public rgw::auth::Engine
{
39 using result_t
= rgw::auth::Engine::result_t
;
41 CephContext
* const cct
;
42 /* const */ RGWRados
* const store
;
43 const TempURLApplier::Factory
* const apl_factory
;
46 void get_owner_info(const req_state
* s
,
47 RGWUserInfo
& owner_info
) const;
48 bool is_applicable(const req_state
* s
) const noexcept
;
49 bool is_expired(const std::string
& expires
) const;
51 class SignatureHelper
;
52 class PrefixableSignatureHelper
;
55 TempURLEngine(CephContext
* const cct
,
56 /*const*/ RGWRados
* const store
,
57 const TempURLApplier::Factory
* const apl_factory
)
60 apl_factory(apl_factory
) {
63 /* Interface implementations. */
64 const char* get_name() const noexcept override
{
65 return "rgw::auth::swift::TempURLEngine";
68 result_t
authenticate(const req_state
* const s
) const override
;
73 class SignedTokenEngine
: public rgw::auth::Engine
{
74 using result_t
= rgw::auth::Engine::result_t
;
76 CephContext
* const cct
;
77 RGWRados
* const store
;
78 const rgw::auth::TokenExtractor
* const extractor
;
79 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
81 bool is_applicable(const std::string
& token
) const noexcept
;
82 result_t
authenticate(const std::string
& token
,
83 const req_state
* s
) const;
86 SignedTokenEngine(CephContext
* const cct
,
87 /* const */RGWRados
* const store
,
88 const rgw::auth::TokenExtractor
* const extractor
,
89 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
93 apl_factory(apl_factory
) {
96 const char* get_name() const noexcept override
{
97 return "rgw::auth::swift::SignedTokenEngine";
100 result_t
authenticate(const req_state
* const s
) const override
{
101 return authenticate(extractor
->get_token(s
), s
);
107 class ExternalTokenEngine
: public rgw::auth::Engine
{
108 using result_t
= rgw::auth::Engine::result_t
;
110 CephContext
* const cct
;
111 RGWRados
* const store
;
112 const rgw::auth::TokenExtractor
* const extractor
;
113 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
115 bool is_applicable(const std::string
& token
) const noexcept
;
116 result_t
authenticate(const std::string
& token
,
117 const req_state
* s
) const;
120 ExternalTokenEngine(CephContext
* const cct
,
121 /* const */RGWRados
* const store
,
122 const rgw::auth::TokenExtractor
* const extractor
,
123 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
126 extractor(extractor
),
127 apl_factory(apl_factory
) {
130 const char* get_name() const noexcept override
{
131 return "rgw::auth::swift::ExternalTokenEngine";
134 result_t
authenticate(const req_state
* const s
) const override
{
135 return authenticate(extractor
->get_token(s
), s
);
140 class SwiftAnonymousEngine
: public rgw::auth::AnonymousEngine
{
141 const rgw::auth::TokenExtractor
* const extractor
;
143 bool is_applicable(const req_state
* s
) const noexcept override
{
144 return extractor
->get_token(s
).empty();
148 SwiftAnonymousEngine(CephContext
* const cct
,
149 const rgw::auth::LocalApplier::Factory
* const apl_factory
,
150 const rgw::auth::TokenExtractor
* const extractor
)
151 : AnonymousEngine(cct
, apl_factory
),
152 extractor(extractor
) {
155 const char* get_name() const noexcept override
{
156 return "rgw::auth::swift::SwiftAnonymousEngine";
161 class DefaultStrategy
: public rgw::auth::Strategy
,
162 public rgw::auth::TokenExtractor
,
163 public rgw::auth::RemoteApplier::Factory
,
164 public rgw::auth::LocalApplier::Factory
,
165 public rgw::auth::swift::TempURLApplier::Factory
{
166 RGWRados
* const store
;
167 ImplicitTenants
& implicit_tenant_context
;
170 const rgw::auth::swift::TempURLEngine tempurl_engine
;
171 const rgw::auth::swift::SignedTokenEngine signed_engine
;
172 boost::optional
<const rgw::auth::keystone::TokenEngine
> keystone_engine
;
173 const rgw::auth::swift::ExternalTokenEngine external_engine
;
174 const rgw::auth::swift::SwiftAnonymousEngine anon_engine
;
176 using keystone_config_t
= rgw::keystone::CephCtxConfig
;
177 using keystone_cache_t
= rgw::keystone::TokenCache
;
178 using aplptr_t
= rgw::auth::IdentityApplier::aplptr_t
;
179 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
181 /* The method implements TokenExtractor for X-Auth-Token present in req_state. */
182 std::string
get_token(const req_state
* const s
) const override
{
183 /* Returning a reference here would end in GCC complaining about a reference
185 return s
->info
.env
->get("HTTP_X_AUTH_TOKEN", "");
188 aplptr_t
create_apl_remote(CephContext
* const cct
,
189 const req_state
* const s
,
190 acl_strategy_t
&& extra_acl_strategy
,
191 const rgw::auth::RemoteApplier::AuthInfo info
) const override
{
193 rgw::auth::add_3rdparty(store
, s
->account_name
,
194 rgw::auth::add_sysreq(cct
, store
, s
,
195 rgw::auth::RemoteApplier(cct
, store
, std::move(extra_acl_strategy
), info
,
196 implicit_tenant_context
,
197 rgw::auth::ImplicitTenants::IMPLICIT_TENANTS_SWIFT
)));
198 /* TODO(rzarzynski): replace with static_ptr. */
199 return aplptr_t(new decltype(apl
)(std::move(apl
)));
202 aplptr_t
create_apl_local(CephContext
* const cct
,
203 const req_state
* const s
,
204 const RGWUserInfo
& user_info
,
205 const std::string
& subuser
) const override
{
207 rgw::auth::add_3rdparty(store
, s
->account_name
,
208 rgw::auth::add_sysreq(cct
, store
, s
,
209 rgw::auth::LocalApplier(cct
, user_info
, subuser
)));
210 /* TODO(rzarzynski): replace with static_ptr. */
211 return aplptr_t(new decltype(apl
)(std::move(apl
)));
214 aplptr_t
create_apl_turl(CephContext
* const cct
,
215 const req_state
* const s
,
216 const RGWUserInfo
& user_info
) const override
{
217 /* TempURL doesn't need any user account override. It's a Swift-specific
218 * mechanism that requires account name internally, so there is no
219 * business with delegating the responsibility outside. */
220 return aplptr_t(new rgw::auth::swift::TempURLApplier(cct
, user_info
));
224 DefaultStrategy(CephContext
* const cct
,
225 ImplicitTenants
& implicit_tenant_context
,
226 RGWRados
* const store
)
228 implicit_tenant_context(implicit_tenant_context
),
231 static_cast<rgw::auth::swift::TempURLApplier::Factory
*>(this)),
234 static_cast<rgw::auth::TokenExtractor
*>(this),
235 static_cast<rgw::auth::LocalApplier::Factory
*>(this)),
238 static_cast<rgw::auth::TokenExtractor
*>(this),
239 static_cast<rgw::auth::LocalApplier::Factory
*>(this)),
241 static_cast<rgw::auth::LocalApplier::Factory
*>(this),
242 static_cast<rgw::auth::TokenExtractor
*>(this)) {
243 /* When the constructor's body is being executed, all member engines
244 * should be initialized. Thus, we can safely add them. */
245 using Control
= rgw::auth::Strategy::Control
;
247 add_engine(Control::SUFFICIENT
, tempurl_engine
);
248 add_engine(Control::SUFFICIENT
, signed_engine
);
250 /* The auth strategy is responsible for deciding whether a parcular
251 * engine is disabled or not. */
252 if (! cct
->_conf
->rgw_keystone_url
.empty()) {
253 keystone_engine
.emplace(cct
,
254 static_cast<rgw::auth::TokenExtractor
*>(this),
255 static_cast<rgw::auth::RemoteApplier::Factory
*>(this),
256 keystone_config_t::get_instance(),
257 keystone_cache_t::get_instance
<keystone_config_t
>());
259 add_engine(Control::SUFFICIENT
, *keystone_engine
);
261 if (! cct
->_conf
->rgw_swift_auth_url
.empty()) {
262 add_engine(Control::SUFFICIENT
, external_engine
);
265 add_engine(Control::SUFFICIENT
, anon_engine
);
268 const char* get_name() const noexcept override
{
269 return "rgw::auth::swift::DefaultStrategy";
273 } /* namespace swift */
274 } /* namespace auth */
275 } /* namespace rgw */
278 class RGW_SWIFT_Auth_Get
: public RGWOp
{
280 RGW_SWIFT_Auth_Get() {}
281 ~RGW_SWIFT_Auth_Get() override
{}
283 int verify_permission() override
{ return 0; }
284 void execute() override
;
285 const string
name() override
{ return "swift_auth_get"; }
288 class RGWHandler_SWIFT_Auth
: public RGWHandler_REST
{
290 RGWHandler_SWIFT_Auth() {}
291 ~RGWHandler_SWIFT_Auth() override
{}
292 RGWOp
*op_get() override
;
294 int init(RGWRados
*store
, struct req_state
*state
, rgw::io::BasicClient
*cio
) override
;
295 int authorize() override
;
296 int postauth_init() override
{ return 0; }
297 int read_permissions(RGWOp
*op
) override
{ return 0; }
299 virtual RGWAccessControlPolicy
*alloc_policy() { return NULL
; }
300 virtual void free_policy(RGWAccessControlPolicy
*policy
) {}
303 class RGWRESTMgr_SWIFT_Auth
: public RGWRESTMgr
{
305 RGWRESTMgr_SWIFT_Auth() = default;
306 ~RGWRESTMgr_SWIFT_Auth() override
= default;
308 RGWRESTMgr
*get_resource_mgr(struct req_state
* const s
,
309 const std::string
& uri
,
310 std::string
* const out_uri
) override
{
314 RGWHandler_REST
* get_handler(struct req_state
*,
315 const rgw::auth::StrategyRegistry
&,
316 const std::string
&) override
{
317 return new RGWHandler_SWIFT_Auth
;