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
;
54 TempURLEngine(CephContext
* const cct
,
55 /*const*/ RGWRados
* const store
,
56 const TempURLApplier::Factory
* const apl_factory
)
59 apl_factory(apl_factory
) {
62 /* Interface implementations. */
63 const char* get_name() const noexcept override
{
64 return "rgw::auth::swift::TempURLEngine";
67 result_t
authenticate(const req_state
* const s
) const override
;
72 class SignedTokenEngine
: public rgw::auth::Engine
{
73 using result_t
= rgw::auth::Engine::result_t
;
75 CephContext
* const cct
;
76 RGWRados
* const store
;
77 const rgw::auth::TokenExtractor
* const extractor
;
78 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
80 bool is_applicable(const std::string
& token
) const noexcept
;
81 result_t
authenticate(const std::string
& token
,
82 const req_state
* s
) const;
85 SignedTokenEngine(CephContext
* const cct
,
86 /* const */RGWRados
* const store
,
87 const rgw::auth::TokenExtractor
* const extractor
,
88 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
92 apl_factory(apl_factory
) {
95 const char* get_name() const noexcept override
{
96 return "rgw::auth::swift::SignedTokenEngine";
99 result_t
authenticate(const req_state
* const s
) const override
{
100 return authenticate(extractor
->get_token(s
), s
);
106 class ExternalTokenEngine
: public rgw::auth::Engine
{
107 using result_t
= rgw::auth::Engine::result_t
;
109 CephContext
* const cct
;
110 RGWRados
* const store
;
111 const rgw::auth::TokenExtractor
* const extractor
;
112 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
114 bool is_applicable(const std::string
& token
) const noexcept
;
115 result_t
authenticate(const std::string
& token
,
116 const req_state
* s
) const;
119 ExternalTokenEngine(CephContext
* const cct
,
120 /* const */RGWRados
* const store
,
121 const rgw::auth::TokenExtractor
* const extractor
,
122 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
125 extractor(extractor
),
126 apl_factory(apl_factory
) {
129 const char* get_name() const noexcept override
{
130 return "rgw::auth::swift::ExternalTokenEngine";
133 result_t
authenticate(const req_state
* const s
) const override
{
134 return authenticate(extractor
->get_token(s
), s
);
139 class SwiftAnonymousEngine
: public rgw::auth::AnonymousEngine
{
140 const rgw::auth::TokenExtractor
* const extractor
;
142 bool is_applicable(const req_state
* s
) const noexcept override
{
143 return extractor
->get_token(s
).empty();
147 SwiftAnonymousEngine(CephContext
* const cct
,
148 const rgw::auth::LocalApplier::Factory
* const apl_factory
,
149 const rgw::auth::TokenExtractor
* const extractor
)
150 : AnonymousEngine(cct
, apl_factory
),
151 extractor(extractor
) {
154 const char* get_name() const noexcept override
{
155 return "rgw::auth::swift::SwiftAnonymousEngine";
160 class DefaultStrategy
: public rgw::auth::Strategy
,
161 public rgw::auth::TokenExtractor
,
162 public rgw::auth::RemoteApplier::Factory
,
163 public rgw::auth::LocalApplier::Factory
,
164 public rgw::auth::swift::TempURLApplier::Factory
{
165 RGWRados
* const store
;
168 const rgw::auth::swift::TempURLEngine tempurl_engine
;
169 const rgw::auth::swift::SignedTokenEngine signed_engine
;
170 const rgw::auth::keystone::TokenEngine keystone_engine
;
171 const rgw::auth::swift::ExternalTokenEngine external_engine
;
172 const rgw::auth::swift::SwiftAnonymousEngine anon_engine
;
174 using keystone_config_t
= rgw::keystone::CephCtxConfig
;
175 using keystone_cache_t
= rgw::keystone::TokenCache
;
176 using aplptr_t
= rgw::auth::IdentityApplier::aplptr_t
;
177 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
179 /* The method implements TokenExtractor for X-Auth-Token present in req_state. */
180 std::string
get_token(const req_state
* const s
) const override
{
181 /* Returning a reference here would end in GCC complaining about a reference
183 return s
->info
.env
->get("HTTP_X_AUTH_TOKEN", "");
186 aplptr_t
create_apl_remote(CephContext
* const cct
,
187 const req_state
* const s
,
188 acl_strategy_t
&& extra_acl_strategy
,
189 const rgw::auth::RemoteApplier::AuthInfo info
) const override
{
191 rgw::auth::add_3rdparty(store
, s
->account_name
,
192 rgw::auth::add_sysreq(cct
, store
, s
,
193 rgw::auth::RemoteApplier(cct
, store
, std::move(extra_acl_strategy
), info
,
194 cct
->_conf
->rgw_keystone_implicit_tenants
)));
195 /* TODO(rzarzynski): replace with static_ptr. */
196 return aplptr_t(new decltype(apl
)(std::move(apl
)));
199 aplptr_t
create_apl_local(CephContext
* const cct
,
200 const req_state
* const s
,
201 const RGWUserInfo
& user_info
,
202 const std::string
& subuser
) const override
{
204 rgw::auth::add_3rdparty(store
, s
->account_name
,
205 rgw::auth::add_sysreq(cct
, store
, s
,
206 rgw::auth::LocalApplier(cct
, user_info
, subuser
)));
207 /* TODO(rzarzynski): replace with static_ptr. */
208 return aplptr_t(new decltype(apl
)(std::move(apl
)));
211 aplptr_t
create_apl_turl(CephContext
* const cct
,
212 const req_state
* const s
,
213 const RGWUserInfo
& user_info
) const override
{
214 /* TempURL doesn't need any user account override. It's a Swift-specific
215 * mechanism that requires account name internally, so there is no
216 * business with delegating the responsibility outside. */
217 return aplptr_t(new rgw::auth::swift::TempURLApplier(cct
, user_info
));
221 DefaultStrategy(CephContext
* const cct
,
222 RGWRados
* const store
)
226 static_cast<rgw::auth::swift::TempURLApplier::Factory
*>(this)),
229 static_cast<rgw::auth::TokenExtractor
*>(this),
230 static_cast<rgw::auth::LocalApplier::Factory
*>(this)),
232 static_cast<rgw::auth::TokenExtractor
*>(this),
233 static_cast<rgw::auth::RemoteApplier::Factory
*>(this),
234 keystone_config_t::get_instance(),
235 keystone_cache_t::get_instance
<keystone_config_t
>()),
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 add_engine(Control::SUFFICIENT
, keystone_engine
);
255 if (! cct
->_conf
->rgw_swift_auth_url
.empty()) {
256 add_engine(Control::SUFFICIENT
, external_engine
);
259 add_engine(Control::SUFFICIENT
, anon_engine
);
262 const char* get_name() const noexcept override
{
263 return "rgw::auth::swift::DefaultStrategy";
267 } /* namespace swift */
268 } /* namespace auth */
269 } /* namespace rgw */
272 class RGW_SWIFT_Auth_Get
: public RGWOp
{
274 RGW_SWIFT_Auth_Get() {}
275 ~RGW_SWIFT_Auth_Get() override
{}
277 int verify_permission() override
{ return 0; }
278 void execute() override
;
279 const string
name() override
{ return "swift_auth_get"; }
282 class RGWHandler_SWIFT_Auth
: public RGWHandler_REST
{
284 RGWHandler_SWIFT_Auth() {}
285 ~RGWHandler_SWIFT_Auth() override
{}
286 RGWOp
*op_get() override
;
288 int init(RGWRados
*store
, struct req_state
*state
, rgw::io::BasicClient
*cio
) override
;
289 int authorize() override
;
290 int postauth_init() override
{ return 0; }
291 int read_permissions(RGWOp
*op
) override
{ return 0; }
293 virtual RGWAccessControlPolicy
*alloc_policy() { return NULL
; }
294 virtual void free_policy(RGWAccessControlPolicy
*policy
) {}
297 class RGWRESTMgr_SWIFT_Auth
: public RGWRESTMgr
{
299 RGWRESTMgr_SWIFT_Auth() = default;
300 ~RGWRESTMgr_SWIFT_Auth() override
= default;
302 RGWRESTMgr
*get_resource_mgr(struct req_state
* const s
,
303 const std::string
& uri
,
304 std::string
* const out_uri
) override
{
308 RGWHandler_REST
* get_handler(struct req_state
*,
309 const rgw::auth::StrategyRegistry
&,
310 const std::string
&) override
{
311 return new RGWHandler_SWIFT_Auth
;