]>
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) | |
11fdf7f2 | 27 | : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, boost::none) { |
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; | |
9f95a23c | 45 | /* const */ RGWCtl* const ctl; |
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, | |
7c673cae | 51 | RGWUserInfo& owner_info) const; |
11fdf7f2 | 52 | std::string convert_from_iso8601(std::string expires) const; |
7c673cae FG |
53 | bool is_applicable(const req_state* s) const noexcept; |
54 | bool is_expired(const std::string& expires) const; | |
494da23a | 55 | bool is_disallowed_header_present(const req_info& info) const; |
7c673cae FG |
56 | |
57 | class SignatureHelper; | |
d2e6a577 | 58 | class PrefixableSignatureHelper; |
7c673cae FG |
59 | |
60 | public: | |
61 | TempURLEngine(CephContext* const cct, | |
9f95a23c | 62 | /*const*/ RGWCtl* const ctl, |
7c673cae FG |
63 | const TempURLApplier::Factory* const apl_factory) |
64 | : cct(cct), | |
9f95a23c | 65 | ctl(ctl), |
7c673cae FG |
66 | apl_factory(apl_factory) { |
67 | } | |
68 | ||
69 | /* Interface implementations. */ | |
70 | const char* get_name() const noexcept override { | |
71 | return "rgw::auth::swift::TempURLEngine"; | |
72 | } | |
73 | ||
11fdf7f2 | 74 | result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const override; |
7c673cae FG |
75 | }; |
76 | ||
77 | ||
78 | /* AUTH_rgwtk */ | |
79 | class SignedTokenEngine : public rgw::auth::Engine { | |
80 | using result_t = rgw::auth::Engine::result_t; | |
81 | ||
82 | CephContext* const cct; | |
9f95a23c | 83 | RGWCtl* const ctl; |
7c673cae FG |
84 | const rgw::auth::TokenExtractor* const extractor; |
85 | const rgw::auth::LocalApplier::Factory* const apl_factory; | |
86 | ||
87 | bool is_applicable(const std::string& token) const noexcept; | |
11fdf7f2 TL |
88 | result_t authenticate(const DoutPrefixProvider* dpp, |
89 | const std::string& token, | |
7c673cae FG |
90 | const req_state* s) const; |
91 | ||
92 | public: | |
93 | SignedTokenEngine(CephContext* const cct, | |
9f95a23c | 94 | /* const */RGWCtl* const ctl, |
7c673cae FG |
95 | const rgw::auth::TokenExtractor* const extractor, |
96 | const rgw::auth::LocalApplier::Factory* const apl_factory) | |
97 | : cct(cct), | |
9f95a23c | 98 | ctl(ctl), |
7c673cae FG |
99 | extractor(extractor), |
100 | apl_factory(apl_factory) { | |
101 | } | |
102 | ||
103 | const char* get_name() const noexcept override { | |
104 | return "rgw::auth::swift::SignedTokenEngine"; | |
105 | } | |
106 | ||
11fdf7f2 TL |
107 | result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const override { |
108 | return authenticate(dpp, extractor->get_token(s), s); | |
7c673cae FG |
109 | } |
110 | }; | |
111 | ||
112 | ||
113 | /* External token */ | |
114 | class ExternalTokenEngine : public rgw::auth::Engine { | |
115 | using result_t = rgw::auth::Engine::result_t; | |
116 | ||
117 | CephContext* const cct; | |
9f95a23c | 118 | RGWCtl* const ctl; |
7c673cae FG |
119 | const rgw::auth::TokenExtractor* const extractor; |
120 | const rgw::auth::LocalApplier::Factory* const apl_factory; | |
121 | ||
122 | bool is_applicable(const std::string& token) const noexcept; | |
11fdf7f2 TL |
123 | result_t authenticate(const DoutPrefixProvider* dpp, |
124 | const std::string& token, | |
7c673cae FG |
125 | const req_state* s) const; |
126 | ||
127 | public: | |
128 | ExternalTokenEngine(CephContext* const cct, | |
9f95a23c | 129 | /* const */RGWCtl* const ctl, |
7c673cae FG |
130 | const rgw::auth::TokenExtractor* const extractor, |
131 | const rgw::auth::LocalApplier::Factory* const apl_factory) | |
132 | : cct(cct), | |
9f95a23c | 133 | ctl(ctl), |
7c673cae FG |
134 | extractor(extractor), |
135 | apl_factory(apl_factory) { | |
136 | } | |
137 | ||
138 | const char* get_name() const noexcept override { | |
139 | return "rgw::auth::swift::ExternalTokenEngine"; | |
140 | } | |
141 | ||
11fdf7f2 TL |
142 | result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const override { |
143 | return authenticate(dpp, extractor->get_token(s), s); | |
7c673cae FG |
144 | } |
145 | }; | |
146 | ||
e306af50 TL |
147 | /* SwiftAnonymous: applier. */ |
148 | class SwiftAnonymousApplier : public rgw::auth::LocalApplier { | |
149 | public: | |
150 | SwiftAnonymousApplier(CephContext* const cct, | |
151 | const RGWUserInfo& user_info) | |
152 | : LocalApplier(cct, user_info, LocalApplier::NO_SUBUSER, boost::none) { | |
153 | }; | |
154 | bool is_admin_of(const rgw_user& uid) const {return false;} | |
155 | bool is_owner_of(const rgw_user& uid) const {return false;} | |
156 | }; | |
7c673cae FG |
157 | |
158 | class SwiftAnonymousEngine : public rgw::auth::AnonymousEngine { | |
159 | const rgw::auth::TokenExtractor* const extractor; | |
160 | ||
161 | bool is_applicable(const req_state* s) const noexcept override { | |
162 | return extractor->get_token(s).empty(); | |
163 | } | |
164 | ||
165 | public: | |
166 | SwiftAnonymousEngine(CephContext* const cct, | |
e306af50 | 167 | const SwiftAnonymousApplier::Factory* const apl_factory, |
7c673cae FG |
168 | const rgw::auth::TokenExtractor* const extractor) |
169 | : AnonymousEngine(cct, apl_factory), | |
170 | extractor(extractor) { | |
171 | } | |
172 | ||
173 | const char* get_name() const noexcept override { | |
174 | return "rgw::auth::swift::SwiftAnonymousEngine"; | |
175 | } | |
176 | }; | |
177 | ||
178 | ||
179 | class DefaultStrategy : public rgw::auth::Strategy, | |
180 | public rgw::auth::TokenExtractor, | |
181 | public rgw::auth::RemoteApplier::Factory, | |
182 | public rgw::auth::LocalApplier::Factory, | |
183 | public rgw::auth::swift::TempURLApplier::Factory { | |
9f95a23c TL |
184 | RGWCtl* const ctl; |
185 | ImplicitTenants& implicit_tenant_context; | |
7c673cae FG |
186 | |
187 | /* The engines. */ | |
188 | const rgw::auth::swift::TempURLEngine tempurl_engine; | |
189 | const rgw::auth::swift::SignedTokenEngine signed_engine; | |
3efd9988 | 190 | boost::optional <const rgw::auth::keystone::TokenEngine> keystone_engine; |
7c673cae FG |
191 | const rgw::auth::swift::ExternalTokenEngine external_engine; |
192 | const rgw::auth::swift::SwiftAnonymousEngine anon_engine; | |
193 | ||
194 | using keystone_config_t = rgw::keystone::CephCtxConfig; | |
195 | using keystone_cache_t = rgw::keystone::TokenCache; | |
196 | using aplptr_t = rgw::auth::IdentityApplier::aplptr_t; | |
197 | using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t; | |
198 | ||
199 | /* The method implements TokenExtractor for X-Auth-Token present in req_state. */ | |
200 | std::string get_token(const req_state* const s) const override { | |
201 | /* Returning a reference here would end in GCC complaining about a reference | |
202 | * to temporary. */ | |
203 | return s->info.env->get("HTTP_X_AUTH_TOKEN", ""); | |
204 | } | |
205 | ||
206 | aplptr_t create_apl_remote(CephContext* const cct, | |
207 | const req_state* const s, | |
208 | acl_strategy_t&& extra_acl_strategy, | |
11fdf7f2 | 209 | const rgw::auth::RemoteApplier::AuthInfo &info) const override { |
e306af50 TL |
210 | rgw_user user(s->account_name); |
211 | if (info.is_anon()) | |
212 | user = rgw_user(RGW_USER_ANON_ID); | |
7c673cae | 213 | auto apl = \ |
e306af50 | 214 | rgw::auth::add_3rdparty(ctl, user, |
9f95a23c TL |
215 | rgw::auth::add_sysreq(cct, ctl, s, |
216 | rgw::auth::RemoteApplier(cct, ctl, std::move(extra_acl_strategy), info, | |
217 | implicit_tenant_context, | |
218 | rgw::auth::ImplicitTenants::IMPLICIT_TENANTS_SWIFT))); | |
7c673cae FG |
219 | /* TODO(rzarzynski): replace with static_ptr. */ |
220 | return aplptr_t(new decltype(apl)(std::move(apl))); | |
221 | } | |
222 | ||
223 | aplptr_t create_apl_local(CephContext* const cct, | |
224 | const req_state* const s, | |
225 | const RGWUserInfo& user_info, | |
11fdf7f2 TL |
226 | const std::string& subuser, |
227 | const boost::optional<uint32_t>& perm_mask) const override { | |
e306af50 TL |
228 | rgw_user user(s->account_name); |
229 | if (user_info.user_id.compare(RGW_USER_ANON_ID) == 0) | |
230 | user = rgw_user(user_info.user_id); | |
7c673cae | 231 | auto apl = \ |
e306af50 | 232 | rgw::auth::add_3rdparty(ctl, user, |
9f95a23c | 233 | rgw::auth::add_sysreq(cct, ctl, s, |
11fdf7f2 | 234 | rgw::auth::LocalApplier(cct, user_info, subuser, perm_mask))); |
7c673cae FG |
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, | |
9f95a23c TL |
250 | ImplicitTenants& implicit_tenant_context, |
251 | RGWCtl* const ctl) | |
252 | : ctl(ctl), | |
253 | implicit_tenant_context(implicit_tenant_context), | |
7c673cae | 254 | tempurl_engine(cct, |
9f95a23c | 255 | ctl, |
7c673cae FG |
256 | static_cast<rgw::auth::swift::TempURLApplier::Factory*>(this)), |
257 | signed_engine(cct, | |
9f95a23c | 258 | ctl, |
7c673cae FG |
259 | static_cast<rgw::auth::TokenExtractor*>(this), |
260 | static_cast<rgw::auth::LocalApplier::Factory*>(this)), | |
7c673cae | 261 | external_engine(cct, |
9f95a23c | 262 | ctl, |
7c673cae FG |
263 | static_cast<rgw::auth::TokenExtractor*>(this), |
264 | static_cast<rgw::auth::LocalApplier::Factory*>(this)), | |
265 | anon_engine(cct, | |
266 | static_cast<rgw::auth::LocalApplier::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()) { | |
3efd9988 FG |
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); | |
7c673cae FG |
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() override { return 0; } | |
309 | void execute() override; | |
11fdf7f2 TL |
310 | const char* name() const override { return "swift_auth_get"; } |
311 | dmc::client_id dmclock_client() override { return dmc::client_id::auth; } | |
7c673cae FG |
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 | ||
9f95a23c | 320 | int init(rgw::sal::RGWRadosStore *store, struct req_state *state, rgw::io::BasicClient *cio) override; |
11fdf7f2 | 321 | int authorize(const DoutPrefixProvider *dpp) override; |
7c673cae FG |
322 | int postauth_init() override { return 0; } |
323 | int read_permissions(RGWOp *op) 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(struct req_state*, | |
341 | const rgw::auth::StrategyRegistry&, | |
342 | const std::string&) override { | |
343 | return new RGWHandler_SWIFT_Auth; | |
344 | } | |
345 | }; | |
346 | ||
347 | ||
348 | #endif |