Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / 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
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;
52   class PrefixableSignatureHelper;
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;
167
168   /* The engines. */
169   const rgw::auth::swift::TempURLEngine tempurl_engine;
170   const rgw::auth::swift::SignedTokenEngine signed_engine;
171   boost::optional <const rgw::auth::keystone::TokenEngine> keystone_engine;
172   const rgw::auth::swift::ExternalTokenEngine external_engine;
173   const rgw::auth::swift::SwiftAnonymousEngine anon_engine;
174
175   using keystone_config_t = rgw::keystone::CephCtxConfig;
176   using keystone_cache_t = rgw::keystone::TokenCache;
177   using aplptr_t = rgw::auth::IdentityApplier::aplptr_t;
178   using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
179
180   /* The method implements TokenExtractor for X-Auth-Token present in req_state. */
181   std::string get_token(const req_state* const s) const override {
182     /* Returning a reference here would end in GCC complaining about a reference
183      * to temporary. */
184     return s->info.env->get("HTTP_X_AUTH_TOKEN", "");
185   }
186
187   aplptr_t create_apl_remote(CephContext* const cct,
188                              const req_state* const s,
189                              acl_strategy_t&& extra_acl_strategy,
190                              const rgw::auth::RemoteApplier::AuthInfo info) const override {
191     auto apl = \
192       rgw::auth::add_3rdparty(store, s->account_name,
193         rgw::auth::add_sysreq(cct, store, s,
194           rgw::auth::RemoteApplier(cct, store, std::move(extra_acl_strategy), info,
195                                    cct->_conf->rgw_keystone_implicit_tenants)));
196     /* TODO(rzarzynski): replace with static_ptr. */
197     return aplptr_t(new decltype(apl)(std::move(apl)));
198   }
199
200   aplptr_t create_apl_local(CephContext* const cct,
201                             const req_state* const s,
202                             const RGWUserInfo& user_info,
203                             const std::string& subuser) const override {
204     auto apl = \
205       rgw::auth::add_3rdparty(store, s->account_name,
206         rgw::auth::add_sysreq(cct, store, s,
207           rgw::auth::LocalApplier(cct, user_info, subuser)));
208     /* TODO(rzarzynski): replace with static_ptr. */
209     return aplptr_t(new decltype(apl)(std::move(apl)));
210   }
211
212   aplptr_t create_apl_turl(CephContext* const cct,
213                            const req_state* const s,
214                            const RGWUserInfo& user_info) const override {
215     /* TempURL doesn't need any user account override. It's a Swift-specific
216      * mechanism that requires  account name internally, so there is no
217      * business with delegating the responsibility outside. */
218     return aplptr_t(new rgw::auth::swift::TempURLApplier(cct, user_info));
219   }
220
221 public:
222   DefaultStrategy(CephContext* const cct,
223                   RGWRados* const store)
224     : store(store),
225       tempurl_engine(cct,
226                      store,
227                      static_cast<rgw::auth::swift::TempURLApplier::Factory*>(this)),
228       signed_engine(cct,
229                     store,
230                     static_cast<rgw::auth::TokenExtractor*>(this),
231                     static_cast<rgw::auth::LocalApplier::Factory*>(this)),
232       external_engine(cct,
233                       store,
234                       static_cast<rgw::auth::TokenExtractor*>(this),
235                       static_cast<rgw::auth::LocalApplier::Factory*>(this)),
236       anon_engine(cct,
237                   static_cast<rgw::auth::LocalApplier::Factory*>(this),
238                   static_cast<rgw::auth::TokenExtractor*>(this)) {
239     /* When the constructor's body is being executed, all member engines
240      * should be initialized. Thus, we can safely add them. */
241     using Control = rgw::auth::Strategy::Control;
242
243     add_engine(Control::SUFFICIENT, tempurl_engine);
244     add_engine(Control::SUFFICIENT, signed_engine);
245
246     /* The auth strategy is responsible for deciding whether a parcular
247      * engine is disabled or not. */
248     if (! cct->_conf->rgw_keystone_url.empty()) {
249       keystone_engine.emplace(cct,
250                               static_cast<rgw::auth::TokenExtractor*>(this),
251                               static_cast<rgw::auth::RemoteApplier::Factory*>(this),
252                               keystone_config_t::get_instance(),
253                               keystone_cache_t::get_instance<keystone_config_t>());
254
255       add_engine(Control::SUFFICIENT, *keystone_engine);
256     }
257     if (! cct->_conf->rgw_swift_auth_url.empty()) {
258       add_engine(Control::SUFFICIENT, external_engine);
259     }
260
261     add_engine(Control::SUFFICIENT, anon_engine);
262   }
263
264   const char* get_name() const noexcept override {
265     return "rgw::auth::swift::DefaultStrategy";
266   }
267 };
268
269 } /* namespace swift */
270 } /* namespace auth */
271 } /* namespace rgw */
272
273
274 class RGW_SWIFT_Auth_Get : public RGWOp {
275 public:
276   RGW_SWIFT_Auth_Get() {}
277   ~RGW_SWIFT_Auth_Get() override {}
278
279   int verify_permission() override { return 0; }
280   void execute() override;
281   const string name() override { return "swift_auth_get"; }
282 };
283
284 class RGWHandler_SWIFT_Auth : public RGWHandler_REST {
285 public:
286   RGWHandler_SWIFT_Auth() {}
287   ~RGWHandler_SWIFT_Auth() override {}
288   RGWOp *op_get() override;
289
290   int init(RGWRados *store, struct req_state *state, rgw::io::BasicClient *cio) override;
291   int authorize() override;
292   int postauth_init() override { return 0; }
293   int read_permissions(RGWOp *op) override { return 0; }
294
295   virtual RGWAccessControlPolicy *alloc_policy() { return NULL; }
296   virtual void free_policy(RGWAccessControlPolicy *policy) {}
297 };
298
299 class RGWRESTMgr_SWIFT_Auth : public RGWRESTMgr {
300 public:
301   RGWRESTMgr_SWIFT_Auth() = default;
302   ~RGWRESTMgr_SWIFT_Auth() override = default;
303
304   RGWRESTMgr *get_resource_mgr(struct req_state* const s,
305                                const std::string& uri,
306                                std::string* const out_uri) override {
307     return this;
308   }
309
310   RGWHandler_REST* get_handler(struct req_state*,
311                                const rgw::auth::StrategyRegistry&,
312                                const std::string&) override {
313     return new RGWHandler_SWIFT_Auth;
314   }
315 };
316
317
318 #endif