]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_rest_s3.h
update sources to v12.1.3
[ceph.git] / ceph / src / rgw / rgw_rest_s3.h
CommitLineData
7c673cae
FG
1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2// vim: ts=8 sw=2 smarttab
3
4#ifndef CEPH_RGW_REST_S3_H
5
6#define CEPH_RGW_REST_S3_H
7#define TIME_BUF_SIZE 128
8
9#include <mutex>
10
31f18b77
FG
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"
7c673cae
FG
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
31f18b77
FG
35struct rgw_http_error {
36 int http_ret;
37 const char *s3_code;
38};
39
40void rgw_get_errno_s3(struct rgw_http_error *e, int err_no);
7c673cae
FG
41
42class RGWGetObj_ObjStore_S3 : public RGWGetObj_ObjStore
43{
44protected:
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;
49public:
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
224ce89b
WB
62class RGWGetObjTags_ObjStore_S3 : public RGWGetObjTags_ObjStore
63{
64 bufferlist tags_bl;
65public:
66 RGWGetObjTags_ObjStore_S3() {}
67 ~RGWGetObjTags_ObjStore_S3() {}
68
69 void send_response_data(bufferlist &bl) override;
70};
71
72class RGWPutObjTags_ObjStore_S3 : public RGWPutObjTags_ObjStore
73{
74public:
75 RGWPutObjTags_ObjStore_S3() {}
76 ~RGWPutObjTags_ObjStore_S3() {}
77
78 int get_params() override;
79 void send_response() override;
80};
81
82class RGWDeleteObjTags_ObjStore_S3 : public RGWDeleteObjTags
83{
84public:
85 ~RGWDeleteObjTags_ObjStore_S3() override {}
86 void send_response() override;
87};
88
7c673cae
FG
89class RGWListBuckets_ObjStore_S3 : public RGWListBuckets_ObjStore {
90public:
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
103class RGWGetUsage_ObjStore_S3 : public RGWGetUsage_ObjStore {
104public:
105 RGWGetUsage_ObjStore_S3() {}
106 ~RGWGetUsage_ObjStore_S3() override {}
107
108 int get_params() override ;
109 void send_response() override;
110};
111
112class RGWListBucket_ObjStore_S3 : public RGWListBucket_ObjStore {
113 bool objs_container;
114public:
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
125class RGWGetBucketLogging_ObjStore_S3 : public RGWGetBucketLogging {
126public:
127 RGWGetBucketLogging_ObjStore_S3() {}
128 ~RGWGetBucketLogging_ObjStore_S3() override {}
129
130 void send_response() override;
131};
132
133class RGWGetBucketLocation_ObjStore_S3 : public RGWGetBucketLocation {
134public:
135 RGWGetBucketLocation_ObjStore_S3() {}
136 ~RGWGetBucketLocation_ObjStore_S3() override {}
137
138 void send_response() override;
139};
140
141class RGWGetBucketVersioning_ObjStore_S3 : public RGWGetBucketVersioning {
142public:
143 RGWGetBucketVersioning_ObjStore_S3() {}
144 ~RGWGetBucketVersioning_ObjStore_S3() override {}
145
146 void send_response() override;
147};
148
149class RGWSetBucketVersioning_ObjStore_S3 : public RGWSetBucketVersioning {
150public:
151 RGWSetBucketVersioning_ObjStore_S3() {}
152 ~RGWSetBucketVersioning_ObjStore_S3() override {}
153
154 int get_params() override;
155 void send_response() override;
156};
157
158class RGWGetBucketWebsite_ObjStore_S3 : public RGWGetBucketWebsite {
159public:
160 RGWGetBucketWebsite_ObjStore_S3() {}
161 ~RGWGetBucketWebsite_ObjStore_S3() override {}
162
163 void send_response() override;
164};
165
166class RGWSetBucketWebsite_ObjStore_S3 : public RGWSetBucketWebsite {
167public:
168 RGWSetBucketWebsite_ObjStore_S3() {}
169 ~RGWSetBucketWebsite_ObjStore_S3() override {}
170
171 int get_params() override;
172 void send_response() override;
173};
174
175class RGWDeleteBucketWebsite_ObjStore_S3 : public RGWDeleteBucketWebsite {
176public:
177 RGWDeleteBucketWebsite_ObjStore_S3() {}
178 ~RGWDeleteBucketWebsite_ObjStore_S3() override {}
179
180 void send_response() override;
181};
182
183class RGWStatBucket_ObjStore_S3 : public RGWStatBucket_ObjStore {
184public:
185 RGWStatBucket_ObjStore_S3() {}
186 ~RGWStatBucket_ObjStore_S3() override {}
187
188 void send_response() override;
189};
190
191class RGWCreateBucket_ObjStore_S3 : public RGWCreateBucket_ObjStore {
192public:
193 RGWCreateBucket_ObjStore_S3() {}
194 ~RGWCreateBucket_ObjStore_S3() override {}
195
196 int get_params() override;
197 void send_response() override;
198};
199
200class RGWDeleteBucket_ObjStore_S3 : public RGWDeleteBucket_ObjStore {
201public:
202 RGWDeleteBucket_ObjStore_S3() {}
203 ~RGWDeleteBucket_ObjStore_S3() override {}
204
205 void send_response() override;
206};
207
208class RGWPutObj_ObjStore_S3 : public RGWPutObj_ObjStore {
209private:
210 std::map<std::string, std::string> crypt_http_responses;
211
212public:
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
7c673cae
FG
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
228class 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();
224ce89b 239 int get_tags();
7c673cae
FG
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
245public:
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
263class RGWDeleteObj_ObjStore_S3 : public RGWDeleteObj_ObjStore {
264public:
265 RGWDeleteObj_ObjStore_S3() {}
266 ~RGWDeleteObj_ObjStore_S3() override {}
267
268 int get_params() override;
269 void send_response() override;
270};
271
272class RGWCopyObj_ObjStore_S3 : public RGWCopyObj_ObjStore {
273 bool sent_header;
274public:
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
284class RGWGetACLs_ObjStore_S3 : public RGWGetACLs_ObjStore {
285public:
286 RGWGetACLs_ObjStore_S3() {}
287 ~RGWGetACLs_ObjStore_S3() override {}
288
289 void send_response() override;
290};
291
292class RGWPutACLs_ObjStore_S3 : public RGWPutACLs_ObjStore {
293public:
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
302class RGWGetLC_ObjStore_S3 : public RGWGetLC_ObjStore {
303protected:
304 RGWLifecycleConfiguration_S3 config;
305public:
306 RGWGetLC_ObjStore_S3() {}
307 ~RGWGetLC_ObjStore_S3() override {}
308 void execute() override;
309
310 void send_response() override;
311};
312
313class RGWPutLC_ObjStore_S3 : public RGWPutLC_ObjStore {
314public:
315 RGWPutLC_ObjStore_S3() {}
316 ~RGWPutLC_ObjStore_S3() override {}
317
318 void send_response() override;
319};
320
321class RGWDeleteLC_ObjStore_S3 : public RGWDeleteLC_ObjStore {
322public:
323 RGWDeleteLC_ObjStore_S3() {}
324 ~RGWDeleteLC_ObjStore_S3() override {}
325
326 void send_response() override;
327};
328
329class RGWGetCORS_ObjStore_S3 : public RGWGetCORS_ObjStore {
330public:
331 RGWGetCORS_ObjStore_S3() {}
332 ~RGWGetCORS_ObjStore_S3() override {}
333
334 void send_response() override;
335};
336
337class RGWPutCORS_ObjStore_S3 : public RGWPutCORS_ObjStore {
338public:
339 RGWPutCORS_ObjStore_S3() {}
340 ~RGWPutCORS_ObjStore_S3() override {}
341
342 int get_params() override;
343 void send_response() override;
344};
345
346class RGWDeleteCORS_ObjStore_S3 : public RGWDeleteCORS_ObjStore {
347public:
348 RGWDeleteCORS_ObjStore_S3() {}
349 ~RGWDeleteCORS_ObjStore_S3() override {}
350
351 void send_response() override;
352};
353
354class RGWOptionsCORS_ObjStore_S3 : public RGWOptionsCORS_ObjStore {
355public:
356 RGWOptionsCORS_ObjStore_S3() {}
357 ~RGWOptionsCORS_ObjStore_S3() override {}
358
359 void send_response() override;
360};
361
362class RGWGetRequestPayment_ObjStore_S3 : public RGWGetRequestPayment {
363public:
364 RGWGetRequestPayment_ObjStore_S3() {}
365 ~RGWGetRequestPayment_ObjStore_S3() override {}
366
367 void send_response() override;
368};
369
370class RGWSetRequestPayment_ObjStore_S3 : public RGWSetRequestPayment {
371public:
372 RGWSetRequestPayment_ObjStore_S3() {}
373 ~RGWSetRequestPayment_ObjStore_S3() override {}
374
375 int get_params() override;
376 void send_response() override;
377};
378
379class RGWInitMultipart_ObjStore_S3 : public RGWInitMultipart_ObjStore {
380private:
381 std::map<std::string, std::string> crypt_http_responses;
382public:
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
391class RGWCompleteMultipart_ObjStore_S3 : public RGWCompleteMultipart_ObjStore {
392public:
393 RGWCompleteMultipart_ObjStore_S3() {}
394 ~RGWCompleteMultipart_ObjStore_S3() override {}
395
396 int get_params() override;
397 void send_response() override;
398};
399
400class RGWAbortMultipart_ObjStore_S3 : public RGWAbortMultipart_ObjStore {
401public:
402 RGWAbortMultipart_ObjStore_S3() {}
403 ~RGWAbortMultipart_ObjStore_S3() override {}
404
405 void send_response() override;
406};
407
408class RGWListMultipart_ObjStore_S3 : public RGWListMultipart_ObjStore {
409public:
410 RGWListMultipart_ObjStore_S3() {}
411 ~RGWListMultipart_ObjStore_S3() override {}
412
413 void send_response() override;
414};
415
416class RGWListBucketMultiparts_ObjStore_S3 : public RGWListBucketMultiparts_ObjStore {
417public:
418 RGWListBucketMultiparts_ObjStore_S3() {
419 default_max = 1000;
420 }
421 ~RGWListBucketMultiparts_ObjStore_S3() override {}
422
423 void send_response() override;
424};
425
426class RGWDeleteMultiObj_ObjStore_S3 : public RGWDeleteMultiObj_ObjStore {
427public:
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
439class RGWGetObjLayout_ObjStore_S3 : public RGWGetObjLayout {
440public:
441 RGWGetObjLayout_ObjStore_S3() {}
442 ~RGWGetObjLayout_ObjStore_S3() {}
443
444 void send_response();
445};
446
31f18b77
FG
447class RGWConfigBucketMetaSearch_ObjStore_S3 : public RGWConfigBucketMetaSearch {
448public:
449 RGWConfigBucketMetaSearch_ObjStore_S3() {}
450 ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
451
452 int get_params() override;
453 void send_response() override;
454};
455
456class RGWGetBucketMetaSearch_ObjStore_S3 : public RGWGetBucketMetaSearch {
457public:
458 RGWGetBucketMetaSearch_ObjStore_S3() {}
459 ~RGWGetBucketMetaSearch_ObjStore_S3() {}
460
461 void send_response() override;
462};
463
464class RGWDelBucketMetaSearch_ObjStore_S3 : public RGWDelBucketMetaSearch {
465public:
466 RGWDelBucketMetaSearch_ObjStore_S3() {}
467 ~RGWDelBucketMetaSearch_ObjStore_S3() {}
468
469 void send_response() override;
470};
7c673cae
FG
471
472class RGW_Auth_S3 {
7c673cae
FG
473public:
474 static int authorize(RGWRados *store,
475 const rgw::auth::StrategyRegistry& auth_registry,
476 struct req_state *s);
7c673cae
FG
477};
478
479class RGWHandler_Auth_S3 : public RGWHandler_REST {
480 friend class RGWRESTMgr_S3;
481
482 const rgw::auth::StrategyRegistry& auth_registry;
483
484public:
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
503class RGWHandler_REST_S3 : public RGWHandler_REST {
504 friend class RGWRESTMgr_S3;
505
506 const rgw::auth::StrategyRegistry& auth_registry;
507public:
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
525class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
526protected:
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;
533public:
534 using RGWHandler_REST_S3::RGWHandler_REST_S3;
535 ~RGWHandler_REST_Service_S3() override = default;
536};
537
538class RGWHandler_REST_Bucket_S3 : public RGWHandler_REST_S3 {
539protected:
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 }
31f18b77
FG
555 bool is_policy_op() {
556 return s->info.args.exists("policy");
557 }
7c673cae
FG
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;
566public:
567 using RGWHandler_REST_S3::RGWHandler_REST_S3;
568 ~RGWHandler_REST_Bucket_S3() override = default;
569};
570
571class RGWHandler_REST_Obj_S3 : public RGWHandler_REST_S3 {
572protected:
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 }
224ce89b
WB
579 bool is_tagging_op() {
580 return s->info.args.exists("tagging");
581 }
7c673cae 582 bool is_obj_update_op() override {
224ce89b 583 return is_acl_op() || is_tagging_op() ;
7c673cae
FG
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;
593public:
594 using RGWHandler_REST_S3::RGWHandler_REST_S3;
595 ~RGWHandler_REST_Obj_S3() override = default;
596};
597
598class RGWRESTMgr_S3 : public RGWRESTMgr {
599private:
600 bool enable_s3website;
601public:
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
613class RGWHandler_REST_Obj_S3Website;
614
615static 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
638static 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
648static 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
688namespace rgw {
689namespace auth {
690namespace s3 {
691
31f18b77 692class AWSEngine : public rgw::auth::Engine {
7c673cae 693public:
31f18b77
FG
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
7c673cae 704 public:
31f18b77 705 virtual ~VersionAbstractor() {};
7c673cae 706
31f18b77
FG
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>;
7c673cae
FG
710 using string_to_sign_t = std::string;
711
31f18b77
FG
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
224ce89b
WB
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;
7c673cae
FG
736 };
737
738protected:
739 CephContext* cct;
31f18b77 740 const VersionAbstractor& ver_abstractor;
7c673cae 741
31f18b77 742 AWSEngine(CephContext* const cct, const VersionAbstractor& ver_abstractor)
7c673cae 743 : cct(cct),
31f18b77 744 ver_abstractor(ver_abstractor) {
7c673cae
FG
745 }
746
747 using result_t = rgw::auth::Engine::result_t;
31f18b77
FG
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,
7c673cae
FG
760 const req_state* s) const = 0;
761
762public:
31f18b77 763 result_t authenticate(const req_state* const s) const final;
7c673cae
FG
764};
765
31f18b77
FG
766
767class AWSGeneralAbstractor : public AWSEngine::VersionAbstractor {
7c673cae
FG
768 CephContext* const cct;
769
770 bool is_time_skew_ok(const utime_t& header_time,
771 const bool qsr) const;
772
31f18b77
FG
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
224ce89b
WB
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;
31f18b77 780
7c673cae 781public:
31f18b77 782 AWSGeneralAbstractor(CephContext* const cct)
7c673cae
FG
783 : cct(cct) {
784 }
785
224ce89b 786 auth_data_t get_auth_data(const req_state* s) const override;
7c673cae
FG
787};
788
31f18b77
FG
789class 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
795public:
796 using AWSGeneralAbstractor::AWSGeneralAbstractor;
797};
7c673cae 798
31f18b77 799class AWSBrowserUploadAbstractor : public AWSEngine::VersionAbstractor {
7c673cae
FG
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
31f18b77
FG
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
7c673cae 808public:
31f18b77 809 AWSBrowserUploadAbstractor(CephContext*) {
7c673cae
FG
810 }
811
224ce89b 812 auth_data_t get_auth_data(const req_state* s) const override;
7c673cae
FG
813};
814
815
31f18b77 816class LDAPEngine : public AWSEngine {
7c673cae
FG
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
826protected:
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
31f18b77
FG
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,
7c673cae
FG
838 const req_state* s) const override;
839public:
840 LDAPEngine(CephContext* const cct,
841 RGWRados* const store,
31f18b77 842 const VersionAbstractor& ver_abstractor,
7c673cae 843 const rgw::auth::RemoteApplier::Factory* const apl_factory)
31f18b77 844 : AWSEngine(cct, ver_abstractor),
7c673cae
FG
845 store(store),
846 apl_factory(apl_factory) {
847 init(cct);
848 }
849
31f18b77 850 using AWSEngine::authenticate;
7c673cae
FG
851
852 const char* get_name() const noexcept override {
853 return "rgw::auth::s3::LDAPEngine";
854 }
855};
856
857
31f18b77 858class LocalEngine : public AWSEngine {
7c673cae
FG
859 RGWRados* const store;
860 const rgw::auth::LocalApplier::Factory* const apl_factory;
861
31f18b77
FG
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,
7c673cae
FG
867 const req_state* s) const override;
868public:
31f18b77
FG
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),
7c673cae
FG
874 store(store),
875 apl_factory(apl_factory) {
876 }
877
31f18b77 878 using AWSEngine::authenticate;
7c673cae
FG
879
880 const char* get_name() const noexcept override {
31f18b77 881 return "rgw::auth::s3::LocalEngine";
7c673cae
FG
882 }
883};
884
885
d2e6a577
FG
886class S3AnonymousEngine : public rgw::auth::AnonymousEngine {
887 bool is_applicable(const req_state* s) const noexcept override;
888
889public:
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
7c673cae
FG
899class 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
904public:
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,
224ce89b 916 cct->_conf->rgw_keystone_implicit_tenants));
7c673cae
FG
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 */