1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
6 #define TIME_BUF_SIZE 128
10 #include <boost/utility/string_view.hpp>
11 #include <boost/container/static_vector.hpp>
13 #include "common/sstring.hh"
16 #include "rgw_http_errors.h"
17 #include "rgw_acl_s3.h"
18 #include "rgw_policy_s3.h"
19 #include "rgw_lc_s3.h"
20 #include "rgw_keystone.h"
21 #include "rgw_rest_conn.h"
24 #include "rgw_token.h"
25 #include "include/ceph_assert.h"
28 #include "rgw_auth_filters.h"
31 struct rgw_http_error
{
36 void rgw_get_errno_s3(struct rgw_http_error
*e
, int err_no
);
38 class RGWGetObj_ObjStore_S3
: public RGWGetObj_ObjStore
41 // Serving a custom error page from an object is really a 200 response with
42 // just the status line altered.
43 int custom_http_ret
= 0;
44 std::map
<std::string
, std::string
> crypt_http_responses
;
46 RGWGetObj_ObjStore_S3() {}
47 ~RGWGetObj_ObjStore_S3() override
{}
49 int get_params() override
;
50 int send_response_data_error() override
;
51 int send_response_data(bufferlist
& bl
, off_t ofs
, off_t len
) override
;
52 void set_custom_http_response(int http_ret
) { custom_http_ret
= http_ret
; }
53 int get_decrypt_filter(std::unique_ptr
<RGWGetObj_Filter
>* filter
,
55 bufferlist
* manifest_bl
) override
;
58 class RGWGetObjTags_ObjStore_S3
: public RGWGetObjTags_ObjStore
61 RGWGetObjTags_ObjStore_S3() {}
62 ~RGWGetObjTags_ObjStore_S3() {}
64 void send_response_data(bufferlist
&bl
) override
;
67 class RGWPutObjTags_ObjStore_S3
: public RGWPutObjTags_ObjStore
70 RGWPutObjTags_ObjStore_S3() {}
71 ~RGWPutObjTags_ObjStore_S3() {}
73 int get_params() override
;
74 void send_response() override
;
77 class RGWDeleteObjTags_ObjStore_S3
: public RGWDeleteObjTags
80 ~RGWDeleteObjTags_ObjStore_S3() override
{}
81 void send_response() override
;
84 class RGWGetBucketTags_ObjStore_S3
: public RGWGetBucketTags_ObjStore
88 void send_response_data(bufferlist
&bl
) override
;
91 class RGWPutBucketTags_ObjStore_S3
: public RGWPutBucketTags_ObjStore
94 int get_params() override
;
95 void send_response() override
;
98 class RGWDeleteBucketTags_ObjStore_S3
: public RGWDeleteBucketTags
101 void send_response() override
;
104 class RGWGetBucketReplication_ObjStore_S3
: public RGWGetBucketReplication_ObjStore
107 void send_response_data() override
;
110 class RGWPutBucketReplication_ObjStore_S3
: public RGWPutBucketReplication_ObjStore
113 int get_params() override
;
114 void send_response() override
;
117 class RGWDeleteBucketReplication_ObjStore_S3
: public RGWDeleteBucketReplication_ObjStore
120 void update_sync_policy(rgw_sync_policy_info
*policy
) override
;
122 void send_response() override
;
125 class RGWListBuckets_ObjStore_S3
: public RGWListBuckets_ObjStore
{
127 RGWListBuckets_ObjStore_S3() {}
128 ~RGWListBuckets_ObjStore_S3() override
{}
130 int get_params() override
{
131 limit
= -1; /* no limit */
134 void send_response_begin(bool has_buckets
) override
;
135 void send_response_data(rgw::sal::RGWBucketList
& buckets
) override
;
136 void send_response_end() override
;
139 class RGWGetUsage_ObjStore_S3
: public RGWGetUsage_ObjStore
{
141 RGWGetUsage_ObjStore_S3() {}
142 ~RGWGetUsage_ObjStore_S3() override
{}
144 int get_params() override
;
145 void send_response() override
;
148 class RGWListBucket_ObjStore_S3
: public RGWListBucket_ObjStore
{
151 bool encode_key
{false};
152 int get_common_params();
153 void send_common_response();
154 void send_common_versioned_response();
156 RGWListBucket_ObjStore_S3() : objs_container(false) {
159 ~RGWListBucket_ObjStore_S3() override
{}
161 int get_params() override
;
162 void send_response() override
;
163 void send_versioned_response();
166 class RGWListBucket_ObjStore_S3v2
: public RGWListBucket_ObjStore_S3
{
168 bool start_after_exist
;
169 bool continuation_token_exist
;
171 string continuation_token
;
173 RGWListBucket_ObjStore_S3v2() : fetchOwner(false) {
175 ~RGWListBucket_ObjStore_S3v2() override
{}
177 int get_params() override
;
178 void send_response() override
;
179 void send_versioned_response();
182 class RGWGetBucketLogging_ObjStore_S3
: public RGWGetBucketLogging
{
184 RGWGetBucketLogging_ObjStore_S3() {}
185 ~RGWGetBucketLogging_ObjStore_S3() override
{}
187 void send_response() override
;
190 class RGWGetBucketLocation_ObjStore_S3
: public RGWGetBucketLocation
{
192 RGWGetBucketLocation_ObjStore_S3() {}
193 ~RGWGetBucketLocation_ObjStore_S3() override
{}
195 void send_response() override
;
198 class RGWGetBucketVersioning_ObjStore_S3
: public RGWGetBucketVersioning
{
200 RGWGetBucketVersioning_ObjStore_S3() {}
201 ~RGWGetBucketVersioning_ObjStore_S3() override
{}
203 void send_response() override
;
206 class RGWSetBucketVersioning_ObjStore_S3
: public RGWSetBucketVersioning
{
208 RGWSetBucketVersioning_ObjStore_S3() {}
209 ~RGWSetBucketVersioning_ObjStore_S3() override
{}
211 int get_params() override
;
212 void send_response() override
;
215 class RGWGetBucketWebsite_ObjStore_S3
: public RGWGetBucketWebsite
{
217 RGWGetBucketWebsite_ObjStore_S3() {}
218 ~RGWGetBucketWebsite_ObjStore_S3() override
{}
220 void send_response() override
;
223 class RGWSetBucketWebsite_ObjStore_S3
: public RGWSetBucketWebsite
{
225 RGWSetBucketWebsite_ObjStore_S3() {}
226 ~RGWSetBucketWebsite_ObjStore_S3() override
{}
228 int get_params() override
;
229 void send_response() override
;
232 class RGWDeleteBucketWebsite_ObjStore_S3
: public RGWDeleteBucketWebsite
{
234 RGWDeleteBucketWebsite_ObjStore_S3() {}
235 ~RGWDeleteBucketWebsite_ObjStore_S3() override
{}
237 void send_response() override
;
240 class RGWStatBucket_ObjStore_S3
: public RGWStatBucket_ObjStore
{
242 RGWStatBucket_ObjStore_S3() {}
243 ~RGWStatBucket_ObjStore_S3() override
{}
245 void send_response() override
;
248 class RGWCreateBucket_ObjStore_S3
: public RGWCreateBucket_ObjStore
{
250 RGWCreateBucket_ObjStore_S3() {}
251 ~RGWCreateBucket_ObjStore_S3() override
{}
253 int get_params() override
;
254 void send_response() override
;
257 class RGWDeleteBucket_ObjStore_S3
: public RGWDeleteBucket_ObjStore
{
259 RGWDeleteBucket_ObjStore_S3() {}
260 ~RGWDeleteBucket_ObjStore_S3() override
{}
262 void send_response() override
;
265 class RGWPutObj_ObjStore_S3
: public RGWPutObj_ObjStore
{
267 std::map
<std::string
, std::string
> crypt_http_responses
;
270 RGWPutObj_ObjStore_S3() {}
271 ~RGWPutObj_ObjStore_S3() override
{}
273 int get_params() override
;
274 int get_data(bufferlist
& bl
) override
;
275 void send_response() override
;
277 int get_encrypt_filter(std::unique_ptr
<rgw::putobj::DataProcessor
> *filter
,
278 rgw::putobj::DataProcessor
*cb
) override
;
279 int get_decrypt_filter(std::unique_ptr
<RGWGetObj_Filter
>* filter
,
280 RGWGetObj_Filter
* cb
,
281 map
<string
, bufferlist
>& attrs
,
282 bufferlist
* manifest_bl
) override
;
285 class RGWPostObj_ObjStore_S3
: public RGWPostObj_ObjStore
{
286 parts_collection_t parts
;
287 std::string filename
;
288 std::string content_type
;
290 RGWPolicy post_policy
;
291 map
<string
, string
> crypt_http_responses
;
293 const rgw::auth::StrategyRegistry
* auth_registry_ptr
= nullptr;
297 void rebuild_key(string
& key
);
299 std::string
get_current_filename() const override
;
300 std::string
get_current_content_type() const override
;
303 RGWPostObj_ObjStore_S3() {}
304 ~RGWPostObj_ObjStore_S3() override
{}
306 int verify_requester(const rgw::auth::StrategyRegistry
& auth_registry
) override
{
307 auth_registry_ptr
= &auth_registry
;
308 return RGWPostObj_ObjStore::verify_requester(auth_registry
);
311 int get_params() override
;
312 int complete_get_params();
314 void send_response() override
;
315 int get_data(ceph::bufferlist
& bl
, bool& again
) override
;
316 int get_encrypt_filter(std::unique_ptr
<rgw::putobj::DataProcessor
> *filter
,
317 rgw::putobj::DataProcessor
*cb
) override
;
320 class RGWDeleteObj_ObjStore_S3
: public RGWDeleteObj_ObjStore
{
322 RGWDeleteObj_ObjStore_S3() {}
323 ~RGWDeleteObj_ObjStore_S3() override
{}
325 int get_params() override
;
326 void send_response() override
;
329 class RGWCopyObj_ObjStore_S3
: public RGWCopyObj_ObjStore
{
332 RGWCopyObj_ObjStore_S3() : sent_header(false) {}
333 ~RGWCopyObj_ObjStore_S3() override
{}
335 int init_dest_policy() override
;
336 int get_params() override
;
337 int check_storage_class(const rgw_placement_rule
& src_placement
);
338 void send_partial_response(off_t ofs
) override
;
339 void send_response() override
;
342 class RGWGetACLs_ObjStore_S3
: public RGWGetACLs_ObjStore
{
344 RGWGetACLs_ObjStore_S3() {}
345 ~RGWGetACLs_ObjStore_S3() override
{}
347 void send_response() override
;
350 class RGWPutACLs_ObjStore_S3
: public RGWPutACLs_ObjStore
{
352 RGWPutACLs_ObjStore_S3() {}
353 ~RGWPutACLs_ObjStore_S3() override
{}
355 int get_policy_from_state(rgw::sal::RGWRadosStore
*store
, struct req_state
*s
, stringstream
& ss
) override
;
356 void send_response() override
;
357 int get_params() override
;
360 class RGWGetLC_ObjStore_S3
: public RGWGetLC_ObjStore
{
362 RGWLifecycleConfiguration_S3 config
;
364 RGWGetLC_ObjStore_S3() {}
365 ~RGWGetLC_ObjStore_S3() override
{}
366 void execute() override
;
368 void send_response() override
;
371 class RGWPutLC_ObjStore_S3
: public RGWPutLC_ObjStore
{
373 RGWPutLC_ObjStore_S3() {}
374 ~RGWPutLC_ObjStore_S3() override
{}
376 void send_response() override
;
379 class RGWDeleteLC_ObjStore_S3
: public RGWDeleteLC_ObjStore
{
381 RGWDeleteLC_ObjStore_S3() {}
382 ~RGWDeleteLC_ObjStore_S3() override
{}
384 void send_response() override
;
387 class RGWGetCORS_ObjStore_S3
: public RGWGetCORS_ObjStore
{
389 RGWGetCORS_ObjStore_S3() {}
390 ~RGWGetCORS_ObjStore_S3() override
{}
392 void send_response() override
;
395 class RGWPutCORS_ObjStore_S3
: public RGWPutCORS_ObjStore
{
397 RGWPutCORS_ObjStore_S3() {}
398 ~RGWPutCORS_ObjStore_S3() override
{}
400 int get_params() override
;
401 void send_response() override
;
404 class RGWDeleteCORS_ObjStore_S3
: public RGWDeleteCORS_ObjStore
{
406 RGWDeleteCORS_ObjStore_S3() {}
407 ~RGWDeleteCORS_ObjStore_S3() override
{}
409 void send_response() override
;
412 class RGWOptionsCORS_ObjStore_S3
: public RGWOptionsCORS_ObjStore
{
414 RGWOptionsCORS_ObjStore_S3() {}
415 ~RGWOptionsCORS_ObjStore_S3() override
{}
417 void send_response() override
;
420 class RGWGetRequestPayment_ObjStore_S3
: public RGWGetRequestPayment
{
422 RGWGetRequestPayment_ObjStore_S3() {}
423 ~RGWGetRequestPayment_ObjStore_S3() override
{}
425 void send_response() override
;
428 class RGWSetRequestPayment_ObjStore_S3
: public RGWSetRequestPayment
{
430 RGWSetRequestPayment_ObjStore_S3() {}
431 ~RGWSetRequestPayment_ObjStore_S3() override
{}
433 int get_params() override
;
434 void send_response() override
;
437 class RGWInitMultipart_ObjStore_S3
: public RGWInitMultipart_ObjStore
{
439 std::map
<std::string
, std::string
> crypt_http_responses
;
441 RGWInitMultipart_ObjStore_S3() {}
442 ~RGWInitMultipart_ObjStore_S3() override
{}
444 int get_params() override
;
445 void send_response() override
;
446 int prepare_encryption(map
<string
, bufferlist
>& attrs
) override
;
449 class RGWCompleteMultipart_ObjStore_S3
: public RGWCompleteMultipart_ObjStore
{
451 RGWCompleteMultipart_ObjStore_S3() {}
452 ~RGWCompleteMultipart_ObjStore_S3() override
{}
454 int get_params() override
;
455 void send_response() override
;
458 class RGWAbortMultipart_ObjStore_S3
: public RGWAbortMultipart_ObjStore
{
460 RGWAbortMultipart_ObjStore_S3() {}
461 ~RGWAbortMultipart_ObjStore_S3() override
{}
463 void send_response() override
;
466 class RGWListMultipart_ObjStore_S3
: public RGWListMultipart_ObjStore
{
468 RGWListMultipart_ObjStore_S3() {}
469 ~RGWListMultipart_ObjStore_S3() override
{}
471 void send_response() override
;
474 class RGWListBucketMultiparts_ObjStore_S3
: public RGWListBucketMultiparts_ObjStore
{
476 RGWListBucketMultiparts_ObjStore_S3() {
479 ~RGWListBucketMultiparts_ObjStore_S3() override
{}
481 void send_response() override
;
484 class RGWDeleteMultiObj_ObjStore_S3
: public RGWDeleteMultiObj_ObjStore
{
486 RGWDeleteMultiObj_ObjStore_S3() {}
487 ~RGWDeleteMultiObj_ObjStore_S3() override
{}
489 int get_params() override
;
490 void send_status() override
;
491 void begin_response() override
;
492 void send_partial_response(rgw_obj_key
& key
, bool delete_marker
,
493 const string
& marker_version_id
, int ret
) override
;
494 void end_response() override
;
497 class RGWPutBucketObjectLock_ObjStore_S3
: public RGWPutBucketObjectLock_ObjStore
{
499 RGWPutBucketObjectLock_ObjStore_S3() {}
500 ~RGWPutBucketObjectLock_ObjStore_S3() override
{}
501 void send_response() override
;
504 class RGWGetBucketObjectLock_ObjStore_S3
: public RGWGetBucketObjectLock_ObjStore
{
506 RGWGetBucketObjectLock_ObjStore_S3() {}
507 ~RGWGetBucketObjectLock_ObjStore_S3() {}
508 void send_response() override
;
511 class RGWPutObjRetention_ObjStore_S3
: public RGWPutObjRetention_ObjStore
{
513 RGWPutObjRetention_ObjStore_S3() {}
514 ~RGWPutObjRetention_ObjStore_S3() {}
515 int get_params() override
;
516 void send_response() override
;
519 class RGWGetObjRetention_ObjStore_S3
: public RGWGetObjRetention_ObjStore
{
521 RGWGetObjRetention_ObjStore_S3() {}
522 ~RGWGetObjRetention_ObjStore_S3() {}
523 void send_response() override
;
526 class RGWPutObjLegalHold_ObjStore_S3
: public RGWPutObjLegalHold_ObjStore
{
528 RGWPutObjLegalHold_ObjStore_S3() {}
529 ~RGWPutObjLegalHold_ObjStore_S3() {}
530 void send_response() override
;
533 class RGWGetObjLegalHold_ObjStore_S3
: public RGWGetObjLegalHold_ObjStore
{
535 RGWGetObjLegalHold_ObjStore_S3() {}
536 ~RGWGetObjLegalHold_ObjStore_S3() {}
537 void send_response() override
;
540 class RGWGetObjLayout_ObjStore_S3
: public RGWGetObjLayout
{
542 RGWGetObjLayout_ObjStore_S3() {}
543 ~RGWGetObjLayout_ObjStore_S3() {}
545 void send_response() override
;
548 class RGWConfigBucketMetaSearch_ObjStore_S3
: public RGWConfigBucketMetaSearch
{
550 RGWConfigBucketMetaSearch_ObjStore_S3() {}
551 ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
553 int get_params() override
;
554 void send_response() override
;
557 class RGWGetBucketMetaSearch_ObjStore_S3
: public RGWGetBucketMetaSearch
{
559 RGWGetBucketMetaSearch_ObjStore_S3() {}
560 ~RGWGetBucketMetaSearch_ObjStore_S3() {}
562 void send_response() override
;
565 class RGWDelBucketMetaSearch_ObjStore_S3
: public RGWDelBucketMetaSearch
{
567 RGWDelBucketMetaSearch_ObjStore_S3() {}
568 ~RGWDelBucketMetaSearch_ObjStore_S3() {}
570 void send_response() override
;
573 class RGWGetBucketPolicyStatus_ObjStore_S3
: public RGWGetBucketPolicyStatus
{
575 void send_response() override
;
578 class RGWPutBucketPublicAccessBlock_ObjStore_S3
: public RGWPutBucketPublicAccessBlock
{
580 void send_response() override
;
583 class RGWGetBucketPublicAccessBlock_ObjStore_S3
: public RGWGetBucketPublicAccessBlock
{
585 void send_response() override
;
590 static int authorize(const DoutPrefixProvider
*dpp
,
591 rgw::sal::RGWRadosStore
*store
,
592 const rgw::auth::StrategyRegistry
& auth_registry
,
593 struct req_state
*s
);
596 class RGWHandler_Auth_S3
: public RGWHandler_REST
{
597 friend class RGWRESTMgr_S3
;
599 const rgw::auth::StrategyRegistry
& auth_registry
;
602 explicit RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry
& auth_registry
)
604 auth_registry(auth_registry
) {
606 ~RGWHandler_Auth_S3() override
= default;
608 static int validate_bucket_name(const string
& bucket
);
609 static int validate_object_name(const string
& bucket
);
611 int init(rgw::sal::RGWRadosStore
*store
,
613 rgw::io::BasicClient
*cio
) override
;
614 int authorize(const DoutPrefixProvider
*dpp
) override
{
615 return RGW_Auth_S3::authorize(dpp
, store
, auth_registry
, s
);
617 int postauth_init() override
{ return 0; }
620 class RGWHandler_REST_S3
: public RGWHandler_REST
{
621 friend class RGWRESTMgr_S3
;
623 const rgw::auth::StrategyRegistry
& auth_registry
;
625 static int init_from_header(struct req_state
*s
, int default_formatter
, bool configurable_format
);
627 explicit RGWHandler_REST_S3(const rgw::auth::StrategyRegistry
& auth_registry
)
629 auth_registry(auth_registry
) {
631 ~RGWHandler_REST_S3() override
= default;
633 int init(rgw::sal::RGWRadosStore
*store
,
635 rgw::io::BasicClient
*cio
) override
;
636 int authorize(const DoutPrefixProvider
*dpp
) override
;
637 int postauth_init() override
;
640 class RGWHandler_REST_Service_S3
: public RGWHandler_REST_S3
{
642 const bool isSTSEnabled
;
643 const bool isIAMEnabled
;
644 const bool isPSEnabled
;
645 bool is_usage_op() const {
646 return s
->info
.args
.exists("usage");
648 RGWOp
*op_get() override
;
649 RGWOp
*op_head() override
;
650 RGWOp
*op_post() override
;
652 RGWHandler_REST_Service_S3(const rgw::auth::StrategyRegistry
& auth_registry
,
653 bool _isSTSEnabled
, bool _isIAMEnabled
, bool _isPSEnabled
) :
654 RGWHandler_REST_S3(auth_registry
), isSTSEnabled(_isSTSEnabled
), isIAMEnabled(_isIAMEnabled
), isPSEnabled(_isPSEnabled
) {}
655 ~RGWHandler_REST_Service_S3() override
= default;
658 class RGWHandler_REST_Bucket_S3
: public RGWHandler_REST_S3
{
659 const bool enable_pubsub
;
661 bool is_acl_op() const {
662 return s
->info
.args
.exists("acl");
664 bool is_cors_op() const {
665 return s
->info
.args
.exists("cors");
667 bool is_lc_op() const {
668 return s
->info
.args
.exists("lifecycle");
670 bool is_obj_update_op() const override
{
671 return is_acl_op() || is_cors_op();
673 bool is_tagging_op() const {
674 return s
->info
.args
.exists("tagging");
676 bool is_request_payment_op() const {
677 return s
->info
.args
.exists("requestPayment");
679 bool is_policy_op() const {
680 return s
->info
.args
.exists("policy");
682 bool is_object_lock_op() const {
683 return s
->info
.args
.exists("object-lock");
685 bool is_notification_op() const {
687 return s
->info
.args
.exists("notification");
691 bool is_replication_op() const {
692 return s
->info
.args
.exists("replication");
694 bool is_policy_status_op() {
695 return s
->info
.args
.exists("policyStatus");
697 bool is_block_public_access_op() {
698 return s
->info
.args
.exists("publicAccessBlock");
701 RGWOp
*get_obj_op(bool get_data
) const;
702 RGWOp
*op_get() override
;
703 RGWOp
*op_head() override
;
704 RGWOp
*op_put() override
;
705 RGWOp
*op_delete() override
;
706 RGWOp
*op_post() override
;
707 RGWOp
*op_options() override
;
709 RGWHandler_REST_Bucket_S3(const rgw::auth::StrategyRegistry
& auth_registry
, bool _enable_pubsub
) :
710 RGWHandler_REST_S3(auth_registry
), enable_pubsub(_enable_pubsub
) {}
711 ~RGWHandler_REST_Bucket_S3() override
= default;
714 class RGWHandler_REST_Obj_S3
: public RGWHandler_REST_S3
{
716 bool is_acl_op() const {
717 return s
->info
.args
.exists("acl");
719 bool is_tagging_op() const {
720 return s
->info
.args
.exists("tagging");
722 bool is_obj_retention_op() const {
723 return s
->info
.args
.exists("retention");
725 bool is_obj_legal_hold_op() const {
726 return s
->info
.args
.exists("legal-hold");
729 bool is_obj_update_op() const override
{
730 return is_acl_op() || is_tagging_op() || is_obj_retention_op() || is_obj_legal_hold_op();
732 RGWOp
*get_obj_op(bool get_data
);
734 RGWOp
*op_get() override
;
735 RGWOp
*op_head() override
;
736 RGWOp
*op_put() override
;
737 RGWOp
*op_delete() override
;
738 RGWOp
*op_post() override
;
739 RGWOp
*op_options() override
;
741 using RGWHandler_REST_S3::RGWHandler_REST_S3
;
742 ~RGWHandler_REST_Obj_S3() override
= default;
745 class RGWRESTMgr_S3
: public RGWRESTMgr
{
747 const bool enable_s3website
;
748 const bool enable_sts
;
749 const bool enable_iam
;
750 const bool enable_pubsub
;
752 explicit RGWRESTMgr_S3(bool _enable_s3website
=false, bool _enable_sts
=false, bool _enable_iam
=false, bool _enable_pubsub
=false)
753 : enable_s3website(_enable_s3website
),
754 enable_sts(_enable_sts
),
755 enable_iam(_enable_iam
),
756 enable_pubsub(_enable_pubsub
) {
759 ~RGWRESTMgr_S3() override
= default;
761 RGWHandler_REST
*get_handler(struct req_state
* s
,
762 const rgw::auth::StrategyRegistry
& auth_registry
,
763 const std::string
& frontend_prefix
) override
;
766 class RGWHandler_REST_Obj_S3Website
;
768 static inline bool looks_like_ip_address(const char *bucket
)
771 if (inet_pton(AF_INET6
, bucket
, static_cast<void*>(&a
)) == 1) {
775 bool expect_period
= false;
776 for (const char *b
= bucket
; *b
; ++b
) {
783 expect_period
= false;
785 else if (isdigit(*b
)) {
786 expect_period
= true;
792 return (num_periods
== 3);
795 static inline int valid_s3_object_name(const string
& name
) {
796 if (name
.size() > 1024) {
797 return -ERR_INVALID_OBJECT_NAME
;
799 if (check_utf8(name
.c_str(), name
.size())) {
800 return -ERR_INVALID_OBJECT_NAME
;
805 static inline int valid_s3_bucket_name(const string
& name
, bool relaxed
=false)
807 // This function enforces Amazon's spec for bucket names.
808 // (The requirements, not the recommendations.)
809 int len
= name
.size();
810 int max
= (relaxed
? 255 : 63);
814 return -ERR_INVALID_BUCKET_NAME
;
815 } else if (len
> max
) {
817 return -ERR_INVALID_BUCKET_NAME
;
820 // bucket names must start with a number or letter
821 if (!(isalpha(name
[0]) || isdigit(name
[0]))) {
823 return -ERR_INVALID_BUCKET_NAME
;
824 else if (!(name
[0] == '_' || name
[0] == '.' || name
[0] == '-'))
825 return -ERR_INVALID_BUCKET_NAME
;
828 // bucket names must end with a number or letter
829 if (!(isalpha(name
[len
-1]) || isdigit(name
[len
-1])))
831 return -ERR_INVALID_BUCKET_NAME
;
833 for (const char *s
= name
.c_str(); *s
; ++s
) {
839 // name cannot contain uppercase letters
840 if (relaxed
|| islower(c
))
845 // name cannot contain underscore
853 if (!relaxed
&& s
&& *s
) {
854 // name cannot have consecutive periods or dashes
855 // adjacent to periods
856 // ensure s is neither the first nor the last character
859 if ((p
!= '-') && (n
!= '.') && (n
!= '-'))
867 return -ERR_INVALID_BUCKET_NAME
;
870 if (looks_like_ip_address(name
.c_str()))
871 return -ERR_INVALID_BUCKET_NAME
;
877 namespace rgw::auth::s3
{
879 class AWSEngine
: public rgw::auth::Engine
{
881 class VersionAbstractor
{
882 static constexpr size_t DIGEST_SIZE_V2
= CEPH_CRYPTO_HMACSHA1_DIGESTSIZE
;
883 static constexpr size_t DIGEST_SIZE_V4
= CEPH_CRYPTO_HMACSHA256_DIGESTSIZE
;
885 /* Knowing the signature max size allows us to employ the sstring, and thus
886 * avoid dynamic allocations. The multiplier comes from representing digest
887 * in the base64-encoded form. */
888 static constexpr size_t SIGNATURE_MAX_SIZE
= \
889 std::max(DIGEST_SIZE_V2
, DIGEST_SIZE_V4
) * 2 + sizeof('\0');
892 virtual ~VersionAbstractor() {};
894 using access_key_id_t
= boost::string_view
;
895 using client_signature_t
= boost::string_view
;
896 using session_token_t
= boost::string_view
;
897 using server_signature_t
= basic_sstring
<char, uint16_t, SIGNATURE_MAX_SIZE
>;
898 using string_to_sign_t
= std::string
;
900 /* Transformation for crafting the AWS signature at server side which is
901 * used later to compare with the user-provided one. The methodology for
902 * doing that depends on AWS auth version. */
903 using signature_factory_t
= \
904 std::function
<server_signature_t(CephContext
* cct
,
905 const std::string
& secret_key
,
906 const string_to_sign_t
& string_to_sign
)>;
908 /* Return an instance of Completer for verifying the payload's fingerprint
909 * if necessary. Otherwise caller gets nullptr. Caller may provide secret
911 using completer_factory_t
= \
912 std::function
<rgw::auth::Completer::cmplptr_t(
913 const boost::optional
<std::string
>& secret_key
)>;
916 access_key_id_t access_key_id
;
917 client_signature_t client_signature
;
918 session_token_t session_token
;
919 string_to_sign_t string_to_sign
;
920 signature_factory_t signature_factory
;
921 completer_factory_t completer_factory
;
924 virtual auth_data_t
get_auth_data(const req_state
* s
) const = 0;
929 const VersionAbstractor
& ver_abstractor
;
931 AWSEngine(CephContext
* const cct
, const VersionAbstractor
& ver_abstractor
)
933 ver_abstractor(ver_abstractor
) {
936 using result_t
= rgw::auth::Engine::result_t
;
937 using string_to_sign_t
= VersionAbstractor::string_to_sign_t
;
938 using signature_factory_t
= VersionAbstractor::signature_factory_t
;
939 using completer_factory_t
= VersionAbstractor::completer_factory_t
;
941 /* TODO(rzarzynski): clean up. We've too many input parameter hee. Also
942 * the signature get_auth_data() of VersionAbstractor is too complicated.
943 * Replace these thing with a simple, dedicated structure. */
944 virtual result_t
authenticate(const DoutPrefixProvider
* dpp
,
945 const boost::string_view
& access_key_id
,
946 const boost::string_view
& signature
,
947 const boost::string_view
& session_token
,
948 const string_to_sign_t
& string_to_sign
,
949 const signature_factory_t
& signature_factory
,
950 const completer_factory_t
& completer_factory
,
951 const req_state
* s
) const = 0;
954 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
) const final
;
958 class AWSGeneralAbstractor
: public AWSEngine::VersionAbstractor
{
959 CephContext
* const cct
;
961 virtual boost::optional
<std::string
>
962 get_v4_canonical_headers(const req_info
& info
,
963 const boost::string_view
& signedheaders
,
964 const bool using_qs
) const;
966 auth_data_t
get_auth_data_v2(const req_state
* s
) const;
967 auth_data_t
get_auth_data_v4(const req_state
* s
, const bool using_qs
) const;
970 explicit AWSGeneralAbstractor(CephContext
* const cct
)
974 auth_data_t
get_auth_data(const req_state
* s
) const override
;
977 class AWSGeneralBoto2Abstractor
: public AWSGeneralAbstractor
{
978 boost::optional
<std::string
>
979 get_v4_canonical_headers(const req_info
& info
,
980 const boost::string_view
& signedheaders
,
981 const bool using_qs
) const override
;
984 using AWSGeneralAbstractor::AWSGeneralAbstractor
;
987 class AWSBrowserUploadAbstractor
: public AWSEngine::VersionAbstractor
{
988 static std::string
to_string(ceph::bufferlist bl
) {
989 return std::string(bl
.c_str(),
990 static_cast<std::string::size_type
>(bl
.length()));
993 auth_data_t
get_auth_data_v2(const req_state
* s
) const;
994 auth_data_t
get_auth_data_v4(const req_state
* s
) const;
997 explicit AWSBrowserUploadAbstractor(CephContext
*) {
1000 auth_data_t
get_auth_data(const req_state
* s
) const override
;
1004 class LDAPEngine
: public AWSEngine
{
1005 static rgw::LDAPHelper
* ldh
;
1006 static std::mutex mtx
;
1008 static void init(CephContext
* const cct
);
1010 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
1011 using auth_info_t
= rgw::auth::RemoteApplier::AuthInfo
;
1012 using result_t
= rgw::auth::Engine::result_t
;
1016 const rgw::auth::RemoteApplier::Factory
* const apl_factory
;
1018 acl_strategy_t
get_acl_strategy() const;
1019 auth_info_t
get_creds_info(const rgw::RGWToken
& token
) const noexcept
;
1021 result_t
authenticate(const DoutPrefixProvider
* dpp
,
1022 const boost::string_view
& access_key_id
,
1023 const boost::string_view
& signature
,
1024 const boost::string_view
& session_token
,
1025 const string_to_sign_t
& string_to_sign
,
1026 const signature_factory_t
&,
1027 const completer_factory_t
& completer_factory
,
1028 const req_state
* s
) const override
;
1030 LDAPEngine(CephContext
* const cct
,
1032 const VersionAbstractor
& ver_abstractor
,
1033 const rgw::auth::RemoteApplier::Factory
* const apl_factory
)
1034 : AWSEngine(cct
, ver_abstractor
),
1036 apl_factory(apl_factory
) {
1040 using AWSEngine::authenticate
;
1042 const char* get_name() const noexcept override
{
1043 return "rgw::auth::s3::LDAPEngine";
1046 static bool valid();
1047 static void shutdown();
1050 class LocalEngine
: public AWSEngine
{
1052 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
1054 result_t
authenticate(const DoutPrefixProvider
* dpp
,
1055 const boost::string_view
& access_key_id
,
1056 const boost::string_view
& signature
,
1057 const boost::string_view
& session_token
,
1058 const string_to_sign_t
& string_to_sign
,
1059 const signature_factory_t
& signature_factory
,
1060 const completer_factory_t
& completer_factory
,
1061 const req_state
* s
) const override
;
1063 LocalEngine(CephContext
* const cct
,
1065 const VersionAbstractor
& ver_abstractor
,
1066 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
1067 : AWSEngine(cct
, ver_abstractor
),
1069 apl_factory(apl_factory
) {
1072 using AWSEngine::authenticate
;
1074 const char* get_name() const noexcept override
{
1075 return "rgw::auth::s3::LocalEngine";
1079 class STSEngine
: public AWSEngine
{
1081 const rgw::auth::LocalApplier::Factory
* const local_apl_factory
;
1082 const rgw::auth::RemoteApplier::Factory
* const remote_apl_factory
;
1083 const rgw::auth::RoleApplier::Factory
* const role_apl_factory
;
1085 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
1086 using auth_info_t
= rgw::auth::RemoteApplier::AuthInfo
;
1088 acl_strategy_t
get_acl_strategy() const { return nullptr; };
1089 auth_info_t
get_creds_info(const STS::SessionToken
& token
) const noexcept
;
1091 int get_session_token(const DoutPrefixProvider
* dpp
, const boost::string_view
& session_token
,
1092 STS::SessionToken
& token
) const;
1094 result_t
authenticate(const DoutPrefixProvider
* dpp
,
1095 const boost::string_view
& access_key_id
,
1096 const boost::string_view
& signature
,
1097 const boost::string_view
& session_token
,
1098 const string_to_sign_t
& string_to_sign
,
1099 const signature_factory_t
& signature_factory
,
1100 const completer_factory_t
& completer_factory
,
1101 const req_state
* s
) const override
;
1103 STSEngine(CephContext
* const cct
,
1105 const VersionAbstractor
& ver_abstractor
,
1106 const rgw::auth::LocalApplier::Factory
* const local_apl_factory
,
1107 const rgw::auth::RemoteApplier::Factory
* const remote_apl_factory
,
1108 const rgw::auth::RoleApplier::Factory
* const role_apl_factory
)
1109 : AWSEngine(cct
, ver_abstractor
),
1111 local_apl_factory(local_apl_factory
),
1112 remote_apl_factory(remote_apl_factory
),
1113 role_apl_factory(role_apl_factory
) {
1116 using AWSEngine::authenticate
;
1118 const char* get_name() const noexcept override
{
1119 return "rgw::auth::s3::STSEngine";
1123 class S3AnonymousEngine
: public rgw::auth::AnonymousEngine
{
1124 bool is_applicable(const req_state
* s
) const noexcept override
;
1127 /* Let's reuse the parent class' constructor. */
1128 using rgw::auth::AnonymousEngine::AnonymousEngine
;
1130 const char* get_name() const noexcept override
{
1131 return "rgw::auth::s3::S3AnonymousEngine";
1136 } // namespace rgw::auth::s3