]>
Commit | Line | Data |
---|---|---|
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 | ||
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) | |
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 */ | |
41 | class 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 | |
61 | public: | |
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 */ | |
80 | class 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 | ||
94 | public: | |
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 */ | |
117 | class 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 | |
130 | public: | |
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. */ |
152 | class 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 | |
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, | |
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 | ||
183 | class 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 | ||
246 | public: | |
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 | ||
301 | class RGW_SWIFT_Auth_Get : public RGWOp { | |
302 | public: | |
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 | ||
312 | class RGWHandler_SWIFT_Auth : public RGWHandler_REST { | |
313 | public: | |
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 | ||
327 | class RGWRESTMgr_SWIFT_Auth : public RGWRESTMgr { | |
328 | public: | |
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 |