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
11 #include <boost/container/static_vector.hpp>
12 #include <boost/crc.hpp>
14 #include "common/sstring.hh"
17 #include "rgw_http_errors.h"
18 #include "rgw_acl_s3.h"
19 #include "rgw_policy_s3.h"
20 #include "rgw_lc_s3.h"
21 #include "rgw_keystone.h"
22 #include "rgw_rest_conn.h"
25 #include "rgw_token.h"
26 #include "include/ceph_assert.h"
29 #include "rgw_auth_filters.h"
32 struct rgw_http_error
{
37 void rgw_get_errno_s3(struct rgw_http_error
*e
, int err_no
);
39 class RGWGetObj_ObjStore_S3
: public RGWGetObj_ObjStore
42 // Serving a custom error page from an object is really a 200 response with
43 // just the status line altered.
44 int custom_http_ret
= 0;
45 std::map
<std::string
, std::string
> crypt_http_responses
;
46 int override_range_hdr(const rgw::auth::StrategyRegistry
& auth_registry
, optional_yield y
);
48 RGWGetObj_ObjStore_S3() {}
49 ~RGWGetObj_ObjStore_S3() override
{}
51 int verify_requester(const rgw::auth::StrategyRegistry
& auth_registry
, optional_yield y
) override
;
52 int get_params(optional_yield y
) override
;
53 int send_response_data_error(optional_yield y
) override
;
54 int send_response_data(bufferlist
& bl
, off_t ofs
, off_t len
) override
;
55 void set_custom_http_response(int http_ret
) { custom_http_ret
= http_ret
; }
56 int get_decrypt_filter(std::unique_ptr
<RGWGetObj_Filter
>* filter
,
58 bufferlist
* manifest_bl
) override
;
61 class RGWGetObjTags_ObjStore_S3
: public RGWGetObjTags_ObjStore
64 RGWGetObjTags_ObjStore_S3() {}
65 ~RGWGetObjTags_ObjStore_S3() {}
67 void send_response_data(bufferlist
&bl
) override
;
70 class RGWPutObjTags_ObjStore_S3
: public RGWPutObjTags_ObjStore
73 RGWPutObjTags_ObjStore_S3() {}
74 ~RGWPutObjTags_ObjStore_S3() {}
76 int get_params(optional_yield y
) override
;
77 void send_response() override
;
80 class RGWDeleteObjTags_ObjStore_S3
: public RGWDeleteObjTags
83 ~RGWDeleteObjTags_ObjStore_S3() override
{}
84 void send_response() override
;
87 class RGWGetBucketTags_ObjStore_S3
: public RGWGetBucketTags_ObjStore
91 void send_response_data(bufferlist
&bl
) override
;
94 class RGWPutBucketTags_ObjStore_S3
: public RGWPutBucketTags_ObjStore
97 int get_params(const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
98 void send_response() override
;
101 class RGWDeleteBucketTags_ObjStore_S3
: public RGWDeleteBucketTags
104 void send_response() override
;
107 class RGWGetBucketReplication_ObjStore_S3
: public RGWGetBucketReplication_ObjStore
110 void send_response_data() override
;
113 class RGWPutBucketReplication_ObjStore_S3
: public RGWPutBucketReplication_ObjStore
116 int get_params(optional_yield y
) override
;
117 void send_response() override
;
120 class RGWDeleteBucketReplication_ObjStore_S3
: public RGWDeleteBucketReplication_ObjStore
123 void update_sync_policy(rgw_sync_policy_info
*policy
) override
;
125 void send_response() override
;
128 class RGWListBuckets_ObjStore_S3
: public RGWListBuckets_ObjStore
{
130 RGWListBuckets_ObjStore_S3() {}
131 ~RGWListBuckets_ObjStore_S3() override
{}
133 int get_params(optional_yield y
) override
{
134 limit
= -1; /* no limit */
137 void send_response_begin(bool has_buckets
) override
;
138 void send_response_data(rgw::sal::BucketList
& buckets
) override
;
139 void send_response_end() override
;
142 class RGWGetUsage_ObjStore_S3
: public RGWGetUsage_ObjStore
{
144 RGWGetUsage_ObjStore_S3() {}
145 ~RGWGetUsage_ObjStore_S3() override
{}
147 int get_params(optional_yield y
) override
;
148 void send_response() override
;
151 class RGWListBucket_ObjStore_S3
: public RGWListBucket_ObjStore
{
154 bool encode_key
{false};
155 int get_common_params();
156 void send_common_response();
157 void send_common_versioned_response();
159 RGWListBucket_ObjStore_S3() : objs_container(false) {
162 ~RGWListBucket_ObjStore_S3() override
{}
164 int get_params(optional_yield y
) override
;
165 void send_response() override
;
166 void send_versioned_response();
169 class RGWListBucket_ObjStore_S3v2
: public RGWListBucket_ObjStore_S3
{
171 bool start_after_exist
;
172 bool continuation_token_exist
;
173 std::string startAfter
;
174 std::string continuation_token
;
176 RGWListBucket_ObjStore_S3v2() : fetchOwner(false) {
178 ~RGWListBucket_ObjStore_S3v2() override
{}
180 int get_params(optional_yield y
) override
;
181 void send_response() override
;
182 void send_versioned_response();
185 class RGWGetBucketLogging_ObjStore_S3
: public RGWGetBucketLogging
{
187 RGWGetBucketLogging_ObjStore_S3() {}
188 ~RGWGetBucketLogging_ObjStore_S3() override
{}
190 void send_response() override
;
193 class RGWGetBucketLocation_ObjStore_S3
: public RGWGetBucketLocation
{
195 RGWGetBucketLocation_ObjStore_S3() {}
196 ~RGWGetBucketLocation_ObjStore_S3() override
{}
198 void send_response() override
;
201 class RGWGetBucketVersioning_ObjStore_S3
: public RGWGetBucketVersioning
{
203 RGWGetBucketVersioning_ObjStore_S3() {}
204 ~RGWGetBucketVersioning_ObjStore_S3() override
{}
206 void send_response() override
;
209 class RGWSetBucketVersioning_ObjStore_S3
: public RGWSetBucketVersioning
{
211 RGWSetBucketVersioning_ObjStore_S3() {}
212 ~RGWSetBucketVersioning_ObjStore_S3() override
{}
214 int get_params(optional_yield y
) override
;
215 void send_response() override
;
218 class RGWGetBucketWebsite_ObjStore_S3
: public RGWGetBucketWebsite
{
220 RGWGetBucketWebsite_ObjStore_S3() {}
221 ~RGWGetBucketWebsite_ObjStore_S3() override
{}
223 void send_response() override
;
226 class RGWSetBucketWebsite_ObjStore_S3
: public RGWSetBucketWebsite
{
228 RGWSetBucketWebsite_ObjStore_S3() {}
229 ~RGWSetBucketWebsite_ObjStore_S3() override
{}
231 int get_params(optional_yield y
) override
;
232 void send_response() override
;
235 class RGWDeleteBucketWebsite_ObjStore_S3
: public RGWDeleteBucketWebsite
{
237 RGWDeleteBucketWebsite_ObjStore_S3() {}
238 ~RGWDeleteBucketWebsite_ObjStore_S3() override
{}
240 void send_response() override
;
243 class RGWStatBucket_ObjStore_S3
: public RGWStatBucket_ObjStore
{
245 RGWStatBucket_ObjStore_S3() {}
246 ~RGWStatBucket_ObjStore_S3() override
{}
248 void send_response() override
;
251 class RGWCreateBucket_ObjStore_S3
: public RGWCreateBucket_ObjStore
{
253 RGWCreateBucket_ObjStore_S3() {}
254 ~RGWCreateBucket_ObjStore_S3() override
{}
256 int get_params(optional_yield y
) override
;
257 void send_response() override
;
260 class RGWDeleteBucket_ObjStore_S3
: public RGWDeleteBucket_ObjStore
{
262 RGWDeleteBucket_ObjStore_S3() {}
263 ~RGWDeleteBucket_ObjStore_S3() override
{}
265 void send_response() override
;
268 class RGWPutObj_ObjStore_S3
: public RGWPutObj_ObjStore
{
270 std::map
<std::string
, std::string
> crypt_http_responses
;
273 RGWPutObj_ObjStore_S3() {}
274 ~RGWPutObj_ObjStore_S3() override
{}
276 int get_params(optional_yield y
) override
;
277 int get_data(bufferlist
& bl
) override
;
278 void send_response() override
;
280 int get_encrypt_filter(std::unique_ptr
<rgw::sal::DataProcessor
> *filter
,
281 rgw::sal::DataProcessor
*cb
) override
;
282 int get_decrypt_filter(std::unique_ptr
<RGWGetObj_Filter
>* filter
,
283 RGWGetObj_Filter
* cb
,
284 std::map
<std::string
, bufferlist
>& attrs
,
285 bufferlist
* manifest_bl
) override
;
288 class RGWPostObj_ObjStore_S3
: public RGWPostObj_ObjStore
{
289 parts_collection_t parts
;
290 std::string filename
;
291 std::string content_type
;
293 RGWPolicy post_policy
;
294 std::map
<std::string
, std::string
> crypt_http_responses
;
296 const rgw::auth::StrategyRegistry
* auth_registry_ptr
= nullptr;
298 int get_policy(optional_yield y
);
300 void rebuild_key(rgw::sal::Object
* obj
);
302 std::string
get_current_filename() const override
;
303 std::string
get_current_content_type() const override
;
306 RGWPostObj_ObjStore_S3() {}
307 ~RGWPostObj_ObjStore_S3() override
{}
309 int verify_requester(const rgw::auth::StrategyRegistry
& auth_registry
, optional_yield y
) override
{
310 auth_registry_ptr
= &auth_registry
;
311 return RGWPostObj_ObjStore::verify_requester(auth_registry
, y
);
314 int get_params(optional_yield y
) override
;
315 int complete_get_params();
317 void send_response() override
;
318 int get_data(ceph::bufferlist
& bl
, bool& again
) override
;
319 int get_encrypt_filter(std::unique_ptr
<rgw::sal::DataProcessor
> *filter
,
320 rgw::sal::DataProcessor
*cb
) override
;
323 class RGWDeleteObj_ObjStore_S3
: public RGWDeleteObj_ObjStore
{
325 RGWDeleteObj_ObjStore_S3() {}
326 ~RGWDeleteObj_ObjStore_S3() override
{}
328 int get_params(optional_yield y
) override
;
329 void send_response() override
;
332 class RGWCopyObj_ObjStore_S3
: public RGWCopyObj_ObjStore
{
335 RGWCopyObj_ObjStore_S3() : sent_header(false) {}
336 ~RGWCopyObj_ObjStore_S3() override
{}
338 int init_dest_policy() override
;
339 int get_params(optional_yield y
) override
;
340 int check_storage_class(const rgw_placement_rule
& src_placement
) override
;
341 void send_partial_response(off_t ofs
) override
;
342 void send_response() override
;
345 class RGWGetACLs_ObjStore_S3
: public RGWGetACLs_ObjStore
{
347 RGWGetACLs_ObjStore_S3() {}
348 ~RGWGetACLs_ObjStore_S3() override
{}
350 void send_response() override
;
353 class RGWPutACLs_ObjStore_S3
: public RGWPutACLs_ObjStore
{
355 RGWPutACLs_ObjStore_S3() {}
356 ~RGWPutACLs_ObjStore_S3() override
{}
358 int get_policy_from_state(rgw::sal::Driver
* driver
, req_state
*s
, std::stringstream
& ss
) override
;
359 void send_response() override
;
360 int get_params(optional_yield y
) override
;
363 class RGWGetLC_ObjStore_S3
: public RGWGetLC_ObjStore
{
365 RGWLifecycleConfiguration_S3 config
;
367 RGWGetLC_ObjStore_S3() {}
368 ~RGWGetLC_ObjStore_S3() override
{}
369 void execute(optional_yield y
) override
;
371 void send_response() override
;
374 class RGWPutLC_ObjStore_S3
: public RGWPutLC_ObjStore
{
376 RGWPutLC_ObjStore_S3() {}
377 ~RGWPutLC_ObjStore_S3() override
{}
379 void send_response() override
;
382 class RGWDeleteLC_ObjStore_S3
: public RGWDeleteLC_ObjStore
{
384 RGWDeleteLC_ObjStore_S3() {}
385 ~RGWDeleteLC_ObjStore_S3() override
{}
387 void send_response() override
;
390 class RGWGetCORS_ObjStore_S3
: public RGWGetCORS_ObjStore
{
392 RGWGetCORS_ObjStore_S3() {}
393 ~RGWGetCORS_ObjStore_S3() override
{}
395 void send_response() override
;
398 class RGWPutCORS_ObjStore_S3
: public RGWPutCORS_ObjStore
{
400 RGWPutCORS_ObjStore_S3() {}
401 ~RGWPutCORS_ObjStore_S3() override
{}
403 int get_params(optional_yield y
) override
;
404 void send_response() override
;
407 class RGWDeleteCORS_ObjStore_S3
: public RGWDeleteCORS_ObjStore
{
409 RGWDeleteCORS_ObjStore_S3() {}
410 ~RGWDeleteCORS_ObjStore_S3() override
{}
412 void send_response() override
;
415 class RGWOptionsCORS_ObjStore_S3
: public RGWOptionsCORS_ObjStore
{
417 RGWOptionsCORS_ObjStore_S3() {}
418 ~RGWOptionsCORS_ObjStore_S3() override
{}
420 void send_response() override
;
423 class RGWGetBucketEncryption_ObjStore_S3
: public RGWGetBucketEncryption_ObjStore
{
425 RGWGetBucketEncryption_ObjStore_S3() {}
426 ~RGWGetBucketEncryption_ObjStore_S3() override
{}
428 void send_response() override
;
431 class RGWPutBucketEncryption_ObjStore_S3
: public RGWPutBucketEncryption_ObjStore
{
433 RGWPutBucketEncryption_ObjStore_S3() {}
434 ~RGWPutBucketEncryption_ObjStore_S3() override
{}
436 void send_response() override
;
439 class RGWDeleteBucketEncryption_ObjStore_S3
: public RGWDeleteBucketEncryption_ObjStore
{
441 RGWDeleteBucketEncryption_ObjStore_S3() {}
442 ~RGWDeleteBucketEncryption_ObjStore_S3() override
{}
444 void send_response() override
;
447 class RGWGetRequestPayment_ObjStore_S3
: public RGWGetRequestPayment
{
449 RGWGetRequestPayment_ObjStore_S3() {}
450 ~RGWGetRequestPayment_ObjStore_S3() override
{}
452 void send_response() override
;
455 class RGWSetRequestPayment_ObjStore_S3
: public RGWSetRequestPayment
{
457 RGWSetRequestPayment_ObjStore_S3() {}
458 ~RGWSetRequestPayment_ObjStore_S3() override
{}
460 int get_params(optional_yield y
) override
;
461 void send_response() override
;
464 class RGWInitMultipart_ObjStore_S3
: public RGWInitMultipart_ObjStore
{
466 std::map
<std::string
, std::string
> crypt_http_responses
;
468 RGWInitMultipart_ObjStore_S3() {}
469 ~RGWInitMultipart_ObjStore_S3() override
{}
471 int get_params(optional_yield y
) override
;
472 void send_response() override
;
473 int prepare_encryption(std::map
<std::string
, bufferlist
>& attrs
) override
;
476 class RGWCompleteMultipart_ObjStore_S3
: public RGWCompleteMultipart_ObjStore
{
478 RGWCompleteMultipart_ObjStore_S3() {}
479 ~RGWCompleteMultipart_ObjStore_S3() override
{}
481 int get_params(optional_yield y
) override
;
482 void send_response() override
;
485 class RGWAbortMultipart_ObjStore_S3
: public RGWAbortMultipart_ObjStore
{
487 RGWAbortMultipart_ObjStore_S3() {}
488 ~RGWAbortMultipart_ObjStore_S3() override
{}
490 void send_response() override
;
493 class RGWListMultipart_ObjStore_S3
: public RGWListMultipart_ObjStore
{
495 RGWListMultipart_ObjStore_S3() {}
496 ~RGWListMultipart_ObjStore_S3() override
{}
498 void send_response() override
;
501 class RGWListBucketMultiparts_ObjStore_S3
: public RGWListBucketMultiparts_ObjStore
{
503 RGWListBucketMultiparts_ObjStore_S3() {
506 ~RGWListBucketMultiparts_ObjStore_S3() override
{}
508 void send_response() override
;
511 class RGWDeleteMultiObj_ObjStore_S3
: public RGWDeleteMultiObj_ObjStore
{
513 RGWDeleteMultiObj_ObjStore_S3() {}
514 ~RGWDeleteMultiObj_ObjStore_S3() override
{}
516 int get_params(optional_yield y
) override
;
517 void send_status() override
;
518 void begin_response() override
;
519 void send_partial_response(const rgw_obj_key
& key
, bool delete_marker
,
520 const std::string
& marker_version_id
, int ret
,
521 boost::asio::deadline_timer
*formatter_flush_cond
) override
;
522 void end_response() override
;
525 class RGWPutBucketObjectLock_ObjStore_S3
: public RGWPutBucketObjectLock_ObjStore
{
527 RGWPutBucketObjectLock_ObjStore_S3() {}
528 ~RGWPutBucketObjectLock_ObjStore_S3() override
{}
529 void send_response() override
;
532 class RGWGetBucketObjectLock_ObjStore_S3
: public RGWGetBucketObjectLock_ObjStore
{
534 RGWGetBucketObjectLock_ObjStore_S3() {}
535 ~RGWGetBucketObjectLock_ObjStore_S3() {}
536 void send_response() override
;
539 class RGWPutObjRetention_ObjStore_S3
: public RGWPutObjRetention_ObjStore
{
541 RGWPutObjRetention_ObjStore_S3() {}
542 ~RGWPutObjRetention_ObjStore_S3() {}
543 int get_params(optional_yield y
) override
;
544 void send_response() override
;
547 class RGWGetObjRetention_ObjStore_S3
: public RGWGetObjRetention_ObjStore
{
549 RGWGetObjRetention_ObjStore_S3() {}
550 ~RGWGetObjRetention_ObjStore_S3() {}
551 void send_response() override
;
554 class RGWPutObjLegalHold_ObjStore_S3
: public RGWPutObjLegalHold_ObjStore
{
556 RGWPutObjLegalHold_ObjStore_S3() {}
557 ~RGWPutObjLegalHold_ObjStore_S3() {}
558 void send_response() override
;
561 class RGWGetObjLegalHold_ObjStore_S3
: public RGWGetObjLegalHold_ObjStore
{
563 RGWGetObjLegalHold_ObjStore_S3() {}
564 ~RGWGetObjLegalHold_ObjStore_S3() {}
565 void send_response() override
;
568 class RGWGetObjLayout_ObjStore_S3
: public RGWGetObjLayout
{
570 RGWGetObjLayout_ObjStore_S3() {}
571 ~RGWGetObjLayout_ObjStore_S3() {}
573 void send_response() override
;
576 class RGWConfigBucketMetaSearch_ObjStore_S3
: public RGWConfigBucketMetaSearch
{
578 RGWConfigBucketMetaSearch_ObjStore_S3() {}
579 ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
581 int get_params(optional_yield y
) override
;
582 void send_response() override
;
585 class RGWGetBucketMetaSearch_ObjStore_S3
: public RGWGetBucketMetaSearch
{
587 RGWGetBucketMetaSearch_ObjStore_S3() {}
588 ~RGWGetBucketMetaSearch_ObjStore_S3() {}
590 void send_response() override
;
593 class RGWDelBucketMetaSearch_ObjStore_S3
: public RGWDelBucketMetaSearch
{
595 RGWDelBucketMetaSearch_ObjStore_S3() {}
596 ~RGWDelBucketMetaSearch_ObjStore_S3() {}
598 void send_response() override
;
601 class RGWGetBucketPolicyStatus_ObjStore_S3
: public RGWGetBucketPolicyStatus
{
603 void send_response() override
;
606 class RGWPutBucketPublicAccessBlock_ObjStore_S3
: public RGWPutBucketPublicAccessBlock
{
608 void send_response() override
;
611 class RGWGetBucketPublicAccessBlock_ObjStore_S3
: public RGWGetBucketPublicAccessBlock
{
613 void send_response() override
;
618 static int authorize(const DoutPrefixProvider
*dpp
,
619 rgw::sal::Driver
* driver
,
620 const rgw::auth::StrategyRegistry
& auth_registry
,
621 req_state
*s
, optional_yield y
);
624 class RGWHandler_Auth_S3
: public RGWHandler_REST
{
625 friend class RGWRESTMgr_S3
;
627 const rgw::auth::StrategyRegistry
& auth_registry
;
630 explicit RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry
& auth_registry
)
632 auth_registry(auth_registry
) {
634 ~RGWHandler_Auth_S3() override
= default;
636 static int validate_bucket_name(const std::string
& bucket
);
637 static int validate_object_name(const std::string
& bucket
);
639 int init(rgw::sal::Driver
* driver
,
641 rgw::io::BasicClient
*cio
) override
;
642 int authorize(const DoutPrefixProvider
*dpp
, optional_yield y
) override
{
643 return RGW_Auth_S3::authorize(dpp
, driver
, auth_registry
, s
, y
);
645 int postauth_init(optional_yield
) override
{ return 0; }
648 class RGWHandler_REST_S3
: public RGWHandler_REST
{
649 friend class RGWRESTMgr_S3
;
651 const rgw::auth::StrategyRegistry
& auth_registry
;
653 static int init_from_header(rgw::sal::Driver
* driver
, req_state
*s
, RGWFormat default_formatter
,
654 bool configurable_format
);
656 explicit RGWHandler_REST_S3(const rgw::auth::StrategyRegistry
& auth_registry
)
658 auth_registry(auth_registry
) {
660 ~RGWHandler_REST_S3() override
= default;
662 int init(rgw::sal::Driver
* driver
,
664 rgw::io::BasicClient
*cio
) override
;
665 int authorize(const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
666 int postauth_init(optional_yield y
) override
;
669 class RGWHandler_REST_Service_S3
: public RGWHandler_REST_S3
{
671 bool is_usage_op() const {
672 return s
->info
.args
.exists("usage");
674 RGWOp
*op_get() override
;
675 RGWOp
*op_head() override
;
677 RGWHandler_REST_Service_S3(const rgw::auth::StrategyRegistry
& auth_registry
) :
678 RGWHandler_REST_S3(auth_registry
) {}
679 ~RGWHandler_REST_Service_S3() override
= default;
682 class RGWHandler_REST_Bucket_S3
: public RGWHandler_REST_S3
{
683 const bool enable_pubsub
;
685 bool is_acl_op() const {
686 return s
->info
.args
.exists("acl");
688 bool is_cors_op() const {
689 return s
->info
.args
.exists("cors");
691 bool is_lc_op() const {
692 return s
->info
.args
.exists("lifecycle");
694 bool is_obj_update_op() const override
{
695 return is_acl_op() || is_cors_op();
697 bool is_tagging_op() const {
698 return s
->info
.args
.exists("tagging");
700 bool is_request_payment_op() const {
701 return s
->info
.args
.exists("requestPayment");
703 bool is_policy_op() const {
704 return s
->info
.args
.exists("policy");
706 bool is_object_lock_op() const {
707 return s
->info
.args
.exists("object-lock");
709 bool is_notification_op() const {
711 return s
->info
.args
.exists("notification");
715 bool is_replication_op() const {
716 return s
->info
.args
.exists("replication");
718 bool is_policy_status_op() {
719 return s
->info
.args
.exists("policyStatus");
721 bool is_block_public_access_op() {
722 return s
->info
.args
.exists("publicAccessBlock");
724 bool is_bucket_encryption_op() {
725 return s
->info
.args
.exists("encryption");
728 RGWOp
*get_obj_op(bool get_data
) const;
729 RGWOp
*op_get() override
;
730 RGWOp
*op_head() override
;
731 RGWOp
*op_put() override
;
732 RGWOp
*op_delete() override
;
733 RGWOp
*op_post() override
;
734 RGWOp
*op_options() override
;
736 RGWHandler_REST_Bucket_S3(const rgw::auth::StrategyRegistry
& auth_registry
, bool _enable_pubsub
) :
737 RGWHandler_REST_S3(auth_registry
), enable_pubsub(_enable_pubsub
) {}
738 ~RGWHandler_REST_Bucket_S3() override
= default;
741 class RGWHandler_REST_Obj_S3
: public RGWHandler_REST_S3
{
743 bool is_acl_op() const {
744 return s
->info
.args
.exists("acl");
746 bool is_tagging_op() const {
747 return s
->info
.args
.exists("tagging");
749 bool is_obj_retention_op() const {
750 return s
->info
.args
.exists("retention");
752 bool is_obj_legal_hold_op() const {
753 return s
->info
.args
.exists("legal-hold");
756 bool is_select_op() const {
757 return s
->info
.args
.exists("select-type");
760 bool is_obj_update_op() const override
{
761 return is_acl_op() || is_tagging_op() || is_obj_retention_op() || is_obj_legal_hold_op() || is_select_op();
763 RGWOp
*get_obj_op(bool get_data
);
765 RGWOp
*op_get() override
;
766 RGWOp
*op_head() override
;
767 RGWOp
*op_put() override
;
768 RGWOp
*op_delete() override
;
769 RGWOp
*op_post() override
;
770 RGWOp
*op_options() override
;
772 using RGWHandler_REST_S3::RGWHandler_REST_S3
;
773 ~RGWHandler_REST_Obj_S3() override
= default;
776 class RGWRESTMgr_S3
: public RGWRESTMgr
{
778 const bool enable_s3website
;
779 const bool enable_sts
;
780 const bool enable_iam
;
781 const bool enable_pubsub
;
783 explicit RGWRESTMgr_S3(bool _enable_s3website
=false, bool _enable_sts
=false, bool _enable_iam
=false, bool _enable_pubsub
=false)
784 : enable_s3website(_enable_s3website
),
785 enable_sts(_enable_sts
),
786 enable_iam(_enable_iam
),
787 enable_pubsub(_enable_pubsub
) {
790 ~RGWRESTMgr_S3() override
= default;
792 RGWHandler_REST
*get_handler(rgw::sal::Driver
* driver
,
794 const rgw::auth::StrategyRegistry
& auth_registry
,
795 const std::string
& frontend_prefix
) override
;
798 class RGWHandler_REST_Obj_S3Website
;
800 static inline bool looks_like_ip_address(const char *bucket
)
803 if (inet_pton(AF_INET6
, bucket
, static_cast<void*>(&a
)) == 1) {
807 bool expect_period
= false;
808 for (const char *b
= bucket
; *b
; ++b
) {
815 expect_period
= false;
817 else if (isdigit(*b
)) {
818 expect_period
= true;
824 return (num_periods
== 3);
827 inline int valid_s3_object_name(const std::string
& name
) {
828 if (name
.size() > 1024) {
829 return -ERR_INVALID_OBJECT_NAME
;
831 if (check_utf8(name
.c_str(), name
.size())) {
832 return -ERR_INVALID_OBJECT_NAME
;
837 inline int valid_s3_bucket_name(const std::string
& name
, bool relaxed
=false)
839 // This function enforces Amazon's spec for bucket names.
840 // (The requirements, not the recommendations.)
841 int len
= name
.size();
842 int max
= (relaxed
? 255 : 63);
846 return -ERR_INVALID_BUCKET_NAME
;
847 } else if (len
> max
) {
849 return -ERR_INVALID_BUCKET_NAME
;
852 // bucket names must start with a number or letter
853 if (!(isalpha(name
[0]) || isdigit(name
[0]))) {
855 return -ERR_INVALID_BUCKET_NAME
;
856 else if (!(name
[0] == '_' || name
[0] == '.' || name
[0] == '-'))
857 return -ERR_INVALID_BUCKET_NAME
;
860 // bucket names must end with a number or letter
861 if (!(isalpha(name
[len
-1]) || isdigit(name
[len
-1])))
863 return -ERR_INVALID_BUCKET_NAME
;
865 for (const char *s
= name
.c_str(); *s
; ++s
) {
871 // name cannot contain uppercase letters
872 if (relaxed
|| islower(c
))
877 // name cannot contain underscore
885 if (!relaxed
&& s
&& *s
) {
886 // name cannot have consecutive periods or dashes
887 // adjacent to periods
888 // ensure s is neither the first nor the last character
891 if ((p
!= '-') && (n
!= '.') && (n
!= '-'))
899 return -ERR_INVALID_BUCKET_NAME
;
902 if (looks_like_ip_address(name
.c_str()))
903 return -ERR_INVALID_BUCKET_NAME
;
908 namespace rgw::auth::s3
{
910 class AWSEngine
: public rgw::auth::Engine
{
912 class VersionAbstractor
{
913 static constexpr size_t DIGEST_SIZE_V2
= CEPH_CRYPTO_HMACSHA1_DIGESTSIZE
;
914 static constexpr size_t DIGEST_SIZE_V4
= CEPH_CRYPTO_HMACSHA256_DIGESTSIZE
;
916 /* Knowing the signature max size allows us to employ the sstring, and thus
917 * avoid dynamic allocations. The multiplier comes from representing digest
918 * in the base64-encoded form. */
919 static constexpr size_t SIGNATURE_MAX_SIZE
= \
920 std::max(DIGEST_SIZE_V2
, DIGEST_SIZE_V4
) * 2 + sizeof('\0');
923 virtual ~VersionAbstractor() {};
925 using access_key_id_t
= std::string_view
;
926 using client_signature_t
= std::string_view
;
927 using session_token_t
= std::string_view
;
928 using server_signature_t
= basic_sstring
<char, uint16_t, SIGNATURE_MAX_SIZE
>;
929 using string_to_sign_t
= std::string
;
931 /* Transformation for crafting the AWS signature at server side which is
932 * used later to compare with the user-provided one. The methodology for
933 * doing that depends on AWS auth version. */
934 using signature_factory_t
= \
935 std::function
<server_signature_t(CephContext
* cct
,
936 const std::string
& secret_key
,
937 const string_to_sign_t
& string_to_sign
)>;
939 /* Return an instance of Completer for verifying the payload's fingerprint
940 * if necessary. Otherwise caller gets nullptr. Caller may provide secret
942 using completer_factory_t
= \
943 std::function
<rgw::auth::Completer::cmplptr_t(
944 const boost::optional
<std::string
>& secret_key
)>;
947 access_key_id_t access_key_id
;
948 client_signature_t client_signature
;
949 session_token_t session_token
;
950 string_to_sign_t string_to_sign
;
951 signature_factory_t signature_factory
;
952 completer_factory_t completer_factory
;
955 virtual auth_data_t
get_auth_data(const req_state
* s
) const = 0;
960 const VersionAbstractor
& ver_abstractor
;
962 AWSEngine(CephContext
* const cct
, const VersionAbstractor
& ver_abstractor
)
964 ver_abstractor(ver_abstractor
) {
967 using result_t
= rgw::auth::Engine::result_t
;
968 using string_to_sign_t
= VersionAbstractor::string_to_sign_t
;
969 using signature_factory_t
= VersionAbstractor::signature_factory_t
;
970 using completer_factory_t
= VersionAbstractor::completer_factory_t
;
972 /* TODO(rzarzynski): clean up. We've too many input parameter hee. Also
973 * the signature get_auth_data() of VersionAbstractor is too complicated.
974 * Replace these thing with a simple, dedicated structure. */
975 virtual result_t
authenticate(const DoutPrefixProvider
* dpp
,
976 const std::string_view
& access_key_id
,
977 const std::string_view
& signature
,
978 const std::string_view
& session_token
,
979 const string_to_sign_t
& string_to_sign
,
980 const signature_factory_t
& signature_factory
,
981 const completer_factory_t
& completer_factory
,
983 optional_yield y
) const = 0;
986 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
,
987 optional_yield y
) const final
;
991 class AWSGeneralAbstractor
: public AWSEngine::VersionAbstractor
{
992 CephContext
* const cct
;
994 virtual boost::optional
<std::string
>
995 get_v4_canonical_headers(const req_info
& info
,
996 const std::string_view
& signedheaders
,
997 const bool using_qs
) const;
999 auth_data_t
get_auth_data_v2(const req_state
* s
) const;
1000 auth_data_t
get_auth_data_v4(const req_state
* s
, const bool using_qs
) const;
1003 explicit AWSGeneralAbstractor(CephContext
* const cct
)
1007 auth_data_t
get_auth_data(const req_state
* s
) const override
;
1010 class AWSGeneralBoto2Abstractor
: public AWSGeneralAbstractor
{
1011 boost::optional
<std::string
>
1012 get_v4_canonical_headers(const req_info
& info
,
1013 const std::string_view
& signedheaders
,
1014 const bool using_qs
) const override
;
1017 using AWSGeneralAbstractor::AWSGeneralAbstractor
;
1020 class AWSBrowserUploadAbstractor
: public AWSEngine::VersionAbstractor
{
1021 static std::string
to_string(ceph::bufferlist bl
) {
1022 return std::string(bl
.c_str(),
1023 static_cast<std::string::size_type
>(bl
.length()));
1026 auth_data_t
get_auth_data_v2(const req_state
* s
) const;
1027 auth_data_t
get_auth_data_v4(const req_state
* s
) const;
1030 explicit AWSBrowserUploadAbstractor(CephContext
*) {
1033 auth_data_t
get_auth_data(const req_state
* s
) const override
;
1037 const DoutPrefixProvider
*dpp
;
1041 AWSSignerV4(const DoutPrefixProvider
*_dpp
) : dpp(_dpp
),
1042 cct(_dpp
->get_cct()) {}
1044 using access_key_id_t
= std::string_view
;
1045 using string_to_sign_t
= AWSEngine::VersionAbstractor::string_to_sign_t
;
1046 using signature_headers_t
= std::map
<std::string
, std::string
>;
1048 struct prepare_result_t
;
1050 using signature_factory_t
= \
1051 std::function
<signature_headers_t(const DoutPrefixProvider
* dpp
,
1052 const std::string
& secret_key
,
1053 const prepare_result_t
&)>;
1055 struct prepare_result_t
{
1056 access_key_id_t access_key_id
;
1059 std::string signed_headers
;
1060 string_to_sign_t string_to_sign
;
1061 std::map
<std::string
, std::string
> extra_headers
;
1062 signature_factory_t signature_factory
;
1065 static prepare_result_t
prepare(const DoutPrefixProvider
*dpp
,
1066 const std::string
& access_key_id
,
1067 const string
& region
,
1068 const string
& service
,
1069 const req_info
& info
,
1070 const bufferlist
*opt_content
,
1075 extern AWSSignerV4::signature_headers_t
1076 gen_v4_signature(const DoutPrefixProvider
*dpp
,
1077 const std::string_view
& secret_key
,
1078 const AWSSignerV4::prepare_result_t
& sig_info
);
1080 class LDAPEngine
: public AWSEngine
{
1081 static rgw::LDAPHelper
* ldh
;
1082 static std::mutex mtx
;
1084 static void init(CephContext
* const cct
);
1086 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
1087 using auth_info_t
= rgw::auth::RemoteApplier::AuthInfo
;
1088 using result_t
= rgw::auth::Engine::result_t
;
1091 rgw::sal::Driver
* driver
;
1092 const rgw::auth::RemoteApplier::Factory
* const apl_factory
;
1094 acl_strategy_t
get_acl_strategy() const;
1095 auth_info_t
get_creds_info(const rgw::RGWToken
& token
) const noexcept
;
1097 result_t
authenticate(const DoutPrefixProvider
* dpp
,
1098 const std::string_view
& access_key_id
,
1099 const std::string_view
& signature
,
1100 const std::string_view
& session_token
,
1101 const string_to_sign_t
& string_to_sign
,
1102 const signature_factory_t
&,
1103 const completer_factory_t
& completer_factory
,
1105 optional_yield y
) const override
;
1107 LDAPEngine(CephContext
* const cct
,
1108 rgw::sal::Driver
* driver
,
1109 const VersionAbstractor
& ver_abstractor
,
1110 const rgw::auth::RemoteApplier::Factory
* const apl_factory
)
1111 : AWSEngine(cct
, ver_abstractor
),
1113 apl_factory(apl_factory
) {
1117 using AWSEngine::authenticate
;
1119 const char* get_name() const noexcept override
{
1120 return "rgw::auth::s3::LDAPEngine";
1123 static bool valid();
1124 static void shutdown();
1127 class LocalEngine
: public AWSEngine
{
1128 rgw::sal::Driver
* driver
;
1129 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
1131 result_t
authenticate(const DoutPrefixProvider
* dpp
,
1132 const std::string_view
& access_key_id
,
1133 const std::string_view
& signature
,
1134 const std::string_view
& session_token
,
1135 const string_to_sign_t
& string_to_sign
,
1136 const signature_factory_t
& signature_factory
,
1137 const completer_factory_t
& completer_factory
,
1139 optional_yield y
) const override
;
1141 LocalEngine(CephContext
* const cct
,
1142 rgw::sal::Driver
* driver
,
1143 const VersionAbstractor
& ver_abstractor
,
1144 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
1145 : AWSEngine(cct
, ver_abstractor
),
1147 apl_factory(apl_factory
) {
1150 using AWSEngine::authenticate
;
1152 const char* get_name() const noexcept override
{
1153 return "rgw::auth::s3::LocalEngine";
1157 class STSEngine
: public AWSEngine
{
1158 rgw::sal::Driver
* driver
;
1159 const rgw::auth::LocalApplier::Factory
* const local_apl_factory
;
1160 const rgw::auth::RemoteApplier::Factory
* const remote_apl_factory
;
1161 const rgw::auth::RoleApplier::Factory
* const role_apl_factory
;
1163 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
1164 using auth_info_t
= rgw::auth::RemoteApplier::AuthInfo
;
1166 acl_strategy_t
get_acl_strategy() const { return nullptr; };
1167 auth_info_t
get_creds_info(const STS::SessionToken
& token
) const noexcept
;
1169 int get_session_token(const DoutPrefixProvider
* dpp
, const std::string_view
& session_token
,
1170 STS::SessionToken
& token
) const;
1172 result_t
authenticate(const DoutPrefixProvider
* dpp
,
1173 const std::string_view
& access_key_id
,
1174 const std::string_view
& signature
,
1175 const std::string_view
& session_token
,
1176 const string_to_sign_t
& string_to_sign
,
1177 const signature_factory_t
& signature_factory
,
1178 const completer_factory_t
& completer_factory
,
1180 optional_yield y
) const override
;
1182 STSEngine(CephContext
* const cct
,
1183 rgw::sal::Driver
* driver
,
1184 const VersionAbstractor
& ver_abstractor
,
1185 const rgw::auth::LocalApplier::Factory
* const local_apl_factory
,
1186 const rgw::auth::RemoteApplier::Factory
* const remote_apl_factory
,
1187 const rgw::auth::RoleApplier::Factory
* const role_apl_factory
)
1188 : AWSEngine(cct
, ver_abstractor
),
1190 local_apl_factory(local_apl_factory
),
1191 remote_apl_factory(remote_apl_factory
),
1192 role_apl_factory(role_apl_factory
) {
1195 using AWSEngine::authenticate
;
1197 const char* get_name() const noexcept override
{
1198 return "rgw::auth::s3::STSEngine";
1202 class S3AnonymousEngine
: public rgw::auth::AnonymousEngine
{
1203 bool is_applicable(const req_state
* s
) const noexcept override
;
1206 /* Let's reuse the parent class' constructor. */
1207 using rgw::auth::AnonymousEngine::AnonymousEngine
;
1209 const char* get_name() const noexcept override
{
1210 return "rgw::auth::s3::S3AnonymousEngine";
1215 } // namespace rgw::auth::s3