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