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