]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_swift_auth.h
import quincy beta 17.1.0
[ceph.git] / ceph / src / rgw / rgw_swift_auth.h
CommitLineData
7c673cae 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
7c673cae
FG
3
4#ifndef CEPH_RGW_SWIFT_AUTH_H
5#define CEPH_RGW_SWIFT_AUTH_H
6
e306af50
TL
7#include "rgw_common.h"
8#include "rgw_user.h"
7c673cae
FG
9#include "rgw_op.h"
10#include "rgw_rest.h"
11#include "rgw_auth.h"
12#include "rgw_auth_keystone.h"
13#include "rgw_auth_filters.h"
9f95a23c 14#include "rgw_sal.h"
7c673cae
FG
15
16#define RGW_SWIFT_TOKEN_EXPIRATION (15 * 60)
17
18namespace rgw {
19namespace auth {
20namespace swift {
21
22/* TempURL: applier. */
23class TempURLApplier : public rgw::auth::LocalApplier {
24public:
25 TempURLApplier(CephContext* const cct,
26 const RGWUserInfo& user_info)
20effc67 27 : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, std::nullopt) {
7c673cae
FG
28 };
29
11fdf7f2 30 void modify_request_state(const DoutPrefixProvider* dpp, req_state * s) const override; /* in/out */
7c673cae
FG
31
32 struct Factory {
33 virtual ~Factory() {}
34 virtual aplptr_t create_apl_turl(CephContext* cct,
35 const req_state* s,
36 const RGWUserInfo& user_info) const = 0;
37 };
38};
39
40/* TempURL: engine */
41class TempURLEngine : public rgw::auth::Engine {
42 using result_t = rgw::auth::Engine::result_t;
43
44 CephContext* const cct;
20effc67 45 rgw::sal::Store* store;
7c673cae
FG
46 const TempURLApplier::Factory* const apl_factory;
47
48 /* Helper methods. */
11fdf7f2
TL
49 void get_owner_info(const DoutPrefixProvider* dpp,
50 const req_state* s,
f67539c2
TL
51 RGWUserInfo& owner_info,
52 optional_yield y) const;
11fdf7f2 53 std::string convert_from_iso8601(std::string expires) const;
7c673cae
FG
54 bool is_applicable(const req_state* s) const noexcept;
55 bool is_expired(const std::string& expires) const;
494da23a 56 bool is_disallowed_header_present(const req_info& info) const;
7c673cae
FG
57
58 class SignatureHelper;
d2e6a577 59 class PrefixableSignatureHelper;
7c673cae
FG
60
61public:
62 TempURLEngine(CephContext* const cct,
20effc67 63 rgw::sal::Store* _store ,
7c673cae
FG
64 const TempURLApplier::Factory* const apl_factory)
65 : cct(cct),
20effc67 66 store(_store),
7c673cae
FG
67 apl_factory(apl_factory) {
68 }
69
70 /* Interface implementations. */
71 const char* get_name() const noexcept override {
72 return "rgw::auth::swift::TempURLEngine";
73 }
74
f67539c2 75 result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s, optional_yield y) const override;
7c673cae
FG
76};
77
78
79/* AUTH_rgwtk */
80class SignedTokenEngine : public rgw::auth::Engine {
81 using result_t = rgw::auth::Engine::result_t;
82
83 CephContext* const cct;
20effc67 84 rgw::sal::Store* store;
7c673cae
FG
85 const rgw::auth::TokenExtractor* const extractor;
86 const rgw::auth::LocalApplier::Factory* const apl_factory;
87
88 bool is_applicable(const std::string& token) const noexcept;
f67539c2 89 using rgw::auth::Engine::authenticate;
11fdf7f2
TL
90 result_t authenticate(const DoutPrefixProvider* dpp,
91 const std::string& token,
7c673cae
FG
92 const req_state* s) const;
93
94public:
95 SignedTokenEngine(CephContext* const cct,
20effc67 96 rgw::sal::Store* _store,
7c673cae
FG
97 const rgw::auth::TokenExtractor* const extractor,
98 const rgw::auth::LocalApplier::Factory* const apl_factory)
99 : cct(cct),
20effc67 100 store(_store),
7c673cae
FG
101 extractor(extractor),
102 apl_factory(apl_factory) {
103 }
104
105 const char* get_name() const noexcept override {
106 return "rgw::auth::swift::SignedTokenEngine";
107 }
108
f67539c2
TL
109 result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s,
110 optional_yield y) const override {
11fdf7f2 111 return authenticate(dpp, extractor->get_token(s), s);
7c673cae
FG
112 }
113};
114
115
116/* External token */
117class ExternalTokenEngine : public rgw::auth::Engine {
118 using result_t = rgw::auth::Engine::result_t;
119
120 CephContext* const cct;
20effc67 121 rgw::sal::Store* store;
7c673cae
FG
122 const rgw::auth::TokenExtractor* const extractor;
123 const rgw::auth::LocalApplier::Factory* const apl_factory;
124
125 bool is_applicable(const std::string& token) const noexcept;
11fdf7f2
TL
126 result_t authenticate(const DoutPrefixProvider* dpp,
127 const std::string& token,
f67539c2 128 const req_state* s, optional_yield y) const;
7c673cae
FG
129
130public:
131 ExternalTokenEngine(CephContext* const cct,
20effc67 132 rgw::sal::Store* _store,
7c673cae
FG
133 const rgw::auth::TokenExtractor* const extractor,
134 const rgw::auth::LocalApplier::Factory* const apl_factory)
135 : cct(cct),
20effc67 136 store(_store),
7c673cae
FG
137 extractor(extractor),
138 apl_factory(apl_factory) {
139 }
140
141 const char* get_name() const noexcept override {
142 return "rgw::auth::swift::ExternalTokenEngine";
143 }
144
f67539c2
TL
145 result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s,
146 optional_yield y) const override {
147 return authenticate(dpp, extractor->get_token(s), s, y);
7c673cae
FG
148 }
149};
150
e306af50
TL
151/* SwiftAnonymous: applier. */
152class SwiftAnonymousApplier : public rgw::auth::LocalApplier {
153 public:
154 SwiftAnonymousApplier(CephContext* const cct,
155 const RGWUserInfo& user_info)
20effc67
TL
156 : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, std::nullopt) {
157 }
e306af50 158 bool is_admin_of(const rgw_user& uid) const {return false;}
f91f0fd5 159 bool is_owner_of(const rgw_user& uid) const {return uid.id.compare(RGW_USER_ANON_ID) == 0;}
e306af50 160};
7c673cae
FG
161
162class SwiftAnonymousEngine : public rgw::auth::AnonymousEngine {
163 const rgw::auth::TokenExtractor* const extractor;
164
165 bool is_applicable(const req_state* s) const noexcept override {
166 return extractor->get_token(s).empty();
167 }
168
169public:
170 SwiftAnonymousEngine(CephContext* const cct,
e306af50 171 const SwiftAnonymousApplier::Factory* const apl_factory,
7c673cae
FG
172 const rgw::auth::TokenExtractor* const extractor)
173 : AnonymousEngine(cct, apl_factory),
174 extractor(extractor) {
175 }
176
177 const char* get_name() const noexcept override {
178 return "rgw::auth::swift::SwiftAnonymousEngine";
179 }
180};
181
182
183class DefaultStrategy : public rgw::auth::Strategy,
184 public rgw::auth::TokenExtractor,
185 public rgw::auth::RemoteApplier::Factory,
186 public rgw::auth::LocalApplier::Factory,
187 public rgw::auth::swift::TempURLApplier::Factory {
20effc67 188 rgw::sal::Store* store;
9f95a23c 189 ImplicitTenants& implicit_tenant_context;
7c673cae
FG
190
191 /* The engines. */
192 const rgw::auth::swift::TempURLEngine tempurl_engine;
193 const rgw::auth::swift::SignedTokenEngine signed_engine;
3efd9988 194 boost::optional <const rgw::auth::keystone::TokenEngine> keystone_engine;
7c673cae
FG
195 const rgw::auth::swift::ExternalTokenEngine external_engine;
196 const rgw::auth::swift::SwiftAnonymousEngine anon_engine;
197
198 using keystone_config_t = rgw::keystone::CephCtxConfig;
199 using keystone_cache_t = rgw::keystone::TokenCache;
200 using aplptr_t = rgw::auth::IdentityApplier::aplptr_t;
201 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
202
203 /* The method implements TokenExtractor for X-Auth-Token present in req_state. */
204 std::string get_token(const req_state* const s) const override {
205 /* Returning a reference here would end in GCC complaining about a reference
206 * to temporary. */
207 return s->info.env->get("HTTP_X_AUTH_TOKEN", "");
208 }
209
210 aplptr_t create_apl_remote(CephContext* const cct,
211 const req_state* const s,
212 acl_strategy_t&& extra_acl_strategy,
11fdf7f2 213 const rgw::auth::RemoteApplier::AuthInfo &info) const override {
7c673cae 214 auto apl = \
20effc67
TL
215 rgw::auth::add_3rdparty(store, rgw_user(s->account_name),
216 rgw::auth::add_sysreq(cct, store, s,
217 rgw::auth::RemoteApplier(cct, store, std::move(extra_acl_strategy), info,
9f95a23c
TL
218 implicit_tenant_context,
219 rgw::auth::ImplicitTenants::IMPLICIT_TENANTS_SWIFT)));
7c673cae
FG
220 /* TODO(rzarzynski): replace with static_ptr. */
221 return aplptr_t(new decltype(apl)(std::move(apl)));
222 }
223
224 aplptr_t create_apl_local(CephContext* const cct,
225 const req_state* const s,
226 const RGWUserInfo& user_info,
11fdf7f2 227 const std::string& subuser,
20effc67 228 const std::optional<uint32_t>& perm_mask) const override {
7c673cae 229 auto apl = \
20effc67
TL
230 rgw::auth::add_3rdparty(store, rgw_user(s->account_name),
231 rgw::auth::add_sysreq(cct, store, s,
11fdf7f2 232 rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask)));
7c673cae
FG
233 /* TODO(rzarzynski): replace with static_ptr. */
234 return aplptr_t(new decltype(apl)(std::move(apl)));
235 }
236
237 aplptr_t create_apl_turl(CephContext* const cct,
238 const req_state* const s,
239 const RGWUserInfo& user_info) const override {
240 /* TempURL doesn't need any user account override. It's a Swift-specific
241 * mechanism that requires account name internally, so there is no
242 * business with delegating the responsibility outside. */
243 return aplptr_t(new rgw::auth::swift::TempURLApplier(cct, user_info));
244 }
245
246public:
247 DefaultStrategy(CephContext* const cct,
9f95a23c 248 ImplicitTenants& implicit_tenant_context,
20effc67
TL
249 rgw::sal::Store* _store)
250 : store(_store),
9f95a23c 251 implicit_tenant_context(implicit_tenant_context),
7c673cae 252 tempurl_engine(cct,
20effc67 253 store,
7c673cae
FG
254 static_cast<rgw::auth::swift::TempURLApplier::Factory*>(this)),
255 signed_engine(cct,
20effc67 256 store,
7c673cae
FG
257 static_cast<rgw::auth::TokenExtractor*>(this),
258 static_cast<rgw::auth::LocalApplier::Factory*>(this)),
7c673cae 259 external_engine(cct,
20effc67 260 store,
7c673cae
FG
261 static_cast<rgw::auth::TokenExtractor*>(this),
262 static_cast<rgw::auth::LocalApplier::Factory*>(this)),
263 anon_engine(cct,
f91f0fd5 264 static_cast<SwiftAnonymousApplier::Factory*>(this),
7c673cae
FG
265 static_cast<rgw::auth::TokenExtractor*>(this)) {
266 /* When the constructor's body is being executed, all member engines
267 * should be initialized. Thus, we can safely add them. */
268 using Control = rgw::auth::Strategy::Control;
269
270 add_engine(Control::SUFFICIENT, tempurl_engine);
271 add_engine(Control::SUFFICIENT, signed_engine);
272
273 /* The auth strategy is responsible for deciding whether a parcular
274 * engine is disabled or not. */
275 if (! cct->_conf->rgw_keystone_url.empty()) {
3efd9988
FG
276 keystone_engine.emplace(cct,
277 static_cast<rgw::auth::TokenExtractor*>(this),
278 static_cast<rgw::auth::RemoteApplier::Factory*>(this),
279 keystone_config_t::get_instance(),
280 keystone_cache_t::get_instance<keystone_config_t>());
281
282 add_engine(Control::SUFFICIENT, *keystone_engine);
7c673cae
FG
283 }
284 if (! cct->_conf->rgw_swift_auth_url.empty()) {
285 add_engine(Control::SUFFICIENT, external_engine);
286 }
287
288 add_engine(Control::SUFFICIENT, anon_engine);
289 }
290
291 const char* get_name() const noexcept override {
292 return "rgw::auth::swift::DefaultStrategy";
293 }
294};
295
296} /* namespace swift */
297} /* namespace auth */
298} /* namespace rgw */
299
300
301class RGW_SWIFT_Auth_Get : public RGWOp {
302public:
303 RGW_SWIFT_Auth_Get() {}
304 ~RGW_SWIFT_Auth_Get() override {}
305
f67539c2
TL
306 int verify_permission(optional_yield) override { return 0; }
307 void execute(optional_yield y) override;
11fdf7f2
TL
308 const char* name() const override { return "swift_auth_get"; }
309 dmc::client_id dmclock_client() override { return dmc::client_id::auth; }
7c673cae
FG
310};
311
312class RGWHandler_SWIFT_Auth : public RGWHandler_REST {
313public:
314 RGWHandler_SWIFT_Auth() {}
315 ~RGWHandler_SWIFT_Auth() override {}
316 RGWOp *op_get() override;
317
20effc67 318 int init(rgw::sal::Store* store, struct req_state *state, rgw::io::BasicClient *cio) override;
f67539c2
TL
319 int authorize(const DoutPrefixProvider *dpp, optional_yield y) override;
320 int postauth_init(optional_yield) override { return 0; }
321 int read_permissions(RGWOp *op, optional_yield) override { return 0; }
7c673cae
FG
322
323 virtual RGWAccessControlPolicy *alloc_policy() { return NULL; }
324 virtual void free_policy(RGWAccessControlPolicy *policy) {}
325};
326
327class RGWRESTMgr_SWIFT_Auth : public RGWRESTMgr {
328public:
329 RGWRESTMgr_SWIFT_Auth() = default;
330 ~RGWRESTMgr_SWIFT_Auth() override = default;
331
332 RGWRESTMgr *get_resource_mgr(struct req_state* const s,
333 const std::string& uri,
334 std::string* const out_uri) override {
335 return this;
336 }
337
20effc67 338 RGWHandler_REST* get_handler(rgw::sal::Store* store,
f67539c2 339 struct req_state*,
7c673cae
FG
340 const rgw::auth::StrategyRegistry&,
341 const std::string&) override {
342 return new RGWHandler_SWIFT_Auth;
343 }
344};
345
346
347#endif