]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_rest_s3.h
update sources to v12.1.1
[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 {
473private:
474 static int authorize_v2(RGWRados *store,
475 const rgw::auth::StrategyRegistry& auth_registry,
476 struct req_state *s);
7c673cae
FG
477public:
478 static int authorize(RGWRados *store,
479 const rgw::auth::StrategyRegistry& auth_registry,
480 struct req_state *s);
7c673cae
FG
481};
482
483class RGWHandler_Auth_S3 : public RGWHandler_REST {
484 friend class RGWRESTMgr_S3;
485
486 const rgw::auth::StrategyRegistry& auth_registry;
487
488public:
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
507class RGWHandler_REST_S3 : public RGWHandler_REST {
508 friend class RGWRESTMgr_S3;
509
510 const rgw::auth::StrategyRegistry& auth_registry;
511public:
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
529class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
530protected:
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;
537public:
538 using RGWHandler_REST_S3::RGWHandler_REST_S3;
539 ~RGWHandler_REST_Service_S3() override = default;
540};
541
542class RGWHandler_REST_Bucket_S3 : public RGWHandler_REST_S3 {
543protected:
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 }
31f18b77
FG
559 bool is_policy_op() {
560 return s->info.args.exists("policy");
561 }
7c673cae
FG
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;
570public:
571 using RGWHandler_REST_S3::RGWHandler_REST_S3;
572 ~RGWHandler_REST_Bucket_S3() override = default;
573};
574
575class RGWHandler_REST_Obj_S3 : public RGWHandler_REST_S3 {
576protected:
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 }
224ce89b
WB
583 bool is_tagging_op() {
584 return s->info.args.exists("tagging");
585 }
7c673cae 586 bool is_obj_update_op() override {
224ce89b 587 return is_acl_op() || is_tagging_op() ;
7c673cae
FG
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;
597public:
598 using RGWHandler_REST_S3::RGWHandler_REST_S3;
599 ~RGWHandler_REST_Obj_S3() override = default;
600};
601
602class RGWRESTMgr_S3 : public RGWRESTMgr {
603private:
604 bool enable_s3website;
605public:
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
617class RGWHandler_REST_Obj_S3Website;
618
619static 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
642static 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
652static 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
692namespace rgw {
693namespace auth {
694namespace s3 {
695
31f18b77 696class AWSEngine : public rgw::auth::Engine {
7c673cae 697public:
31f18b77
FG
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
7c673cae 708 public:
31f18b77 709 virtual ~VersionAbstractor() {};
7c673cae 710
31f18b77
FG
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>;
7c673cae
FG
714 using string_to_sign_t = std::string;
715
31f18b77
FG
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
224ce89b
WB
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;
7c673cae
FG
740 };
741
742protected:
743 CephContext* cct;
31f18b77 744 const VersionAbstractor& ver_abstractor;
7c673cae 745
31f18b77 746 AWSEngine(CephContext* const cct, const VersionAbstractor& ver_abstractor)
7c673cae 747 : cct(cct),
31f18b77 748 ver_abstractor(ver_abstractor) {
7c673cae
FG
749 }
750
751 using result_t = rgw::auth::Engine::result_t;
31f18b77
FG
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,
7c673cae
FG
764 const req_state* s) const = 0;
765
766public:
31f18b77 767 result_t authenticate(const req_state* const s) const final;
7c673cae
FG
768};
769
31f18b77
FG
770
771class AWSGeneralAbstractor : public AWSEngine::VersionAbstractor {
7c673cae
FG
772 CephContext* const cct;
773
774 bool is_time_skew_ok(const utime_t& header_time,
775 const bool qsr) const;
776
31f18b77
FG
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
224ce89b
WB
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;
31f18b77 784
7c673cae 785public:
31f18b77 786 AWSGeneralAbstractor(CephContext* const cct)
7c673cae
FG
787 : cct(cct) {
788 }
789
224ce89b 790 auth_data_t get_auth_data(const req_state* s) const override;
7c673cae
FG
791};
792
31f18b77
FG
793class 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
799public:
800 using AWSGeneralAbstractor::AWSGeneralAbstractor;
801};
7c673cae 802
31f18b77 803class AWSBrowserUploadAbstractor : public AWSEngine::VersionAbstractor {
7c673cae
FG
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
31f18b77
FG
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
7c673cae 812public:
31f18b77 813 AWSBrowserUploadAbstractor(CephContext*) {
7c673cae
FG
814 }
815
224ce89b 816 auth_data_t get_auth_data(const req_state* s) const override;
7c673cae
FG
817};
818
819
31f18b77 820class LDAPEngine : public AWSEngine {
7c673cae
FG
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
830protected:
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
31f18b77
FG
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,
7c673cae
FG
842 const req_state* s) const override;
843public:
844 LDAPEngine(CephContext* const cct,
845 RGWRados* const store,
31f18b77 846 const VersionAbstractor& ver_abstractor,
7c673cae 847 const rgw::auth::RemoteApplier::Factory* const apl_factory)
31f18b77 848 : AWSEngine(cct, ver_abstractor),
7c673cae
FG
849 store(store),
850 apl_factory(apl_factory) {
851 init(cct);
852 }
853
31f18b77 854 using AWSEngine::authenticate;
7c673cae
FG
855
856 const char* get_name() const noexcept override {
857 return "rgw::auth::s3::LDAPEngine";
858 }
859};
860
861
31f18b77 862class LocalEngine : public AWSEngine {
7c673cae
FG
863 RGWRados* const store;
864 const rgw::auth::LocalApplier::Factory* const apl_factory;
865
31f18b77
FG
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,
7c673cae
FG
871 const req_state* s) const override;
872public:
31f18b77
FG
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),
7c673cae
FG
878 store(store),
879 apl_factory(apl_factory) {
880 }
881
31f18b77 882 using AWSEngine::authenticate;
7c673cae
FG
883
884 const char* get_name() const noexcept override {
31f18b77 885 return "rgw::auth::s3::LocalEngine";
7c673cae
FG
886 }
887};
888
889
890class 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
895public:
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,
224ce89b 907 cct->_conf->rgw_keystone_implicit_tenants));
7c673cae
FG
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 */