]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_swift_auth.h
bump version to 18.2.2-pve1
[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 #pragma once
5
6 #include "rgw_common.h"
7 #include "rgw_user.h"
8 #include "rgw_op.h"
9 #include "rgw_rest.h"
10 #include "rgw_auth.h"
11 #include "rgw_auth_keystone.h"
12 #include "rgw_auth_filters.h"
13 #include "rgw_sal.h"
14
15 #define RGW_SWIFT_TOKEN_EXPIRATION (15 * 60)
16
17 namespace rgw {
18 namespace auth {
19 namespace swift {
20
21 /* TempURL: applier. */
22 class TempURLApplier : public rgw::auth::LocalApplier {
23 public:
24 TempURLApplier(CephContext* const cct,
25 const RGWUserInfo& user_info)
26 : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, std::nullopt, LocalApplier::NO_ACCESS_KEY) {
27 };
28
29 void modify_request_state(const DoutPrefixProvider* dpp, req_state * s) const override; /* in/out */
30 void write_ops_log_entry(rgw_log_entry& entry) const override;
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 */
41 class TempURLEngine : public rgw::auth::Engine {
42 using result_t = rgw::auth::Engine::result_t;
43
44 CephContext* const cct;
45 rgw::sal::Driver* driver;
46 const TempURLApplier::Factory* const apl_factory;
47
48 /* Helper methods. */
49 void get_owner_info(const DoutPrefixProvider* dpp,
50 const req_state* s,
51 RGWUserInfo& owner_info,
52 optional_yield y) const;
53 std::string convert_from_iso8601(std::string expires) const;
54 bool is_applicable(const req_state* s) const noexcept;
55 bool is_expired(const std::string& expires) const;
56 bool is_disallowed_header_present(const req_info& info) const;
57
58 class SignatureHelper;
59 class PrefixableSignatureHelper;
60
61 public:
62 TempURLEngine(CephContext* const cct,
63 rgw::sal::Driver* _driver ,
64 const TempURLApplier::Factory* const apl_factory)
65 : cct(cct),
66 driver(_driver),
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
75 result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s, optional_yield y) const override;
76 };
77
78
79 /* AUTH_rgwtk */
80 class SignedTokenEngine : public rgw::auth::Engine {
81 using result_t = rgw::auth::Engine::result_t;
82
83 CephContext* const cct;
84 rgw::sal::Driver* driver;
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;
89 using rgw::auth::Engine::authenticate;
90 result_t authenticate(const DoutPrefixProvider* dpp,
91 const std::string& token,
92 const req_state* s) const;
93
94 public:
95 SignedTokenEngine(CephContext* const cct,
96 rgw::sal::Driver* _driver,
97 const rgw::auth::TokenExtractor* const extractor,
98 const rgw::auth::LocalApplier::Factory* const apl_factory)
99 : cct(cct),
100 driver(_driver),
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
109 result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s,
110 optional_yield y) const override {
111 return authenticate(dpp, extractor->get_token(s), s);
112 }
113 };
114
115
116 /* External token */
117 class ExternalTokenEngine : public rgw::auth::Engine {
118 using result_t = rgw::auth::Engine::result_t;
119
120 CephContext* const cct;
121 rgw::sal::Driver* driver;
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;
126 result_t authenticate(const DoutPrefixProvider* dpp,
127 const std::string& token,
128 const req_state* s, optional_yield y) const;
129
130 public:
131 ExternalTokenEngine(CephContext* const cct,
132 rgw::sal::Driver* _driver,
133 const rgw::auth::TokenExtractor* const extractor,
134 const rgw::auth::LocalApplier::Factory* const apl_factory)
135 : cct(cct),
136 driver(_driver),
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
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);
148 }
149 };
150
151 /* SwiftAnonymous: applier. */
152 class SwiftAnonymousApplier : public rgw::auth::LocalApplier {
153 public:
154 SwiftAnonymousApplier(CephContext* const cct,
155 const RGWUserInfo& user_info)
156 : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, std::nullopt, LocalApplier::NO_ACCESS_KEY) {
157 }
158 bool is_admin_of(const rgw_user& uid) const {return false;}
159 bool is_owner_of(const rgw_user& uid) const {return uid.id.compare(RGW_USER_ANON_ID) == 0;}
160 };
161
162 class 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
169 public:
170 SwiftAnonymousEngine(CephContext* const cct,
171 const SwiftAnonymousApplier::Factory* const apl_factory,
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
183 class DefaultStrategy : public rgw::auth::Strategy,
184 public rgw::auth::RemoteApplier::Factory,
185 public rgw::auth::LocalApplier::Factory,
186 public rgw::auth::swift::TempURLApplier::Factory {
187 rgw::sal::Driver* driver;
188 const ImplicitTenants& implicit_tenant_context;
189
190 /* The engines. */
191 const rgw::auth::swift::TempURLEngine tempurl_engine;
192 const rgw::auth::swift::SignedTokenEngine signed_engine;
193 boost::optional <const rgw::auth::keystone::TokenEngine> keystone_engine;
194 const rgw::auth::swift::ExternalTokenEngine external_engine;
195 const rgw::auth::swift::SwiftAnonymousEngine anon_engine;
196
197 using keystone_config_t = rgw::keystone::CephCtxConfig;
198 using keystone_cache_t = rgw::keystone::TokenCache;
199 using aplptr_t = rgw::auth::IdentityApplier::aplptr_t;
200 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
201
202 /* The method implements TokenExtractor for X-Auth-Token present in req_state. */
203 struct AuthTokenExtractor : rgw::auth::TokenExtractor {
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 } auth_token_extractor;
210
211 /* The method implements TokenExtractor for X-Service-Token present in req_state. */
212 struct ServiceTokenExtractor : rgw::auth::TokenExtractor {
213 std::string get_token(const req_state* const s) const override {
214 return s->info.env->get("HTTP_X_SERVICE_TOKEN", "");
215 }
216 } service_token_extractor;
217
218 aplptr_t create_apl_remote(CephContext* const cct,
219 const req_state* const s,
220 acl_strategy_t&& extra_acl_strategy,
221 const rgw::auth::RemoteApplier::AuthInfo &info) const override {
222 auto apl = \
223 rgw::auth::add_3rdparty(driver, rgw_user(s->account_name),
224 rgw::auth::add_sysreq(cct, driver, s,
225 rgw::auth::RemoteApplier(cct, driver, std::move(extra_acl_strategy), info,
226 implicit_tenant_context,
227 rgw::auth::ImplicitTenants::IMPLICIT_TENANTS_SWIFT)));
228 /* TODO(rzarzynski): replace with static_ptr. */
229 return aplptr_t(new decltype(apl)(std::move(apl)));
230 }
231
232 aplptr_t create_apl_local(CephContext* const cct,
233 const req_state* const s,
234 const RGWUserInfo& user_info,
235 const std::string& subuser,
236 const std::optional<uint32_t>& perm_mask,
237 const std::string& access_key_id) const override {
238 auto apl = \
239 rgw::auth::add_3rdparty(driver, rgw_user(s->account_name),
240 rgw::auth::add_sysreq(cct, driver, s,
241 rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask, access_key_id)));
242 /* TODO(rzarzynski): replace with static_ptr. */
243 return aplptr_t(new decltype(apl)(std::move(apl)));
244 }
245
246 aplptr_t create_apl_turl(CephContext* const cct,
247 const req_state* const s,
248 const RGWUserInfo& user_info) const override {
249 /* TempURL doesn't need any user account override. It's a Swift-specific
250 * mechanism that requires account name internally, so there is no
251 * business with delegating the responsibility outside. */
252 return aplptr_t(new rgw::auth::swift::TempURLApplier(cct, user_info));
253 }
254
255 public:
256 DefaultStrategy(CephContext* const cct,
257 const ImplicitTenants& implicit_tenant_context,
258 rgw::sal::Driver* _driver)
259 : driver(_driver),
260 implicit_tenant_context(implicit_tenant_context),
261 tempurl_engine(cct,
262 driver,
263 static_cast<rgw::auth::swift::TempURLApplier::Factory*>(this)),
264 signed_engine(cct,
265 driver,
266 static_cast<rgw::auth::TokenExtractor*>(&auth_token_extractor),
267 static_cast<rgw::auth::LocalApplier::Factory*>(this)),
268 external_engine(cct,
269 driver,
270 static_cast<rgw::auth::TokenExtractor*>(&auth_token_extractor),
271 static_cast<rgw::auth::LocalApplier::Factory*>(this)),
272 anon_engine(cct,
273 static_cast<SwiftAnonymousApplier::Factory*>(this),
274 static_cast<rgw::auth::TokenExtractor*>(&auth_token_extractor)) {
275 /* When the constructor's body is being executed, all member engines
276 * should be initialized. Thus, we can safely add them. */
277 using Control = rgw::auth::Strategy::Control;
278
279 add_engine(Control::SUFFICIENT, tempurl_engine);
280 add_engine(Control::SUFFICIENT, signed_engine);
281
282 /* The auth strategy is responsible for deciding whether a parcular
283 * engine is disabled or not. */
284 if (! cct->_conf->rgw_keystone_url.empty()) {
285 keystone_engine.emplace(cct,
286 static_cast<rgw::auth::TokenExtractor*>(&auth_token_extractor),
287 static_cast<rgw::auth::TokenExtractor*>(&service_token_extractor),
288 static_cast<rgw::auth::RemoteApplier::Factory*>(this),
289 keystone_config_t::get_instance(),
290 keystone_cache_t::get_instance<keystone_config_t>());
291
292 add_engine(Control::SUFFICIENT, *keystone_engine);
293 }
294 if (! cct->_conf->rgw_swift_auth_url.empty()) {
295 add_engine(Control::SUFFICIENT, external_engine);
296 }
297
298 add_engine(Control::SUFFICIENT, anon_engine);
299 }
300
301 const char* get_name() const noexcept override {
302 return "rgw::auth::swift::DefaultStrategy";
303 }
304 };
305
306 } /* namespace swift */
307 } /* namespace auth */
308 } /* namespace rgw */
309
310
311 class RGW_SWIFT_Auth_Get : public RGWOp {
312 public:
313 RGW_SWIFT_Auth_Get() {}
314 ~RGW_SWIFT_Auth_Get() override {}
315
316 int verify_permission(optional_yield) override { return 0; }
317 void execute(optional_yield y) override;
318 const char* name() const override { return "swift_auth_get"; }
319 dmc::client_id dmclock_client() override { return dmc::client_id::auth; }
320 };
321
322 class RGWHandler_SWIFT_Auth : public RGWHandler_REST {
323 public:
324 RGWHandler_SWIFT_Auth() {}
325 ~RGWHandler_SWIFT_Auth() override {}
326 RGWOp *op_get() override;
327
328 int init(rgw::sal::Driver* driver, req_state *state, rgw::io::BasicClient *cio) override;
329 int authorize(const DoutPrefixProvider *dpp, optional_yield y) override;
330 int postauth_init(optional_yield) override { return 0; }
331 int read_permissions(RGWOp *op, optional_yield) override { return 0; }
332
333 virtual RGWAccessControlPolicy *alloc_policy() { return NULL; }
334 virtual void free_policy(RGWAccessControlPolicy *policy) {}
335 };
336
337 class RGWRESTMgr_SWIFT_Auth : public RGWRESTMgr {
338 public:
339 RGWRESTMgr_SWIFT_Auth() = default;
340 ~RGWRESTMgr_SWIFT_Auth() override = default;
341
342 RGWRESTMgr *get_resource_mgr(req_state* const s,
343 const std::string& uri,
344 std::string* const out_uri) override {
345 return this;
346 }
347
348 RGWHandler_REST* get_handler(rgw::sal::Driver* driver,
349 req_state*,
350 const rgw::auth::StrategyRegistry&,
351 const std::string&) override {
352 return new RGWHandler_SWIFT_Auth;
353 }
354 };