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