Fix some bugs when testing opensds ansible
[stor4nfv.git] / src / ceph / src / rgw / rgw_rest_s3.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_REST_S3_H
5
6 #define CEPH_RGW_REST_S3_H
7 #define TIME_BUF_SIZE 128
8
9 #include <mutex>
10
11 #include <boost/utility/string_view.hpp>
12 #include <boost/container/static_vector.hpp>
13
14 #include "common/backport14.h"
15 #include "common/sstring.hh"
16 #include "rgw_op.h"
17 #include "rgw_rest.h"
18 #include "rgw_http_errors.h"
19 #include "rgw_acl_s3.h"
20 #include "rgw_policy_s3.h"
21 #include "rgw_lc_s3.h"
22 #include "rgw_keystone.h"
23 #include "rgw_rest_conn.h"
24 #include "rgw_ldap.h"
25 #include "rgw_rest.h"
26
27 #include "rgw_token.h"
28 #include "include/assert.h"
29
30 #include "rgw_auth.h"
31 #include "rgw_auth_filters.h"
32
33 #define RGW_AUTH_GRACE_MINS 15
34
35 struct rgw_http_error {
36   int http_ret;
37   const char *s3_code;
38 };
39
40 void rgw_get_errno_s3(struct rgw_http_error *e, int err_no);
41
42 class RGWGetObj_ObjStore_S3 : public RGWGetObj_ObjStore
43 {
44 protected:
45   // Serving a custom error page from an object is really a 200 response with
46   // just the status line altered.
47   int custom_http_ret = 0;
48   std::map<std::string, std::string> crypt_http_responses;
49 public:
50   RGWGetObj_ObjStore_S3() {}
51   ~RGWGetObj_ObjStore_S3() override {}
52
53   int get_params() override;
54   int send_response_data_error() override;
55   int send_response_data(bufferlist& bl, off_t ofs, off_t len) override;
56   void set_custom_http_response(int http_ret) { custom_http_ret = http_ret; }
57   int get_decrypt_filter(std::unique_ptr<RGWGetDataCB>* filter,
58                          RGWGetDataCB* cb,
59                          bufferlist* manifest_bl) override;
60 };
61
62 class RGWGetObjTags_ObjStore_S3 : public RGWGetObjTags_ObjStore
63 {
64   bufferlist tags_bl;
65 public:
66   RGWGetObjTags_ObjStore_S3() {}
67   ~RGWGetObjTags_ObjStore_S3() {}
68
69   void send_response_data(bufferlist &bl) override;
70 };
71
72 class RGWPutObjTags_ObjStore_S3 : public RGWPutObjTags_ObjStore
73 {
74 public:
75   RGWPutObjTags_ObjStore_S3() {}
76   ~RGWPutObjTags_ObjStore_S3() {}
77
78   int get_params() override;
79   void send_response() override;
80 };
81
82 class RGWDeleteObjTags_ObjStore_S3 : public RGWDeleteObjTags
83 {
84 public:
85   ~RGWDeleteObjTags_ObjStore_S3() override {}
86   void send_response() override;
87 };
88
89 class RGWListBuckets_ObjStore_S3 : public RGWListBuckets_ObjStore {
90 public:
91   RGWListBuckets_ObjStore_S3() {}
92   ~RGWListBuckets_ObjStore_S3() override {}
93
94   int get_params() override {
95     limit = -1; /* no limit */
96     return 0;
97   }
98   void send_response_begin(bool has_buckets) override;
99   void send_response_data(RGWUserBuckets& buckets) override;
100   void send_response_end() override;
101 };
102
103 class RGWGetUsage_ObjStore_S3 : public RGWGetUsage_ObjStore {
104 public:
105   RGWGetUsage_ObjStore_S3() {}
106   ~RGWGetUsage_ObjStore_S3() override {}
107
108   int get_params() override ;
109   void send_response() override;
110 };
111
112 class RGWListBucket_ObjStore_S3 : public RGWListBucket_ObjStore {
113   bool objs_container;
114 public:
115   RGWListBucket_ObjStore_S3() : objs_container(false) {
116     default_max = 1000;
117   }
118   ~RGWListBucket_ObjStore_S3() override {}
119
120   int get_params() override;
121   void send_response() override;
122   void send_versioned_response();
123 };
124
125 class RGWGetBucketLogging_ObjStore_S3 : public RGWGetBucketLogging {
126 public:
127   RGWGetBucketLogging_ObjStore_S3() {}
128   ~RGWGetBucketLogging_ObjStore_S3() override {}
129
130   void send_response() override;
131 };
132
133 class RGWGetBucketLocation_ObjStore_S3 : public RGWGetBucketLocation {
134 public:
135   RGWGetBucketLocation_ObjStore_S3() {}
136   ~RGWGetBucketLocation_ObjStore_S3() override {}
137
138   void send_response() override;
139 };
140
141 class RGWGetBucketVersioning_ObjStore_S3 : public RGWGetBucketVersioning {
142 public:
143   RGWGetBucketVersioning_ObjStore_S3() {}
144   ~RGWGetBucketVersioning_ObjStore_S3() override {}
145
146   void send_response() override;
147 };
148
149 class RGWSetBucketVersioning_ObjStore_S3 : public RGWSetBucketVersioning {
150 public:
151   RGWSetBucketVersioning_ObjStore_S3() {}
152   ~RGWSetBucketVersioning_ObjStore_S3() override {}
153
154   int get_params() override;
155   void send_response() override;
156 };
157
158 class RGWGetBucketWebsite_ObjStore_S3 : public RGWGetBucketWebsite {
159 public:
160   RGWGetBucketWebsite_ObjStore_S3() {}
161   ~RGWGetBucketWebsite_ObjStore_S3() override {}
162
163   void send_response() override;
164 };
165
166 class RGWSetBucketWebsite_ObjStore_S3 : public RGWSetBucketWebsite {
167 public:
168   RGWSetBucketWebsite_ObjStore_S3() {}
169   ~RGWSetBucketWebsite_ObjStore_S3() override {}
170
171   int get_params() override;
172   void send_response() override;
173 };
174
175 class RGWDeleteBucketWebsite_ObjStore_S3 : public RGWDeleteBucketWebsite {
176 public:
177   RGWDeleteBucketWebsite_ObjStore_S3() {}
178   ~RGWDeleteBucketWebsite_ObjStore_S3() override {}
179
180   void send_response() override;
181 };
182
183 class RGWStatBucket_ObjStore_S3 : public RGWStatBucket_ObjStore {
184 public:
185   RGWStatBucket_ObjStore_S3() {}
186   ~RGWStatBucket_ObjStore_S3() override {}
187
188   void send_response() override;
189 };
190
191 class RGWCreateBucket_ObjStore_S3 : public RGWCreateBucket_ObjStore {
192 public:
193   RGWCreateBucket_ObjStore_S3() {}
194   ~RGWCreateBucket_ObjStore_S3() override {}
195
196   int get_params() override;
197   void send_response() override;
198 };
199
200 class RGWDeleteBucket_ObjStore_S3 : public RGWDeleteBucket_ObjStore {
201 public:
202   RGWDeleteBucket_ObjStore_S3() {}
203   ~RGWDeleteBucket_ObjStore_S3() override {}
204
205   void send_response() override;
206 };
207
208 class RGWPutObj_ObjStore_S3 : public RGWPutObj_ObjStore {
209 private:
210   std::map<std::string, std::string> crypt_http_responses;
211
212 public:
213   RGWPutObj_ObjStore_S3() {}
214   ~RGWPutObj_ObjStore_S3() override {}
215
216   int get_params() override;
217   int get_data(bufferlist& bl) override;
218   void send_response() override;
219
220   int get_encrypt_filter(std::unique_ptr<RGWPutObjDataProcessor>* filter,
221                          RGWPutObjDataProcessor* cb) override;
222   int get_decrypt_filter(std::unique_ptr<RGWGetDataCB>* filter,
223                          RGWGetDataCB* cb,
224                          map<string, bufferlist>& attrs,
225                          bufferlist* manifest_bl) override;
226 };
227
228 class RGWPostObj_ObjStore_S3 : public RGWPostObj_ObjStore {
229   parts_collection_t parts;
230   std::string filename;
231   std::string content_type;
232   RGWPolicyEnv env;
233   RGWPolicy post_policy;
234   map<string, string> crypt_http_responses;
235
236   const rgw::auth::StrategyRegistry* auth_registry_ptr = nullptr;
237
238   int get_policy();
239   int get_tags();
240   void rebuild_key(string& key);
241
242   std::string get_current_filename() const override;
243   std::string get_current_content_type() const override;
244
245 public:
246   RGWPostObj_ObjStore_S3() {}
247   ~RGWPostObj_ObjStore_S3() override {}
248
249   int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) {
250     auth_registry_ptr = &auth_registry;
251     return RGWPostObj_ObjStore::verify_requester(auth_registry);
252   }
253
254   int get_params() override;
255   int complete_get_params();
256
257   void send_response() override;
258   int get_data(ceph::bufferlist& bl, bool& again) override;
259   int get_encrypt_filter(std::unique_ptr<RGWPutObjDataProcessor>* filter,
260                          RGWPutObjDataProcessor* cb) override;
261 };
262
263 class RGWDeleteObj_ObjStore_S3 : public RGWDeleteObj_ObjStore {
264 public:
265   RGWDeleteObj_ObjStore_S3() {}
266   ~RGWDeleteObj_ObjStore_S3() override {}
267
268   int get_params() override;
269   void send_response() override;
270 };
271
272 class RGWCopyObj_ObjStore_S3 : public RGWCopyObj_ObjStore {
273   bool sent_header;
274 public:
275   RGWCopyObj_ObjStore_S3() : sent_header(false) {}
276   ~RGWCopyObj_ObjStore_S3() override {}
277
278   int init_dest_policy() override;
279   int get_params() override;
280   void send_partial_response(off_t ofs) override;
281   void send_response() override;
282 };
283
284 class RGWGetACLs_ObjStore_S3 : public RGWGetACLs_ObjStore {
285 public:
286   RGWGetACLs_ObjStore_S3() {}
287   ~RGWGetACLs_ObjStore_S3() override {}
288
289   void send_response() override;
290 };
291
292 class RGWPutACLs_ObjStore_S3 : public RGWPutACLs_ObjStore {
293 public:
294   RGWPutACLs_ObjStore_S3() {}
295   ~RGWPutACLs_ObjStore_S3() override {}
296
297   int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) override;
298   void send_response() override;
299   int get_params() override;
300 };
301
302 class RGWGetLC_ObjStore_S3 : public RGWGetLC_ObjStore {
303 protected:
304   RGWLifecycleConfiguration_S3  config;
305 public:
306   RGWGetLC_ObjStore_S3() {}
307   ~RGWGetLC_ObjStore_S3() override {}
308   void execute() override;
309
310  void send_response() override;
311 };
312
313 class RGWPutLC_ObjStore_S3 : public RGWPutLC_ObjStore {
314 public:
315   RGWPutLC_ObjStore_S3() {}
316   ~RGWPutLC_ObjStore_S3() override {}
317   
318  void send_response() override;
319 };
320
321 class RGWDeleteLC_ObjStore_S3 : public RGWDeleteLC_ObjStore {
322 public:
323   RGWDeleteLC_ObjStore_S3() {}
324   ~RGWDeleteLC_ObjStore_S3() override {}
325   
326  void send_response() override;
327 };
328
329 class RGWGetCORS_ObjStore_S3 : public RGWGetCORS_ObjStore {
330 public:
331   RGWGetCORS_ObjStore_S3() {}
332   ~RGWGetCORS_ObjStore_S3() override {}
333
334   void send_response() override;
335 };
336
337 class RGWPutCORS_ObjStore_S3 : public RGWPutCORS_ObjStore {
338 public:
339   RGWPutCORS_ObjStore_S3() {}
340   ~RGWPutCORS_ObjStore_S3() override {}
341
342   int get_params() override;
343   void send_response() override;
344 };
345
346 class RGWDeleteCORS_ObjStore_S3 : public RGWDeleteCORS_ObjStore {
347 public:
348   RGWDeleteCORS_ObjStore_S3() {}
349   ~RGWDeleteCORS_ObjStore_S3() override {}
350
351   void send_response() override;
352 };
353
354 class RGWOptionsCORS_ObjStore_S3 : public RGWOptionsCORS_ObjStore {
355 public:
356   RGWOptionsCORS_ObjStore_S3() {}
357   ~RGWOptionsCORS_ObjStore_S3() override {}
358
359   void send_response() override;
360 };
361
362 class RGWGetRequestPayment_ObjStore_S3 : public RGWGetRequestPayment {
363 public:
364   RGWGetRequestPayment_ObjStore_S3() {}
365   ~RGWGetRequestPayment_ObjStore_S3() override {}
366
367   void send_response() override;
368 };
369
370 class RGWSetRequestPayment_ObjStore_S3 : public RGWSetRequestPayment {
371 public:
372   RGWSetRequestPayment_ObjStore_S3() {}
373   ~RGWSetRequestPayment_ObjStore_S3() override {}
374
375   int get_params() override;
376   void send_response() override;
377 };
378
379 class RGWInitMultipart_ObjStore_S3 : public RGWInitMultipart_ObjStore {
380 private:
381   std::map<std::string, std::string> crypt_http_responses;
382 public:
383   RGWInitMultipart_ObjStore_S3() {}
384   ~RGWInitMultipart_ObjStore_S3() override {}
385
386   int get_params() override;
387   void send_response() override;
388   int prepare_encryption(map<string, bufferlist>& attrs) override;
389 };
390
391 class RGWCompleteMultipart_ObjStore_S3 : public RGWCompleteMultipart_ObjStore {
392 public:
393   RGWCompleteMultipart_ObjStore_S3() {}
394   ~RGWCompleteMultipart_ObjStore_S3() override {}
395
396   int get_params() override;
397   void send_response() override;
398 };
399
400 class RGWAbortMultipart_ObjStore_S3 : public RGWAbortMultipart_ObjStore {
401 public:
402   RGWAbortMultipart_ObjStore_S3() {}
403   ~RGWAbortMultipart_ObjStore_S3() override {}
404
405   void send_response() override;
406 };
407
408 class RGWListMultipart_ObjStore_S3 : public RGWListMultipart_ObjStore {
409 public:
410   RGWListMultipart_ObjStore_S3() {}
411   ~RGWListMultipart_ObjStore_S3() override {}
412
413   void send_response() override;
414 };
415
416 class RGWListBucketMultiparts_ObjStore_S3 : public RGWListBucketMultiparts_ObjStore {
417 public:
418   RGWListBucketMultiparts_ObjStore_S3() {
419     default_max = 1000;
420   }
421   ~RGWListBucketMultiparts_ObjStore_S3() override {}
422
423   void send_response() override;
424 };
425
426 class RGWDeleteMultiObj_ObjStore_S3 : public RGWDeleteMultiObj_ObjStore {
427 public:
428   RGWDeleteMultiObj_ObjStore_S3() {}
429   ~RGWDeleteMultiObj_ObjStore_S3() override {}
430
431   int get_params() override;
432   void send_status() override;
433   void begin_response() override;
434   void send_partial_response(rgw_obj_key& key, bool delete_marker,
435                              const string& marker_version_id, int ret) override;
436   void end_response() override;
437 };
438
439 class RGWGetObjLayout_ObjStore_S3 : public RGWGetObjLayout {
440 public:
441   RGWGetObjLayout_ObjStore_S3() {}
442   ~RGWGetObjLayout_ObjStore_S3() {}
443
444   void send_response();
445 };
446
447 class RGWConfigBucketMetaSearch_ObjStore_S3 : public RGWConfigBucketMetaSearch {
448 public:
449   RGWConfigBucketMetaSearch_ObjStore_S3() {}
450   ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
451
452   int get_params() override;
453   void send_response() override;
454 };
455
456 class RGWGetBucketMetaSearch_ObjStore_S3 : public RGWGetBucketMetaSearch {
457 public:
458   RGWGetBucketMetaSearch_ObjStore_S3() {}
459   ~RGWGetBucketMetaSearch_ObjStore_S3() {}
460
461   void send_response() override;
462 };
463
464 class RGWDelBucketMetaSearch_ObjStore_S3 : public RGWDelBucketMetaSearch {
465 public:
466   RGWDelBucketMetaSearch_ObjStore_S3() {}
467   ~RGWDelBucketMetaSearch_ObjStore_S3() {}
468
469   void send_response() override;
470 };
471
472 class RGW_Auth_S3 {
473 public:
474   static int authorize(RGWRados *store,
475                        const rgw::auth::StrategyRegistry& auth_registry,
476                        struct req_state *s);
477 };
478
479 class RGWHandler_Auth_S3 : public RGWHandler_REST {
480   friend class RGWRESTMgr_S3;
481
482   const rgw::auth::StrategyRegistry& auth_registry;
483
484 public:
485   RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry& auth_registry)
486     : RGWHandler_REST(),
487       auth_registry(auth_registry) {
488   }
489   ~RGWHandler_Auth_S3() override = default;
490
491   static int validate_bucket_name(const string& bucket);
492   static int validate_object_name(const string& bucket);
493
494   int init(RGWRados *store,
495            struct req_state *s,
496            rgw::io::BasicClient *cio) override;
497   int authorize() override {
498     return RGW_Auth_S3::authorize(store, auth_registry, s);
499   }
500   int postauth_init() override { return 0; }
501 };
502
503 class RGWHandler_REST_S3 : public RGWHandler_REST {
504   friend class RGWRESTMgr_S3;
505
506   const rgw::auth::StrategyRegistry& auth_registry;
507 public:
508   static int init_from_header(struct req_state *s, int default_formatter, bool configurable_format);
509
510   RGWHandler_REST_S3(const rgw::auth::StrategyRegistry& auth_registry)
511     : RGWHandler_REST(),
512       auth_registry(auth_registry) {
513   }
514   ~RGWHandler_REST_S3() override = default;
515
516   int init(RGWRados *store,
517            struct req_state *s,
518            rgw::io::BasicClient *cio) override;
519   int authorize() override {
520     return RGW_Auth_S3::authorize(store, auth_registry, s);
521   }
522   int postauth_init() override;
523 };
524
525 class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
526 protected:
527     bool is_usage_op() {
528     return s->info.args.exists("usage");
529   }
530   RGWOp *op_get() override;
531   RGWOp *op_head() override;
532   RGWOp *op_post() override;
533 public:
534   using RGWHandler_REST_S3::RGWHandler_REST_S3;
535   ~RGWHandler_REST_Service_S3() override = default;
536 };
537
538 class RGWHandler_REST_Bucket_S3 : public RGWHandler_REST_S3 {
539 protected:
540   bool is_acl_op() {
541     return s->info.args.exists("acl");
542   }
543   bool is_cors_op() {
544       return s->info.args.exists("cors");
545   }
546   bool is_lc_op() {
547       return s->info.args.exists("lifecycle");
548   }
549   bool is_obj_update_op() override {
550     return is_acl_op() || is_cors_op();
551   }
552   bool is_request_payment_op() {
553     return s->info.args.exists("requestPayment");
554   }
555   bool is_policy_op() {
556     return s->info.args.exists("policy");
557   }
558   RGWOp *get_obj_op(bool get_data);
559
560   RGWOp *op_get() override;
561   RGWOp *op_head() override;
562   RGWOp *op_put() override;
563   RGWOp *op_delete() override;
564   RGWOp *op_post() override;
565   RGWOp *op_options() override;
566 public:
567   using RGWHandler_REST_S3::RGWHandler_REST_S3;
568   ~RGWHandler_REST_Bucket_S3() override = default;
569 };
570
571 class RGWHandler_REST_Obj_S3 : public RGWHandler_REST_S3 {
572 protected:
573   bool is_acl_op() {
574     return s->info.args.exists("acl");
575   }
576   bool is_cors_op() {
577       return s->info.args.exists("cors");
578   }
579   bool is_tagging_op() {
580     return s->info.args.exists("tagging");
581   }
582   bool is_obj_update_op() override {
583     return is_acl_op() || is_tagging_op() ;
584   }
585   RGWOp *get_obj_op(bool get_data);
586
587   RGWOp *op_get() override;
588   RGWOp *op_head() override;
589   RGWOp *op_put() override;
590   RGWOp *op_delete() override;
591   RGWOp *op_post() override;
592   RGWOp *op_options() override;
593 public:
594   using RGWHandler_REST_S3::RGWHandler_REST_S3;
595   ~RGWHandler_REST_Obj_S3() override = default;
596 };
597
598 class RGWRESTMgr_S3 : public RGWRESTMgr {
599 private:
600   bool enable_s3website;
601 public:
602   explicit RGWRESTMgr_S3(bool enable_s3website = false)
603     : enable_s3website(enable_s3website) {
604   }
605
606   ~RGWRESTMgr_S3() override = default;
607
608   RGWHandler_REST *get_handler(struct req_state* s,
609                                const rgw::auth::StrategyRegistry& auth_registry,
610                                const std::string& frontend_prefix) override;
611 };
612
613 class RGWHandler_REST_Obj_S3Website;
614
615 static inline bool looks_like_ip_address(const char *bucket)
616 {
617   int num_periods = 0;
618   bool expect_period = false;
619   for (const char *b = bucket; *b; ++b) {
620     if (*b == '.') {
621       if (!expect_period)
622         return false;
623       ++num_periods;
624       if (num_periods > 3)
625         return false;
626       expect_period = false;
627     }
628     else if (isdigit(*b)) {
629       expect_period = true;
630     }
631     else {
632       return false;
633     }
634   }
635   return (num_periods == 3);
636 }
637
638 static inline int valid_s3_object_name(const string& name) {
639   if (name.size() > 1024) {
640     return -ERR_INVALID_OBJECT_NAME;
641   }
642   if (check_utf8(name.c_str(), name.size())) {
643     return -ERR_INVALID_OBJECT_NAME;
644   }
645   return 0;
646 }
647
648 static inline int valid_s3_bucket_name(const string& name, bool relaxed=false)
649 {
650   // This function enforces Amazon's spec for bucket names.
651   // (The requirements, not the recommendations.)
652   int len = name.size();
653   if (len < 3) {
654     // Name too short
655     return -ERR_INVALID_BUCKET_NAME;
656   } else if (len > 255) {
657     // Name too long
658     return -ERR_INVALID_BUCKET_NAME;
659   }
660
661   // bucket names must start with a number, letter, or underscore
662   if (!(isalpha(name[0]) || isdigit(name[0]))) {
663     if (!relaxed)
664       return -ERR_INVALID_BUCKET_NAME;
665     else if (!(name[0] == '_' || name[0] == '.' || name[0] == '-'))
666       return -ERR_INVALID_BUCKET_NAME;
667   }
668
669   for (const char *s = name.c_str(); *s; ++s) {
670     char c = *s;
671     if (isdigit(c) || (c == '.'))
672       continue;
673     if (isalpha(c))
674       continue;
675     if ((c == '-') || (c == '_'))
676       continue;
677     // Invalid character
678     return -ERR_INVALID_BUCKET_NAME;
679   }
680
681   if (looks_like_ip_address(name.c_str()))
682     return -ERR_INVALID_BUCKET_NAME;
683
684   return 0;
685 }
686
687
688 namespace rgw {
689 namespace auth {
690 namespace s3 {
691
692 class AWSEngine : public rgw::auth::Engine {
693 public:
694   class VersionAbstractor {
695     static constexpr size_t DIGEST_SIZE_V2 = CEPH_CRYPTO_HMACSHA1_DIGESTSIZE;
696     static constexpr size_t DIGEST_SIZE_V4 = CEPH_CRYPTO_HMACSHA256_DIGESTSIZE;
697
698     /* Knowing the signature max size allows us to employ the sstring, and thus
699      * avoid dynamic allocations. The multiplier comes from representing digest
700      * in the base64-encoded form. */
701     static constexpr size_t SIGNATURE_MAX_SIZE = \
702       ceph::max(DIGEST_SIZE_V2, DIGEST_SIZE_V4) * 2 + sizeof('\0');
703
704   public:
705     virtual ~VersionAbstractor() {};
706
707     using access_key_id_t = boost::string_view;
708     using client_signature_t = boost::string_view;
709     using server_signature_t = basic_sstring<char, uint16_t, SIGNATURE_MAX_SIZE>;
710     using string_to_sign_t = std::string;
711
712     /* Transformation for crafting the AWS signature at server side which is
713      * used later to compare with the user-provided one. The methodology for
714      * doing that depends on AWS auth version. */
715     using signature_factory_t = \
716       std::function<server_signature_t(CephContext* cct,
717                                        const std::string& secret_key,
718                                        const string_to_sign_t& string_to_sign)>;
719
720     /* Return an instance of Completer for verifying the payload's fingerprint
721      * if necessary. Otherwise caller gets nullptr. Caller may provide secret
722      * key */
723     using completer_factory_t = \
724       std::function<rgw::auth::Completer::cmplptr_t(
725         const boost::optional<std::string>& secret_key)>;
726
727     struct auth_data_t {
728       access_key_id_t access_key_id;
729       client_signature_t client_signature;
730       string_to_sign_t string_to_sign;
731       signature_factory_t signature_factory;
732       completer_factory_t completer_factory;
733     };
734
735     virtual auth_data_t get_auth_data(const req_state* s) const = 0;
736   };
737
738 protected:
739   CephContext* cct;
740   const VersionAbstractor& ver_abstractor;
741
742   AWSEngine(CephContext* const cct, const VersionAbstractor& ver_abstractor)
743     : cct(cct),
744       ver_abstractor(ver_abstractor) {
745   }
746
747   using result_t = rgw::auth::Engine::result_t;
748   using string_to_sign_t = VersionAbstractor::string_to_sign_t;
749   using signature_factory_t = VersionAbstractor::signature_factory_t;
750   using completer_factory_t = VersionAbstractor::completer_factory_t;
751
752   /* TODO(rzarzynski): clean up. We've too many input parameter hee. Also
753    * the signature get_auth_data() of VersionAbstractor is too complicated.
754    * Replace these thing with a simple, dedicated structure. */
755   virtual result_t authenticate(const boost::string_view& access_key_id,
756                                 const boost::string_view& signature,
757                                 const string_to_sign_t& string_to_sign,
758                                 const signature_factory_t& signature_factory,
759                                 const completer_factory_t& completer_factory,
760                                 const req_state* s) const = 0;
761
762 public:
763   result_t authenticate(const req_state* const s) const final;
764 };
765
766
767 class AWSGeneralAbstractor : public AWSEngine::VersionAbstractor {
768   CephContext* const cct;
769
770   bool is_time_skew_ok(const utime_t& header_time,
771                        const bool qsr) const;
772
773   virtual boost::optional<std::string>
774   get_v4_canonical_headers(const req_info& info,
775                            const boost::string_view& signedheaders,
776                            const bool using_qs) const;
777
778   auth_data_t get_auth_data_v2(const req_state* s) const;
779   auth_data_t get_auth_data_v4(const req_state* s, bool using_qs) const;
780
781 public:
782   AWSGeneralAbstractor(CephContext* const cct)
783     : cct(cct) {
784   }
785
786   auth_data_t get_auth_data(const req_state* s) const override;
787 };
788
789 class AWSGeneralBoto2Abstractor : public AWSGeneralAbstractor {
790   boost::optional<std::string>
791   get_v4_canonical_headers(const req_info& info,
792                            const boost::string_view& signedheaders,
793                            const bool using_qs) const override;
794
795 public:
796   using AWSGeneralAbstractor::AWSGeneralAbstractor;
797 };
798
799 class AWSBrowserUploadAbstractor : public AWSEngine::VersionAbstractor {
800   static std::string to_string(ceph::bufferlist bl) {
801     return std::string(bl.c_str(),
802                        static_cast<std::string::size_type>(bl.length()));
803   }
804
805   auth_data_t get_auth_data_v2(const req_state* s) const;
806   auth_data_t get_auth_data_v4(const req_state* s) const;
807
808 public:
809   AWSBrowserUploadAbstractor(CephContext*) {
810   }
811
812   auth_data_t get_auth_data(const req_state* s) const override;
813 };
814
815
816 class LDAPEngine : public AWSEngine {
817   static rgw::LDAPHelper* ldh;
818   static std::mutex mtx;
819
820   static void init(CephContext* const cct);
821
822   using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
823   using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
824   using result_t = rgw::auth::Engine::result_t;
825
826 protected:
827   RGWRados* const store;
828   const rgw::auth::RemoteApplier::Factory* const apl_factory;
829
830   acl_strategy_t get_acl_strategy() const;
831   auth_info_t get_creds_info(const rgw::RGWToken& token) const noexcept;
832
833   result_t authenticate(const boost::string_view& access_key_id,
834                         const boost::string_view& signature,
835                         const string_to_sign_t& string_to_sign,
836                         const signature_factory_t&,
837                         const completer_factory_t& completer_factory,
838                         const req_state* s) const override;
839 public:
840   LDAPEngine(CephContext* const cct,
841              RGWRados* const store,
842              const VersionAbstractor& ver_abstractor,
843              const rgw::auth::RemoteApplier::Factory* const apl_factory)
844     : AWSEngine(cct, ver_abstractor),
845       store(store),
846       apl_factory(apl_factory) {
847     init(cct);
848   }
849
850   using AWSEngine::authenticate;
851
852   const char* get_name() const noexcept override {
853     return "rgw::auth::s3::LDAPEngine";
854   }
855 };
856
857
858 class LocalEngine : public AWSEngine {
859   RGWRados* const store;
860   const rgw::auth::LocalApplier::Factory* const apl_factory;
861
862   result_t authenticate(const boost::string_view& access_key_id,
863                         const boost::string_view& signature,
864                         const string_to_sign_t& string_to_sign,
865                         const signature_factory_t& signature_factory,
866                         const completer_factory_t& completer_factory,
867                         const req_state* s) const override;
868 public:
869   LocalEngine(CephContext* const cct,
870               RGWRados* const store,
871               const VersionAbstractor& ver_abstractor,
872               const rgw::auth::LocalApplier::Factory* const apl_factory)
873     : AWSEngine(cct, ver_abstractor),
874       store(store),
875       apl_factory(apl_factory) {
876   }
877
878   using AWSEngine::authenticate;
879
880   const char* get_name() const noexcept override {
881     return "rgw::auth::s3::LocalEngine";
882   }
883 };
884
885
886 class S3AnonymousEngine : public rgw::auth::AnonymousEngine {
887   bool is_applicable(const req_state* s) const noexcept override;
888
889 public:
890   /* Let's reuse the parent class' constructor. */
891   using rgw::auth::AnonymousEngine::AnonymousEngine;
892
893   const char* get_name() const noexcept override {
894     return "rgw::auth::s3::S3AnonymousEngine";
895   }
896 };
897
898
899 class S3AuthFactory : public rgw::auth::RemoteApplier::Factory,
900                       public rgw::auth::LocalApplier::Factory {
901   typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t;
902   RGWRados* const store;
903
904 public:
905   S3AuthFactory(RGWRados* const store)
906     : store(store) {
907   }
908
909   aplptr_t create_apl_remote(CephContext* const cct,
910                              const req_state* const s,
911                              rgw::auth::RemoteApplier::acl_strategy_t&& acl_alg,
912                              const rgw::auth::RemoteApplier::AuthInfo info
913                             ) const override {
914     return aplptr_t(
915       new rgw::auth::RemoteApplier(cct, store, std::move(acl_alg), info,
916                                    cct->_conf->rgw_keystone_implicit_tenants));
917   }
918
919   aplptr_t create_apl_local(CephContext* const cct,
920                             const req_state* const s,
921                             const RGWUserInfo& user_info,
922                             const std::string& subuser) const override {
923       return aplptr_t(
924         new rgw::auth::LocalApplier(cct, user_info, subuser));
925   }
926 };
927
928
929 } /* namespace s3 */
930 } /* namespace auth */
931 } /* namespace rgw */
932
933
934 #endif /* CEPH_RGW_REST_S3_H */