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(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::RGWBucketList
& 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
;
174 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::putobj::DataProcessor
> *filter
,
281 rgw::putobj::DataProcessor
*cb
) override
;
282 int get_decrypt_filter(std::unique_ptr
<RGWGetObj_Filter
>* filter
,
283 RGWGetObj_Filter
* cb
,
284 map
<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 map
<string
, 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::RGWObject
* 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::putobj::DataProcessor
> *filter
,
320 rgw::putobj::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::RGWRadosStore
*store
, struct req_state
*s
, 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 RGWGetRequestPayment_ObjStore_S3
: public RGWGetRequestPayment
{
425 RGWGetRequestPayment_ObjStore_S3() {}
426 ~RGWGetRequestPayment_ObjStore_S3() override
{}
428 void send_response() override
;
431 class RGWSetRequestPayment_ObjStore_S3
: public RGWSetRequestPayment
{
433 RGWSetRequestPayment_ObjStore_S3() {}
434 ~RGWSetRequestPayment_ObjStore_S3() override
{}
436 int get_params(optional_yield y
) override
;
437 void send_response() override
;
440 class RGWInitMultipart_ObjStore_S3
: public RGWInitMultipart_ObjStore
{
442 std::map
<std::string
, std::string
> crypt_http_responses
;
444 RGWInitMultipart_ObjStore_S3() {}
445 ~RGWInitMultipart_ObjStore_S3() override
{}
447 int get_params(optional_yield y
) override
;
448 void send_response() override
;
449 int prepare_encryption(map
<string
, bufferlist
>& attrs
) override
;
452 class RGWCompleteMultipart_ObjStore_S3
: public RGWCompleteMultipart_ObjStore
{
454 RGWCompleteMultipart_ObjStore_S3() {}
455 ~RGWCompleteMultipart_ObjStore_S3() override
{}
457 int get_params(optional_yield y
) override
;
458 void send_response() override
;
461 class RGWAbortMultipart_ObjStore_S3
: public RGWAbortMultipart_ObjStore
{
463 RGWAbortMultipart_ObjStore_S3() {}
464 ~RGWAbortMultipart_ObjStore_S3() override
{}
466 void send_response() override
;
469 class RGWListMultipart_ObjStore_S3
: public RGWListMultipart_ObjStore
{
471 RGWListMultipart_ObjStore_S3() {}
472 ~RGWListMultipart_ObjStore_S3() override
{}
474 void send_response() override
;
477 class RGWListBucketMultiparts_ObjStore_S3
: public RGWListBucketMultiparts_ObjStore
{
479 RGWListBucketMultiparts_ObjStore_S3() {
482 ~RGWListBucketMultiparts_ObjStore_S3() override
{}
484 void send_response() override
;
487 class RGWDeleteMultiObj_ObjStore_S3
: public RGWDeleteMultiObj_ObjStore
{
489 RGWDeleteMultiObj_ObjStore_S3() {}
490 ~RGWDeleteMultiObj_ObjStore_S3() override
{}
492 int get_params(optional_yield y
) override
;
493 void send_status() override
;
494 void begin_response() override
;
495 void send_partial_response(rgw_obj_key
& key
, bool delete_marker
,
496 const string
& marker_version_id
, int ret
) override
;
497 void end_response() override
;
500 class RGWPutBucketObjectLock_ObjStore_S3
: public RGWPutBucketObjectLock_ObjStore
{
502 RGWPutBucketObjectLock_ObjStore_S3() {}
503 ~RGWPutBucketObjectLock_ObjStore_S3() override
{}
504 void send_response() override
;
507 class RGWGetBucketObjectLock_ObjStore_S3
: public RGWGetBucketObjectLock_ObjStore
{
509 RGWGetBucketObjectLock_ObjStore_S3() {}
510 ~RGWGetBucketObjectLock_ObjStore_S3() {}
511 void send_response() override
;
514 class RGWPutObjRetention_ObjStore_S3
: public RGWPutObjRetention_ObjStore
{
516 RGWPutObjRetention_ObjStore_S3() {}
517 ~RGWPutObjRetention_ObjStore_S3() {}
518 int get_params(optional_yield y
) override
;
519 void send_response() override
;
522 class RGWGetObjRetention_ObjStore_S3
: public RGWGetObjRetention_ObjStore
{
524 RGWGetObjRetention_ObjStore_S3() {}
525 ~RGWGetObjRetention_ObjStore_S3() {}
526 void send_response() override
;
529 class RGWPutObjLegalHold_ObjStore_S3
: public RGWPutObjLegalHold_ObjStore
{
531 RGWPutObjLegalHold_ObjStore_S3() {}
532 ~RGWPutObjLegalHold_ObjStore_S3() {}
533 void send_response() override
;
536 class RGWGetObjLegalHold_ObjStore_S3
: public RGWGetObjLegalHold_ObjStore
{
538 RGWGetObjLegalHold_ObjStore_S3() {}
539 ~RGWGetObjLegalHold_ObjStore_S3() {}
540 void send_response() override
;
543 class RGWGetObjLayout_ObjStore_S3
: public RGWGetObjLayout
{
545 RGWGetObjLayout_ObjStore_S3() {}
546 ~RGWGetObjLayout_ObjStore_S3() {}
548 void send_response() override
;
551 class RGWConfigBucketMetaSearch_ObjStore_S3
: public RGWConfigBucketMetaSearch
{
553 RGWConfigBucketMetaSearch_ObjStore_S3() {}
554 ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
556 int get_params(optional_yield y
) override
;
557 void send_response() override
;
560 class RGWGetBucketMetaSearch_ObjStore_S3
: public RGWGetBucketMetaSearch
{
562 RGWGetBucketMetaSearch_ObjStore_S3() {}
563 ~RGWGetBucketMetaSearch_ObjStore_S3() {}
565 void send_response() override
;
568 class RGWDelBucketMetaSearch_ObjStore_S3
: public RGWDelBucketMetaSearch
{
570 RGWDelBucketMetaSearch_ObjStore_S3() {}
571 ~RGWDelBucketMetaSearch_ObjStore_S3() {}
573 void send_response() override
;
576 class RGWGetBucketPolicyStatus_ObjStore_S3
: public RGWGetBucketPolicyStatus
{
578 void send_response() override
;
581 class RGWPutBucketPublicAccessBlock_ObjStore_S3
: public RGWPutBucketPublicAccessBlock
{
583 void send_response() override
;
586 class RGWGetBucketPublicAccessBlock_ObjStore_S3
: public RGWGetBucketPublicAccessBlock
{
588 void send_response() override
;
593 static int authorize(const DoutPrefixProvider
*dpp
,
594 rgw::sal::RGWRadosStore
*store
,
595 const rgw::auth::StrategyRegistry
& auth_registry
,
596 struct req_state
*s
, optional_yield y
);
599 class RGWHandler_Auth_S3
: public RGWHandler_REST
{
600 friend class RGWRESTMgr_S3
;
602 const rgw::auth::StrategyRegistry
& auth_registry
;
605 explicit RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry
& auth_registry
)
607 auth_registry(auth_registry
) {
609 ~RGWHandler_Auth_S3() override
= default;
611 static int validate_bucket_name(const string
& bucket
);
612 static int validate_object_name(const string
& bucket
);
614 int init(rgw::sal::RGWRadosStore
*store
,
616 rgw::io::BasicClient
*cio
) override
;
617 int authorize(const DoutPrefixProvider
*dpp
, optional_yield y
) override
{
618 return RGW_Auth_S3::authorize(dpp
, store
, auth_registry
, s
, y
);
620 int postauth_init(optional_yield
) override
{ return 0; }
623 class RGWHandler_REST_S3
: public RGWHandler_REST
{
624 friend class RGWRESTMgr_S3
;
626 const rgw::auth::StrategyRegistry
& auth_registry
;
628 static int init_from_header(rgw::sal::RGWRadosStore
*store
, struct req_state
*s
, int default_formatter
, bool configurable_format
);
630 explicit RGWHandler_REST_S3(const rgw::auth::StrategyRegistry
& auth_registry
)
632 auth_registry(auth_registry
) {
634 ~RGWHandler_REST_S3() override
= default;
636 int init(rgw::sal::RGWRadosStore
*store
,
638 rgw::io::BasicClient
*cio
) override
;
639 int authorize(const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
640 int postauth_init(optional_yield y
) override
;
643 class RGWHandler_REST_Service_S3
: public RGWHandler_REST_S3
{
645 const bool isSTSEnabled
;
646 const bool isIAMEnabled
;
647 const bool isPSEnabled
;
648 bool is_usage_op() const {
649 return s
->info
.args
.exists("usage");
651 RGWOp
*op_get() override
;
652 RGWOp
*op_head() override
;
653 RGWOp
*op_post() override
;
655 RGWHandler_REST_Service_S3(const rgw::auth::StrategyRegistry
& auth_registry
,
656 bool _isSTSEnabled
, bool _isIAMEnabled
, bool _isPSEnabled
) :
657 RGWHandler_REST_S3(auth_registry
), isSTSEnabled(_isSTSEnabled
), isIAMEnabled(_isIAMEnabled
), isPSEnabled(_isPSEnabled
) {}
658 ~RGWHandler_REST_Service_S3() override
= default;
661 class RGWHandler_REST_Bucket_S3
: public RGWHandler_REST_S3
{
662 const bool enable_pubsub
;
664 bool is_acl_op() const {
665 return s
->info
.args
.exists("acl");
667 bool is_cors_op() const {
668 return s
->info
.args
.exists("cors");
670 bool is_lc_op() const {
671 return s
->info
.args
.exists("lifecycle");
673 bool is_obj_update_op() const override
{
674 return is_acl_op() || is_cors_op();
676 bool is_tagging_op() const {
677 return s
->info
.args
.exists("tagging");
679 bool is_request_payment_op() const {
680 return s
->info
.args
.exists("requestPayment");
682 bool is_policy_op() const {
683 return s
->info
.args
.exists("policy");
685 bool is_object_lock_op() const {
686 return s
->info
.args
.exists("object-lock");
688 bool is_notification_op() const {
690 return s
->info
.args
.exists("notification");
694 bool is_replication_op() const {
695 return s
->info
.args
.exists("replication");
697 bool is_policy_status_op() {
698 return s
->info
.args
.exists("policyStatus");
700 bool is_block_public_access_op() {
701 return s
->info
.args
.exists("publicAccessBlock");
704 RGWOp
*get_obj_op(bool get_data
) const;
705 RGWOp
*op_get() override
;
706 RGWOp
*op_head() override
;
707 RGWOp
*op_put() override
;
708 RGWOp
*op_delete() override
;
709 RGWOp
*op_post() override
;
710 RGWOp
*op_options() override
;
712 RGWHandler_REST_Bucket_S3(const rgw::auth::StrategyRegistry
& auth_registry
, bool _enable_pubsub
) :
713 RGWHandler_REST_S3(auth_registry
), enable_pubsub(_enable_pubsub
) {}
714 ~RGWHandler_REST_Bucket_S3() override
= default;
717 class RGWHandler_REST_Obj_S3
: public RGWHandler_REST_S3
{
719 bool is_acl_op() const {
720 return s
->info
.args
.exists("acl");
722 bool is_tagging_op() const {
723 return s
->info
.args
.exists("tagging");
725 bool is_obj_retention_op() const {
726 return s
->info
.args
.exists("retention");
728 bool is_obj_legal_hold_op() const {
729 return s
->info
.args
.exists("legal-hold");
732 bool is_select_op() const {
733 return s
->info
.args
.exists("select-type");
736 bool is_obj_update_op() const override
{
737 return is_acl_op() || is_tagging_op() || is_obj_retention_op() || is_obj_legal_hold_op() || is_select_op();
739 RGWOp
*get_obj_op(bool get_data
);
741 RGWOp
*op_get() override
;
742 RGWOp
*op_head() override
;
743 RGWOp
*op_put() override
;
744 RGWOp
*op_delete() override
;
745 RGWOp
*op_post() override
;
746 RGWOp
*op_options() override
;
748 using RGWHandler_REST_S3::RGWHandler_REST_S3
;
749 ~RGWHandler_REST_Obj_S3() override
= default;
752 class RGWRESTMgr_S3
: public RGWRESTMgr
{
754 const bool enable_s3website
;
755 const bool enable_sts
;
756 const bool enable_iam
;
757 const bool enable_pubsub
;
759 explicit RGWRESTMgr_S3(bool _enable_s3website
=false, bool _enable_sts
=false, bool _enable_iam
=false, bool _enable_pubsub
=false)
760 : enable_s3website(_enable_s3website
),
761 enable_sts(_enable_sts
),
762 enable_iam(_enable_iam
),
763 enable_pubsub(_enable_pubsub
) {
766 ~RGWRESTMgr_S3() override
= default;
768 RGWHandler_REST
*get_handler(rgw::sal::RGWRadosStore
*store
,
770 const rgw::auth::StrategyRegistry
& auth_registry
,
771 const std::string
& frontend_prefix
) override
;
774 class RGWHandler_REST_Obj_S3Website
;
776 static inline bool looks_like_ip_address(const char *bucket
)
779 if (inet_pton(AF_INET6
, bucket
, static_cast<void*>(&a
)) == 1) {
783 bool expect_period
= false;
784 for (const char *b
= bucket
; *b
; ++b
) {
791 expect_period
= false;
793 else if (isdigit(*b
)) {
794 expect_period
= true;
800 return (num_periods
== 3);
803 inline int valid_s3_object_name(const string
& name
) {
804 if (name
.size() > 1024) {
805 return -ERR_INVALID_OBJECT_NAME
;
807 if (check_utf8(name
.c_str(), name
.size())) {
808 return -ERR_INVALID_OBJECT_NAME
;
813 inline int valid_s3_bucket_name(const string
& name
, bool relaxed
=false)
815 // This function enforces Amazon's spec for bucket names.
816 // (The requirements, not the recommendations.)
817 int len
= name
.size();
818 int max
= (relaxed
? 255 : 63);
822 return -ERR_INVALID_BUCKET_NAME
;
823 } else if (len
> max
) {
825 return -ERR_INVALID_BUCKET_NAME
;
828 // bucket names must start with a number or letter
829 if (!(isalpha(name
[0]) || isdigit(name
[0]))) {
831 return -ERR_INVALID_BUCKET_NAME
;
832 else if (!(name
[0] == '_' || name
[0] == '.' || name
[0] == '-'))
833 return -ERR_INVALID_BUCKET_NAME
;
836 // bucket names must end with a number or letter
837 if (!(isalpha(name
[len
-1]) || isdigit(name
[len
-1])))
839 return -ERR_INVALID_BUCKET_NAME
;
841 for (const char *s
= name
.c_str(); *s
; ++s
) {
847 // name cannot contain uppercase letters
848 if (relaxed
|| islower(c
))
853 // name cannot contain underscore
861 if (!relaxed
&& s
&& *s
) {
862 // name cannot have consecutive periods or dashes
863 // adjacent to periods
864 // ensure s is neither the first nor the last character
867 if ((p
!= '-') && (n
!= '.') && (n
!= '-'))
875 return -ERR_INVALID_BUCKET_NAME
;
878 if (looks_like_ip_address(name
.c_str()))
879 return -ERR_INVALID_BUCKET_NAME
;
884 namespace s3selectEngine
890 class RGWSelectObj_ObjStore_S3
: public RGWGetObj_ObjStore_S3
894 std::unique_ptr
<s3selectEngine::s3select
> s3select_syntax
;
895 std::string m_s3select_query
;
896 std::string m_result
;
897 std::unique_ptr
<s3selectEngine::csv_object
> m_s3_csv_object
;
898 std::string m_column_delimiter
;
900 std::string m_row_delimiter
;
901 std::string m_compression_type
;
902 std::string m_escape_char
;
903 std::unique_ptr
<char[]> m_buff_header
;
904 std::string m_header_info
;
905 std::string m_sql_query
;
908 unsigned int chunk_number
;
916 static const char* header_name_str
[3];
924 static const char* header_value_str
[3];
926 RGWSelectObj_ObjStore_S3();
927 virtual ~RGWSelectObj_ObjStore_S3();
929 virtual int send_response_data(bufferlist
& bl
, off_t ofs
, off_t len
) override
;
931 virtual int get_params(optional_yield y
) override
;
934 void encode_short(char* buff
, uint16_t s
, int& i
);
936 void encode_int(char* buff
, u_int32_t s
, int& i
);
938 int create_header_records(char* buff
);
940 std::unique_ptr
<boost::crc_32_type
> crc32
;
942 int create_message(std::string
&, u_int32_t result_len
, u_int32_t header_len
);
944 int run_s3select(const char* query
, const char* input
, size_t input_length
);
946 int extract_by_tag(std::string tag_name
, std::string
& result
);
948 void convert_escape_seq(std::string
& esc
);
950 int handle_aws_cli_parameters(std::string
& sql_query
);
954 namespace rgw::auth::s3
{
956 class AWSEngine
: public rgw::auth::Engine
{
958 class VersionAbstractor
{
959 static constexpr size_t DIGEST_SIZE_V2
= CEPH_CRYPTO_HMACSHA1_DIGESTSIZE
;
960 static constexpr size_t DIGEST_SIZE_V4
= CEPH_CRYPTO_HMACSHA256_DIGESTSIZE
;
962 /* Knowing the signature max size allows us to employ the sstring, and thus
963 * avoid dynamic allocations. The multiplier comes from representing digest
964 * in the base64-encoded form. */
965 static constexpr size_t SIGNATURE_MAX_SIZE
= \
966 std::max(DIGEST_SIZE_V2
, DIGEST_SIZE_V4
) * 2 + sizeof('\0');
969 virtual ~VersionAbstractor() {};
971 using access_key_id_t
= std::string_view
;
972 using client_signature_t
= std::string_view
;
973 using session_token_t
= std::string_view
;
974 using server_signature_t
= basic_sstring
<char, uint16_t, SIGNATURE_MAX_SIZE
>;
975 using string_to_sign_t
= std::string
;
977 /* Transformation for crafting the AWS signature at server side which is
978 * used later to compare with the user-provided one. The methodology for
979 * doing that depends on AWS auth version. */
980 using signature_factory_t
= \
981 std::function
<server_signature_t(CephContext
* cct
,
982 const std::string
& secret_key
,
983 const string_to_sign_t
& string_to_sign
)>;
985 /* Return an instance of Completer for verifying the payload's fingerprint
986 * if necessary. Otherwise caller gets nullptr. Caller may provide secret
988 using completer_factory_t
= \
989 std::function
<rgw::auth::Completer::cmplptr_t(
990 const boost::optional
<std::string
>& secret_key
)>;
993 access_key_id_t access_key_id
;
994 client_signature_t client_signature
;
995 session_token_t session_token
;
996 string_to_sign_t string_to_sign
;
997 signature_factory_t signature_factory
;
998 completer_factory_t completer_factory
;
1001 virtual auth_data_t
get_auth_data(const req_state
* s
) const = 0;
1006 const VersionAbstractor
& ver_abstractor
;
1008 AWSEngine(CephContext
* const cct
, const VersionAbstractor
& ver_abstractor
)
1010 ver_abstractor(ver_abstractor
) {
1013 using result_t
= rgw::auth::Engine::result_t
;
1014 using string_to_sign_t
= VersionAbstractor::string_to_sign_t
;
1015 using signature_factory_t
= VersionAbstractor::signature_factory_t
;
1016 using completer_factory_t
= VersionAbstractor::completer_factory_t
;
1018 /* TODO(rzarzynski): clean up. We've too many input parameter hee. Also
1019 * the signature get_auth_data() of VersionAbstractor is too complicated.
1020 * Replace these thing with a simple, dedicated structure. */
1021 virtual result_t
authenticate(const DoutPrefixProvider
* dpp
,
1022 const std::string_view
& access_key_id
,
1023 const std::string_view
& signature
,
1024 const std::string_view
& session_token
,
1025 const string_to_sign_t
& string_to_sign
,
1026 const signature_factory_t
& signature_factory
,
1027 const completer_factory_t
& completer_factory
,
1029 optional_yield y
) const = 0;
1032 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
,
1033 optional_yield y
) const final
;
1037 class AWSGeneralAbstractor
: public AWSEngine::VersionAbstractor
{
1038 CephContext
* const cct
;
1040 virtual boost::optional
<std::string
>
1041 get_v4_canonical_headers(const req_info
& info
,
1042 const std::string_view
& signedheaders
,
1043 const bool using_qs
) const;
1045 auth_data_t
get_auth_data_v2(const req_state
* s
) const;
1046 auth_data_t
get_auth_data_v4(const req_state
* s
, const bool using_qs
) const;
1049 explicit AWSGeneralAbstractor(CephContext
* const cct
)
1053 auth_data_t
get_auth_data(const req_state
* s
) const override
;
1056 class AWSGeneralBoto2Abstractor
: public AWSGeneralAbstractor
{
1057 boost::optional
<std::string
>
1058 get_v4_canonical_headers(const req_info
& info
,
1059 const std::string_view
& signedheaders
,
1060 const bool using_qs
) const override
;
1063 using AWSGeneralAbstractor::AWSGeneralAbstractor
;
1066 class AWSBrowserUploadAbstractor
: public AWSEngine::VersionAbstractor
{
1067 static std::string
to_string(ceph::bufferlist bl
) {
1068 return std::string(bl
.c_str(),
1069 static_cast<std::string::size_type
>(bl
.length()));
1072 auth_data_t
get_auth_data_v2(const req_state
* s
) const;
1073 auth_data_t
get_auth_data_v4(const req_state
* s
) const;
1076 explicit AWSBrowserUploadAbstractor(CephContext
*) {
1079 auth_data_t
get_auth_data(const req_state
* s
) const override
;
1083 class LDAPEngine
: public AWSEngine
{
1084 static rgw::LDAPHelper
* ldh
;
1085 static std::mutex mtx
;
1087 static void init(CephContext
* const cct
);
1089 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
1090 using auth_info_t
= rgw::auth::RemoteApplier::AuthInfo
;
1091 using result_t
= rgw::auth::Engine::result_t
;
1095 const rgw::auth::RemoteApplier::Factory
* const apl_factory
;
1097 acl_strategy_t
get_acl_strategy() const;
1098 auth_info_t
get_creds_info(const rgw::RGWToken
& token
) const noexcept
;
1100 result_t
authenticate(const DoutPrefixProvider
* dpp
,
1101 const std::string_view
& access_key_id
,
1102 const std::string_view
& signature
,
1103 const std::string_view
& session_token
,
1104 const string_to_sign_t
& string_to_sign
,
1105 const signature_factory_t
&,
1106 const completer_factory_t
& completer_factory
,
1108 optional_yield y
) const override
;
1110 LDAPEngine(CephContext
* const cct
,
1112 const VersionAbstractor
& ver_abstractor
,
1113 const rgw::auth::RemoteApplier::Factory
* const apl_factory
)
1114 : AWSEngine(cct
, ver_abstractor
),
1116 apl_factory(apl_factory
) {
1120 using AWSEngine::authenticate
;
1122 const char* get_name() const noexcept override
{
1123 return "rgw::auth::s3::LDAPEngine";
1126 static bool valid();
1127 static void shutdown();
1130 class LocalEngine
: public AWSEngine
{
1132 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
1134 result_t
authenticate(const DoutPrefixProvider
* dpp
,
1135 const std::string_view
& access_key_id
,
1136 const std::string_view
& signature
,
1137 const std::string_view
& session_token
,
1138 const string_to_sign_t
& string_to_sign
,
1139 const signature_factory_t
& signature_factory
,
1140 const completer_factory_t
& completer_factory
,
1142 optional_yield y
) const override
;
1144 LocalEngine(CephContext
* const cct
,
1146 const VersionAbstractor
& ver_abstractor
,
1147 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
1148 : AWSEngine(cct
, ver_abstractor
),
1150 apl_factory(apl_factory
) {
1153 using AWSEngine::authenticate
;
1155 const char* get_name() const noexcept override
{
1156 return "rgw::auth::s3::LocalEngine";
1160 class STSEngine
: public AWSEngine
{
1162 const rgw::auth::LocalApplier::Factory
* const local_apl_factory
;
1163 const rgw::auth::RemoteApplier::Factory
* const remote_apl_factory
;
1164 const rgw::auth::RoleApplier::Factory
* const role_apl_factory
;
1166 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
1167 using auth_info_t
= rgw::auth::RemoteApplier::AuthInfo
;
1169 acl_strategy_t
get_acl_strategy() const { return nullptr; };
1170 auth_info_t
get_creds_info(const STS::SessionToken
& token
) const noexcept
;
1172 int get_session_token(const DoutPrefixProvider
* dpp
, const std::string_view
& session_token
,
1173 STS::SessionToken
& token
) const;
1175 result_t
authenticate(const DoutPrefixProvider
* dpp
,
1176 const std::string_view
& access_key_id
,
1177 const std::string_view
& signature
,
1178 const std::string_view
& session_token
,
1179 const string_to_sign_t
& string_to_sign
,
1180 const signature_factory_t
& signature_factory
,
1181 const completer_factory_t
& completer_factory
,
1183 optional_yield y
) const override
;
1185 STSEngine(CephContext
* const cct
,
1187 const VersionAbstractor
& ver_abstractor
,
1188 const rgw::auth::LocalApplier::Factory
* const local_apl_factory
,
1189 const rgw::auth::RemoteApplier::Factory
* const remote_apl_factory
,
1190 const rgw::auth::RoleApplier::Factory
* const role_apl_factory
)
1191 : AWSEngine(cct
, ver_abstractor
),
1193 local_apl_factory(local_apl_factory
),
1194 remote_apl_factory(remote_apl_factory
),
1195 role_apl_factory(role_apl_factory
) {
1198 using AWSEngine::authenticate
;
1200 const char* get_name() const noexcept override
{
1201 return "rgw::auth::s3::STSEngine";
1205 class S3AnonymousEngine
: public rgw::auth::AnonymousEngine
{
1206 bool is_applicable(const req_state
* s
) const noexcept override
;
1209 /* Let's reuse the parent class' constructor. */
1210 using rgw::auth::AnonymousEngine::AnonymousEngine
;
1212 const char* get_name() const noexcept override
{
1213 return "rgw::auth::s3::S3AnonymousEngine";
1218 } // namespace rgw::auth::s3