]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_s3.h
update sources to v12.1.1
[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 #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 private:
474 static int authorize_v2(RGWRados *store,
475 const rgw::auth::StrategyRegistry& auth_registry,
476 struct req_state *s);
477 public:
478 static int authorize(RGWRados *store,
479 const rgw::auth::StrategyRegistry& auth_registry,
480 struct req_state *s);
481 };
482
483 class RGWHandler_Auth_S3 : public RGWHandler_REST {
484 friend class RGWRESTMgr_S3;
485
486 const rgw::auth::StrategyRegistry& auth_registry;
487
488 public:
489 RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry& auth_registry)
490 : RGWHandler_REST(),
491 auth_registry(auth_registry) {
492 }
493 ~RGWHandler_Auth_S3() override = default;
494
495 static int validate_bucket_name(const string& bucket);
496 static int validate_object_name(const string& bucket);
497
498 int init(RGWRados *store,
499 struct req_state *s,
500 rgw::io::BasicClient *cio) override;
501 int authorize() override {
502 return RGW_Auth_S3::authorize(store, auth_registry, s);
503 }
504 int postauth_init() override { return 0; }
505 };
506
507 class RGWHandler_REST_S3 : public RGWHandler_REST {
508 friend class RGWRESTMgr_S3;
509
510 const rgw::auth::StrategyRegistry& auth_registry;
511 public:
512 static int init_from_header(struct req_state *s, int default_formatter, bool configurable_format);
513
514 RGWHandler_REST_S3(const rgw::auth::StrategyRegistry& auth_registry)
515 : RGWHandler_REST(),
516 auth_registry(auth_registry) {
517 }
518 ~RGWHandler_REST_S3() override = default;
519
520 int init(RGWRados *store,
521 struct req_state *s,
522 rgw::io::BasicClient *cio) override;
523 int authorize() override {
524 return RGW_Auth_S3::authorize(store, auth_registry, s);
525 }
526 int postauth_init() override;
527 };
528
529 class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
530 protected:
531 bool is_usage_op() {
532 return s->info.args.exists("usage");
533 }
534 RGWOp *op_get() override;
535 RGWOp *op_head() override;
536 RGWOp *op_post() override;
537 public:
538 using RGWHandler_REST_S3::RGWHandler_REST_S3;
539 ~RGWHandler_REST_Service_S3() override = default;
540 };
541
542 class RGWHandler_REST_Bucket_S3 : public RGWHandler_REST_S3 {
543 protected:
544 bool is_acl_op() {
545 return s->info.args.exists("acl");
546 }
547 bool is_cors_op() {
548 return s->info.args.exists("cors");
549 }
550 bool is_lc_op() {
551 return s->info.args.exists("lifecycle");
552 }
553 bool is_obj_update_op() override {
554 return is_acl_op() || is_cors_op();
555 }
556 bool is_request_payment_op() {
557 return s->info.args.exists("requestPayment");
558 }
559 bool is_policy_op() {
560 return s->info.args.exists("policy");
561 }
562 RGWOp *get_obj_op(bool get_data);
563
564 RGWOp *op_get() override;
565 RGWOp *op_head() override;
566 RGWOp *op_put() override;
567 RGWOp *op_delete() override;
568 RGWOp *op_post() override;
569 RGWOp *op_options() override;
570 public:
571 using RGWHandler_REST_S3::RGWHandler_REST_S3;
572 ~RGWHandler_REST_Bucket_S3() override = default;
573 };
574
575 class RGWHandler_REST_Obj_S3 : public RGWHandler_REST_S3 {
576 protected:
577 bool is_acl_op() {
578 return s->info.args.exists("acl");
579 }
580 bool is_cors_op() {
581 return s->info.args.exists("cors");
582 }
583 bool is_tagging_op() {
584 return s->info.args.exists("tagging");
585 }
586 bool is_obj_update_op() override {
587 return is_acl_op() || is_tagging_op() ;
588 }
589 RGWOp *get_obj_op(bool get_data);
590
591 RGWOp *op_get() override;
592 RGWOp *op_head() override;
593 RGWOp *op_put() override;
594 RGWOp *op_delete() override;
595 RGWOp *op_post() override;
596 RGWOp *op_options() override;
597 public:
598 using RGWHandler_REST_S3::RGWHandler_REST_S3;
599 ~RGWHandler_REST_Obj_S3() override = default;
600 };
601
602 class RGWRESTMgr_S3 : public RGWRESTMgr {
603 private:
604 bool enable_s3website;
605 public:
606 explicit RGWRESTMgr_S3(bool enable_s3website = false)
607 : enable_s3website(enable_s3website) {
608 }
609
610 ~RGWRESTMgr_S3() override = default;
611
612 RGWHandler_REST *get_handler(struct req_state* s,
613 const rgw::auth::StrategyRegistry& auth_registry,
614 const std::string& frontend_prefix) override;
615 };
616
617 class RGWHandler_REST_Obj_S3Website;
618
619 static inline bool looks_like_ip_address(const char *bucket)
620 {
621 int num_periods = 0;
622 bool expect_period = false;
623 for (const char *b = bucket; *b; ++b) {
624 if (*b == '.') {
625 if (!expect_period)
626 return false;
627 ++num_periods;
628 if (num_periods > 3)
629 return false;
630 expect_period = false;
631 }
632 else if (isdigit(*b)) {
633 expect_period = true;
634 }
635 else {
636 return false;
637 }
638 }
639 return (num_periods == 3);
640 }
641
642 static inline int valid_s3_object_name(const string& name) {
643 if (name.size() > 1024) {
644 return -ERR_INVALID_OBJECT_NAME;
645 }
646 if (check_utf8(name.c_str(), name.size())) {
647 return -ERR_INVALID_OBJECT_NAME;
648 }
649 return 0;
650 }
651
652 static inline int valid_s3_bucket_name(const string& name, bool relaxed=false)
653 {
654 // This function enforces Amazon's spec for bucket names.
655 // (The requirements, not the recommendations.)
656 int len = name.size();
657 if (len < 3) {
658 // Name too short
659 return -ERR_INVALID_BUCKET_NAME;
660 } else if (len > 255) {
661 // Name too long
662 return -ERR_INVALID_BUCKET_NAME;
663 }
664
665 // bucket names must start with a number, letter, or underscore
666 if (!(isalpha(name[0]) || isdigit(name[0]))) {
667 if (!relaxed)
668 return -ERR_INVALID_BUCKET_NAME;
669 else if (!(name[0] == '_' || name[0] == '.' || name[0] == '-'))
670 return -ERR_INVALID_BUCKET_NAME;
671 }
672
673 for (const char *s = name.c_str(); *s; ++s) {
674 char c = *s;
675 if (isdigit(c) || (c == '.'))
676 continue;
677 if (isalpha(c))
678 continue;
679 if ((c == '-') || (c == '_'))
680 continue;
681 // Invalid character
682 return -ERR_INVALID_BUCKET_NAME;
683 }
684
685 if (looks_like_ip_address(name.c_str()))
686 return -ERR_INVALID_BUCKET_NAME;
687
688 return 0;
689 }
690
691
692 namespace rgw {
693 namespace auth {
694 namespace s3 {
695
696 class AWSEngine : public rgw::auth::Engine {
697 public:
698 class VersionAbstractor {
699 static constexpr size_t DIGEST_SIZE_V2 = CEPH_CRYPTO_HMACSHA1_DIGESTSIZE;
700 static constexpr size_t DIGEST_SIZE_V4 = CEPH_CRYPTO_HMACSHA256_DIGESTSIZE;
701
702 /* Knowing the signature max size allows us to employ the sstring, and thus
703 * avoid dynamic allocations. The multiplier comes from representing digest
704 * in the base64-encoded form. */
705 static constexpr size_t SIGNATURE_MAX_SIZE = \
706 ceph::max(DIGEST_SIZE_V2, DIGEST_SIZE_V4) * 2 + sizeof('\0');
707
708 public:
709 virtual ~VersionAbstractor() {};
710
711 using access_key_id_t = boost::string_view;
712 using client_signature_t = boost::string_view;
713 using server_signature_t = basic_sstring<char, uint16_t, SIGNATURE_MAX_SIZE>;
714 using string_to_sign_t = std::string;
715
716 /* Transformation for crafting the AWS signature at server side which is
717 * used later to compare with the user-provided one. The methodology for
718 * doing that depends on AWS auth version. */
719 using signature_factory_t = \
720 std::function<server_signature_t(CephContext* cct,
721 const std::string& secret_key,
722 const string_to_sign_t& string_to_sign)>;
723
724 /* Return an instance of Completer for verifying the payload's fingerprint
725 * if necessary. Otherwise caller gets nullptr. Caller may provide secret
726 * key */
727 using completer_factory_t = \
728 std::function<rgw::auth::Completer::cmplptr_t(
729 const boost::optional<std::string>& secret_key)>;
730
731 struct auth_data_t {
732 access_key_id_t access_key_id;
733 client_signature_t client_signature;
734 string_to_sign_t string_to_sign;
735 signature_factory_t signature_factory;
736 completer_factory_t completer_factory;
737 };
738
739 virtual auth_data_t get_auth_data(const req_state* s) const = 0;
740 };
741
742 protected:
743 CephContext* cct;
744 const VersionAbstractor& ver_abstractor;
745
746 AWSEngine(CephContext* const cct, const VersionAbstractor& ver_abstractor)
747 : cct(cct),
748 ver_abstractor(ver_abstractor) {
749 }
750
751 using result_t = rgw::auth::Engine::result_t;
752 using string_to_sign_t = VersionAbstractor::string_to_sign_t;
753 using signature_factory_t = VersionAbstractor::signature_factory_t;
754 using completer_factory_t = VersionAbstractor::completer_factory_t;
755
756 /* TODO(rzarzynski): clean up. We've too many input parameter hee. Also
757 * the signature get_auth_data() of VersionAbstractor is too complicated.
758 * Replace these thing with a simple, dedicated structure. */
759 virtual result_t authenticate(const boost::string_view& access_key_id,
760 const boost::string_view& signature,
761 const string_to_sign_t& string_to_sign,
762 const signature_factory_t& signature_factory,
763 const completer_factory_t& completer_factory,
764 const req_state* s) const = 0;
765
766 public:
767 result_t authenticate(const req_state* const s) const final;
768 };
769
770
771 class AWSGeneralAbstractor : public AWSEngine::VersionAbstractor {
772 CephContext* const cct;
773
774 bool is_time_skew_ok(const utime_t& header_time,
775 const bool qsr) const;
776
777 virtual boost::optional<std::string>
778 get_v4_canonical_headers(const req_info& info,
779 const boost::string_view& signedheaders,
780 const bool using_qs) const;
781
782 auth_data_t get_auth_data_v2(const req_state* s) const;
783 auth_data_t get_auth_data_v4(const req_state* s, bool using_qs) const;
784
785 public:
786 AWSGeneralAbstractor(CephContext* const cct)
787 : cct(cct) {
788 }
789
790 auth_data_t get_auth_data(const req_state* s) const override;
791 };
792
793 class AWSGeneralBoto2Abstractor : public AWSGeneralAbstractor {
794 boost::optional<std::string>
795 get_v4_canonical_headers(const req_info& info,
796 const boost::string_view& signedheaders,
797 const bool using_qs) const override;
798
799 public:
800 using AWSGeneralAbstractor::AWSGeneralAbstractor;
801 };
802
803 class AWSBrowserUploadAbstractor : public AWSEngine::VersionAbstractor {
804 static std::string to_string(ceph::bufferlist bl) {
805 return std::string(bl.c_str(),
806 static_cast<std::string::size_type>(bl.length()));
807 }
808
809 auth_data_t get_auth_data_v2(const req_state* s) const;
810 auth_data_t get_auth_data_v4(const req_state* s) const;
811
812 public:
813 AWSBrowserUploadAbstractor(CephContext*) {
814 }
815
816 auth_data_t get_auth_data(const req_state* s) const override;
817 };
818
819
820 class LDAPEngine : public AWSEngine {
821 static rgw::LDAPHelper* ldh;
822 static std::mutex mtx;
823
824 static void init(CephContext* const cct);
825
826 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
827 using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
828 using result_t = rgw::auth::Engine::result_t;
829
830 protected:
831 RGWRados* const store;
832 const rgw::auth::RemoteApplier::Factory* const apl_factory;
833
834 acl_strategy_t get_acl_strategy() const;
835 auth_info_t get_creds_info(const rgw::RGWToken& token) const noexcept;
836
837 result_t authenticate(const boost::string_view& access_key_id,
838 const boost::string_view& signature,
839 const string_to_sign_t& string_to_sign,
840 const signature_factory_t&,
841 const completer_factory_t& completer_factory,
842 const req_state* s) const override;
843 public:
844 LDAPEngine(CephContext* const cct,
845 RGWRados* const store,
846 const VersionAbstractor& ver_abstractor,
847 const rgw::auth::RemoteApplier::Factory* const apl_factory)
848 : AWSEngine(cct, ver_abstractor),
849 store(store),
850 apl_factory(apl_factory) {
851 init(cct);
852 }
853
854 using AWSEngine::authenticate;
855
856 const char* get_name() const noexcept override {
857 return "rgw::auth::s3::LDAPEngine";
858 }
859 };
860
861
862 class LocalEngine : public AWSEngine {
863 RGWRados* const store;
864 const rgw::auth::LocalApplier::Factory* const apl_factory;
865
866 result_t authenticate(const boost::string_view& access_key_id,
867 const boost::string_view& signature,
868 const string_to_sign_t& string_to_sign,
869 const signature_factory_t& signature_factory,
870 const completer_factory_t& completer_factory,
871 const req_state* s) const override;
872 public:
873 LocalEngine(CephContext* const cct,
874 RGWRados* const store,
875 const VersionAbstractor& ver_abstractor,
876 const rgw::auth::LocalApplier::Factory* const apl_factory)
877 : AWSEngine(cct, ver_abstractor),
878 store(store),
879 apl_factory(apl_factory) {
880 }
881
882 using AWSEngine::authenticate;
883
884 const char* get_name() const noexcept override {
885 return "rgw::auth::s3::LocalEngine";
886 }
887 };
888
889
890 class S3AuthFactory : public rgw::auth::RemoteApplier::Factory,
891 public rgw::auth::LocalApplier::Factory {
892 typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t;
893 RGWRados* const store;
894
895 public:
896 S3AuthFactory(RGWRados* const store)
897 : store(store) {
898 }
899
900 aplptr_t create_apl_remote(CephContext* const cct,
901 const req_state* const s,
902 rgw::auth::RemoteApplier::acl_strategy_t&& acl_alg,
903 const rgw::auth::RemoteApplier::AuthInfo info
904 ) const override {
905 return aplptr_t(
906 new rgw::auth::RemoteApplier(cct, store, std::move(acl_alg), info,
907 cct->_conf->rgw_keystone_implicit_tenants));
908 }
909
910 aplptr_t create_apl_local(CephContext* const cct,
911 const req_state* const s,
912 const RGWUserInfo& user_info,
913 const std::string& subuser) const override {
914 return aplptr_t(
915 new rgw::auth::LocalApplier(cct, user_info, subuser));
916 }
917 };
918
919
920 } /* namespace s3 */
921 } /* namespace auth */
922 } /* namespace rgw */
923
924
925 #endif /* CEPH_RGW_REST_S3_H */