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
, boost::none
) {
27 void modify_request_state(const DoutPrefixProvider
* dpp
, 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 DoutPrefixProvider
* dpp
,
48 RGWUserInfo
& owner_info
) const;
49 std::string
convert_from_iso8601(std::string expires
) const;
50 bool is_applicable(const req_state
* s
) const noexcept
;
51 bool is_expired(const std::string
& expires
) const;
53 class SignatureHelper
;
54 class PrefixableSignatureHelper
;
57 TempURLEngine(CephContext
* const cct
,
58 /*const*/ RGWRados
* const store
,
59 const TempURLApplier::Factory
* const apl_factory
)
62 apl_factory(apl_factory
) {
65 /* Interface implementations. */
66 const char* get_name() const noexcept override
{
67 return "rgw::auth::swift::TempURLEngine";
70 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
) const override
;
75 class SignedTokenEngine
: public rgw::auth::Engine
{
76 using result_t
= rgw::auth::Engine::result_t
;
78 CephContext
* const cct
;
79 RGWRados
* const store
;
80 const rgw::auth::TokenExtractor
* const extractor
;
81 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
83 bool is_applicable(const std::string
& token
) const noexcept
;
84 result_t
authenticate(const DoutPrefixProvider
* dpp
,
85 const std::string
& token
,
86 const req_state
* s
) const;
89 SignedTokenEngine(CephContext
* const cct
,
90 /* const */RGWRados
* const store
,
91 const rgw::auth::TokenExtractor
* const extractor
,
92 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
96 apl_factory(apl_factory
) {
99 const char* get_name() const noexcept override
{
100 return "rgw::auth::swift::SignedTokenEngine";
103 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
) const override
{
104 return authenticate(dpp
, extractor
->get_token(s
), s
);
110 class ExternalTokenEngine
: public rgw::auth::Engine
{
111 using result_t
= rgw::auth::Engine::result_t
;
113 CephContext
* const cct
;
114 RGWRados
* const store
;
115 const rgw::auth::TokenExtractor
* const extractor
;
116 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
118 bool is_applicable(const std::string
& token
) const noexcept
;
119 result_t
authenticate(const DoutPrefixProvider
* dpp
,
120 const std::string
& token
,
121 const req_state
* s
) const;
124 ExternalTokenEngine(CephContext
* const cct
,
125 /* const */RGWRados
* const store
,
126 const rgw::auth::TokenExtractor
* const extractor
,
127 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
130 extractor(extractor
),
131 apl_factory(apl_factory
) {
134 const char* get_name() const noexcept override
{
135 return "rgw::auth::swift::ExternalTokenEngine";
138 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
) const override
{
139 return authenticate(dpp
, extractor
->get_token(s
), s
);
144 class SwiftAnonymousEngine
: public rgw::auth::AnonymousEngine
{
145 const rgw::auth::TokenExtractor
* const extractor
;
147 bool is_applicable(const req_state
* s
) const noexcept override
{
148 return extractor
->get_token(s
).empty();
152 SwiftAnonymousEngine(CephContext
* const cct
,
153 const rgw::auth::LocalApplier::Factory
* const apl_factory
,
154 const rgw::auth::TokenExtractor
* const extractor
)
155 : AnonymousEngine(cct
, apl_factory
),
156 extractor(extractor
) {
159 const char* get_name() const noexcept override
{
160 return "rgw::auth::swift::SwiftAnonymousEngine";
165 class DefaultStrategy
: public rgw::auth::Strategy
,
166 public rgw::auth::TokenExtractor
,
167 public rgw::auth::RemoteApplier::Factory
,
168 public rgw::auth::LocalApplier::Factory
,
169 public rgw::auth::swift::TempURLApplier::Factory
{
170 RGWRados
* const store
;
173 const rgw::auth::swift::TempURLEngine tempurl_engine
;
174 const rgw::auth::swift::SignedTokenEngine signed_engine
;
175 boost::optional
<const rgw::auth::keystone::TokenEngine
> keystone_engine
;
176 const rgw::auth::swift::ExternalTokenEngine external_engine
;
177 const rgw::auth::swift::SwiftAnonymousEngine anon_engine
;
179 using keystone_config_t
= rgw::keystone::CephCtxConfig
;
180 using keystone_cache_t
= rgw::keystone::TokenCache
;
181 using aplptr_t
= rgw::auth::IdentityApplier::aplptr_t
;
182 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
184 /* The method implements TokenExtractor for X-Auth-Token present in req_state. */
185 std::string
get_token(const req_state
* const s
) const override
{
186 /* Returning a reference here would end in GCC complaining about a reference
188 return s
->info
.env
->get("HTTP_X_AUTH_TOKEN", "");
191 aplptr_t
create_apl_remote(CephContext
* const cct
,
192 const req_state
* const s
,
193 acl_strategy_t
&& extra_acl_strategy
,
194 const rgw::auth::RemoteApplier::AuthInfo
&info
) const override
{
196 rgw::auth::add_3rdparty(store
, s
->account_name
,
197 rgw::auth::add_sysreq(cct
, store
, s
,
198 rgw::auth::RemoteApplier(cct
, store
, std::move(extra_acl_strategy
), info
,
199 cct
->_conf
->rgw_keystone_implicit_tenants
)));
200 /* TODO(rzarzynski): replace with static_ptr. */
201 return aplptr_t(new decltype(apl
)(std::move(apl
)));
204 aplptr_t
create_apl_local(CephContext
* const cct
,
205 const req_state
* const s
,
206 const RGWUserInfo
& user_info
,
207 const std::string
& subuser
,
208 const boost::optional
<uint32_t>& perm_mask
) const override
{
210 rgw::auth::add_3rdparty(store
, s
->account_name
,
211 rgw::auth::add_sysreq(cct
, store
, s
,
212 rgw::auth::LocalApplier(cct
, user_info
, subuser
, perm_mask
)));
213 /* TODO(rzarzynski): replace with static_ptr. */
214 return aplptr_t(new decltype(apl
)(std::move(apl
)));
217 aplptr_t
create_apl_turl(CephContext
* const cct
,
218 const req_state
* const s
,
219 const RGWUserInfo
& user_info
) const override
{
220 /* TempURL doesn't need any user account override. It's a Swift-specific
221 * mechanism that requires account name internally, so there is no
222 * business with delegating the responsibility outside. */
223 return aplptr_t(new rgw::auth::swift::TempURLApplier(cct
, user_info
));
227 DefaultStrategy(CephContext
* const cct
,
228 RGWRados
* const store
)
232 static_cast<rgw::auth::swift::TempURLApplier::Factory
*>(this)),
235 static_cast<rgw::auth::TokenExtractor
*>(this),
236 static_cast<rgw::auth::LocalApplier::Factory
*>(this)),
239 static_cast<rgw::auth::TokenExtractor
*>(this),
240 static_cast<rgw::auth::LocalApplier::Factory
*>(this)),
242 static_cast<rgw::auth::LocalApplier::Factory
*>(this),
243 static_cast<rgw::auth::TokenExtractor
*>(this)) {
244 /* When the constructor's body is being executed, all member engines
245 * should be initialized. Thus, we can safely add them. */
246 using Control
= rgw::auth::Strategy::Control
;
248 add_engine(Control::SUFFICIENT
, tempurl_engine
);
249 add_engine(Control::SUFFICIENT
, signed_engine
);
251 /* The auth strategy is responsible for deciding whether a parcular
252 * engine is disabled or not. */
253 if (! cct
->_conf
->rgw_keystone_url
.empty()) {
254 keystone_engine
.emplace(cct
,
255 static_cast<rgw::auth::TokenExtractor
*>(this),
256 static_cast<rgw::auth::RemoteApplier::Factory
*>(this),
257 keystone_config_t::get_instance(),
258 keystone_cache_t::get_instance
<keystone_config_t
>());
260 add_engine(Control::SUFFICIENT
, *keystone_engine
);
262 if (! cct
->_conf
->rgw_swift_auth_url
.empty()) {
263 add_engine(Control::SUFFICIENT
, external_engine
);
266 add_engine(Control::SUFFICIENT
, anon_engine
);
269 const char* get_name() const noexcept override
{
270 return "rgw::auth::swift::DefaultStrategy";
274 } /* namespace swift */
275 } /* namespace auth */
276 } /* namespace rgw */
279 class RGW_SWIFT_Auth_Get
: public RGWOp
{
281 RGW_SWIFT_Auth_Get() {}
282 ~RGW_SWIFT_Auth_Get() override
{}
284 int verify_permission() override
{ return 0; }
285 void execute() override
;
286 const char* name() const override
{ return "swift_auth_get"; }
287 dmc::client_id
dmclock_client() override
{ return dmc::client_id::auth
; }
290 class RGWHandler_SWIFT_Auth
: public RGWHandler_REST
{
292 RGWHandler_SWIFT_Auth() {}
293 ~RGWHandler_SWIFT_Auth() override
{}
294 RGWOp
*op_get() override
;
296 int init(RGWRados
*store
, struct req_state
*state
, rgw::io::BasicClient
*cio
) override
;
297 int authorize(const DoutPrefixProvider
*dpp
) override
;
298 int postauth_init() override
{ return 0; }
299 int read_permissions(RGWOp
*op
) override
{ return 0; }
301 virtual RGWAccessControlPolicy
*alloc_policy() { return NULL
; }
302 virtual void free_policy(RGWAccessControlPolicy
*policy
) {}
305 class RGWRESTMgr_SWIFT_Auth
: public RGWRESTMgr
{
307 RGWRESTMgr_SWIFT_Auth() = default;
308 ~RGWRESTMgr_SWIFT_Auth() override
= default;
310 RGWRESTMgr
*get_resource_mgr(struct req_state
* const s
,
311 const std::string
& uri
,
312 std::string
* const out_uri
) override
{
316 RGWHandler_REST
* get_handler(struct req_state
*,
317 const rgw::auth::StrategyRegistry
&,
318 const std::string
&) override
{
319 return new RGWHandler_SWIFT_Auth
;