1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab
4 #ifndef CEPH_RGW_REST_S3_H
6 #define CEPH_RGW_REST_S3_H
7 #define TIME_BUF_SIZE 128
11 #include <boost/utility/string_view.hpp>
12 #include <boost/container/static_vector.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
;
47 RGWGetObj_ObjStore_S3() {}
48 ~RGWGetObj_ObjStore_S3() override
{}
50 int get_params() override
;
51 int send_response_data_error() override
;
52 int send_response_data(bufferlist
& bl
, off_t ofs
, off_t len
) override
;
53 void set_custom_http_response(int http_ret
) { custom_http_ret
= http_ret
; }
54 int get_decrypt_filter(std::unique_ptr
<RGWGetObj_Filter
>* filter
,
56 bufferlist
* manifest_bl
) override
;
59 class RGWGetObjTags_ObjStore_S3
: public RGWGetObjTags_ObjStore
63 RGWGetObjTags_ObjStore_S3() {}
64 ~RGWGetObjTags_ObjStore_S3() {}
66 void send_response_data(bufferlist
&bl
) override
;
69 class RGWPutObjTags_ObjStore_S3
: public RGWPutObjTags_ObjStore
72 RGWPutObjTags_ObjStore_S3() {}
73 ~RGWPutObjTags_ObjStore_S3() {}
75 int get_params() override
;
76 void send_response() override
;
79 class RGWDeleteObjTags_ObjStore_S3
: public RGWDeleteObjTags
82 ~RGWDeleteObjTags_ObjStore_S3() override
{}
83 void send_response() override
;
86 class RGWListBuckets_ObjStore_S3
: public RGWListBuckets_ObjStore
{
88 RGWListBuckets_ObjStore_S3() {}
89 ~RGWListBuckets_ObjStore_S3() override
{}
91 int get_params() override
{
92 limit
= -1; /* no limit */
95 void send_response_begin(bool has_buckets
) override
;
96 void send_response_data(RGWUserBuckets
& buckets
) override
;
97 void send_response_end() override
;
100 class RGWGetUsage_ObjStore_S3
: public RGWGetUsage_ObjStore
{
102 RGWGetUsage_ObjStore_S3() {}
103 ~RGWGetUsage_ObjStore_S3() override
{}
105 int get_params() override
;
106 void send_response() override
;
109 class RGWListBucket_ObjStore_S3
: public RGWListBucket_ObjStore
{
110 protected: bool objs_container
;
111 int get_common_params();
112 void send_common_response();
113 void send_common_versioned_response();
115 RGWListBucket_ObjStore_S3() : objs_container(false) {
118 ~RGWListBucket_ObjStore_S3() override
{}
120 int get_params() override
;
121 void send_response() override
;
122 void send_versioned_response();
125 class RGWListBucket_ObjStore_S3v2
: public RGWListBucket_ObjStore_S3
{
127 bool start_after_exist
;
128 bool continuation_token_exist
;
130 string continuation_token
;
132 RGWListBucket_ObjStore_S3v2() : fetchOwner(false) {
134 ~RGWListBucket_ObjStore_S3v2() override
{}
136 int get_params() override
;
137 void send_response() override
;
138 void send_versioned_response();
141 class RGWGetBucketLogging_ObjStore_S3
: public RGWGetBucketLogging
{
143 RGWGetBucketLogging_ObjStore_S3() {}
144 ~RGWGetBucketLogging_ObjStore_S3() override
{}
146 void send_response() override
;
149 class RGWGetBucketLocation_ObjStore_S3
: public RGWGetBucketLocation
{
151 RGWGetBucketLocation_ObjStore_S3() {}
152 ~RGWGetBucketLocation_ObjStore_S3() override
{}
154 void send_response() override
;
157 class RGWGetBucketVersioning_ObjStore_S3
: public RGWGetBucketVersioning
{
159 RGWGetBucketVersioning_ObjStore_S3() {}
160 ~RGWGetBucketVersioning_ObjStore_S3() override
{}
162 void send_response() override
;
165 class RGWSetBucketVersioning_ObjStore_S3
: public RGWSetBucketVersioning
{
167 RGWSetBucketVersioning_ObjStore_S3() {}
168 ~RGWSetBucketVersioning_ObjStore_S3() override
{}
170 int get_params() override
;
171 void send_response() override
;
174 class RGWGetBucketWebsite_ObjStore_S3
: public RGWGetBucketWebsite
{
176 RGWGetBucketWebsite_ObjStore_S3() {}
177 ~RGWGetBucketWebsite_ObjStore_S3() override
{}
179 void send_response() override
;
182 class RGWSetBucketWebsite_ObjStore_S3
: public RGWSetBucketWebsite
{
184 RGWSetBucketWebsite_ObjStore_S3() {}
185 ~RGWSetBucketWebsite_ObjStore_S3() override
{}
187 int get_params() override
;
188 void send_response() override
;
191 class RGWDeleteBucketWebsite_ObjStore_S3
: public RGWDeleteBucketWebsite
{
193 RGWDeleteBucketWebsite_ObjStore_S3() {}
194 ~RGWDeleteBucketWebsite_ObjStore_S3() override
{}
196 void send_response() override
;
199 class RGWStatBucket_ObjStore_S3
: public RGWStatBucket_ObjStore
{
201 RGWStatBucket_ObjStore_S3() {}
202 ~RGWStatBucket_ObjStore_S3() override
{}
204 void send_response() override
;
207 class RGWCreateBucket_ObjStore_S3
: public RGWCreateBucket_ObjStore
{
209 RGWCreateBucket_ObjStore_S3() {}
210 ~RGWCreateBucket_ObjStore_S3() override
{}
212 int get_params() override
;
213 void send_response() override
;
216 class RGWDeleteBucket_ObjStore_S3
: public RGWDeleteBucket_ObjStore
{
218 RGWDeleteBucket_ObjStore_S3() {}
219 ~RGWDeleteBucket_ObjStore_S3() override
{}
221 void send_response() override
;
224 class RGWPutObj_ObjStore_S3
: public RGWPutObj_ObjStore
{
226 std::map
<std::string
, std::string
> crypt_http_responses
;
229 RGWPutObj_ObjStore_S3() {}
230 ~RGWPutObj_ObjStore_S3() override
{}
232 int get_params() override
;
233 int get_data(bufferlist
& bl
) override
;
234 void send_response() override
;
236 int get_encrypt_filter(std::unique_ptr
<rgw::putobj::DataProcessor
> *filter
,
237 rgw::putobj::DataProcessor
*cb
) override
;
238 int get_decrypt_filter(std::unique_ptr
<RGWGetObj_Filter
>* filter
,
239 RGWGetObj_Filter
* cb
,
240 map
<string
, bufferlist
>& attrs
,
241 bufferlist
* manifest_bl
) override
;
244 class RGWPostObj_ObjStore_S3
: public RGWPostObj_ObjStore
{
245 parts_collection_t parts
;
246 std::string filename
;
247 std::string content_type
;
249 RGWPolicy post_policy
;
250 map
<string
, string
> crypt_http_responses
;
252 const rgw::auth::StrategyRegistry
* auth_registry_ptr
= nullptr;
256 void rebuild_key(string
& key
);
258 std::string
get_current_filename() const override
;
259 std::string
get_current_content_type() const override
;
262 RGWPostObj_ObjStore_S3() {}
263 ~RGWPostObj_ObjStore_S3() override
{}
265 int verify_requester(const rgw::auth::StrategyRegistry
& auth_registry
) override
{
266 auth_registry_ptr
= &auth_registry
;
267 return RGWPostObj_ObjStore::verify_requester(auth_registry
);
270 int get_params() override
;
271 int complete_get_params();
273 void send_response() override
;
274 int get_data(ceph::bufferlist
& bl
, bool& again
) override
;
275 int get_encrypt_filter(std::unique_ptr
<rgw::putobj::DataProcessor
> *filter
,
276 rgw::putobj::DataProcessor
*cb
) override
;
279 class RGWDeleteObj_ObjStore_S3
: public RGWDeleteObj_ObjStore
{
281 RGWDeleteObj_ObjStore_S3() {}
282 ~RGWDeleteObj_ObjStore_S3() override
{}
284 int get_params() override
;
285 void send_response() override
;
288 class RGWCopyObj_ObjStore_S3
: public RGWCopyObj_ObjStore
{
291 RGWCopyObj_ObjStore_S3() : sent_header(false) {}
292 ~RGWCopyObj_ObjStore_S3() override
{}
294 int init_dest_policy() override
;
295 int get_params() override
;
296 int check_storage_class(const rgw_placement_rule
& src_placement
);
297 void send_partial_response(off_t ofs
) override
;
298 void send_response() override
;
301 class RGWGetACLs_ObjStore_S3
: public RGWGetACLs_ObjStore
{
303 RGWGetACLs_ObjStore_S3() {}
304 ~RGWGetACLs_ObjStore_S3() override
{}
306 void send_response() override
;
309 class RGWPutACLs_ObjStore_S3
: public RGWPutACLs_ObjStore
{
311 RGWPutACLs_ObjStore_S3() {}
312 ~RGWPutACLs_ObjStore_S3() override
{}
314 int get_policy_from_state(RGWRados
*store
, struct req_state
*s
, stringstream
& ss
) override
;
315 void send_response() override
;
316 int get_params() override
;
319 class RGWGetLC_ObjStore_S3
: public RGWGetLC_ObjStore
{
321 RGWLifecycleConfiguration_S3 config
;
323 RGWGetLC_ObjStore_S3() {}
324 ~RGWGetLC_ObjStore_S3() override
{}
325 void execute() override
;
327 void send_response() override
;
330 class RGWPutLC_ObjStore_S3
: public RGWPutLC_ObjStore
{
332 RGWPutLC_ObjStore_S3() {}
333 ~RGWPutLC_ObjStore_S3() override
{}
335 void send_response() override
;
338 class RGWDeleteLC_ObjStore_S3
: public RGWDeleteLC_ObjStore
{
340 RGWDeleteLC_ObjStore_S3() {}
341 ~RGWDeleteLC_ObjStore_S3() override
{}
343 void send_response() override
;
346 class RGWGetCORS_ObjStore_S3
: public RGWGetCORS_ObjStore
{
348 RGWGetCORS_ObjStore_S3() {}
349 ~RGWGetCORS_ObjStore_S3() override
{}
351 void send_response() override
;
354 class RGWPutCORS_ObjStore_S3
: public RGWPutCORS_ObjStore
{
356 RGWPutCORS_ObjStore_S3() {}
357 ~RGWPutCORS_ObjStore_S3() override
{}
359 int get_params() override
;
360 void send_response() override
;
363 class RGWDeleteCORS_ObjStore_S3
: public RGWDeleteCORS_ObjStore
{
365 RGWDeleteCORS_ObjStore_S3() {}
366 ~RGWDeleteCORS_ObjStore_S3() override
{}
368 void send_response() override
;
371 class RGWOptionsCORS_ObjStore_S3
: public RGWOptionsCORS_ObjStore
{
373 RGWOptionsCORS_ObjStore_S3() {}
374 ~RGWOptionsCORS_ObjStore_S3() override
{}
376 void send_response() override
;
379 class RGWGetRequestPayment_ObjStore_S3
: public RGWGetRequestPayment
{
381 RGWGetRequestPayment_ObjStore_S3() {}
382 ~RGWGetRequestPayment_ObjStore_S3() override
{}
384 void send_response() override
;
387 class RGWSetRequestPayment_ObjStore_S3
: public RGWSetRequestPayment
{
389 RGWSetRequestPayment_ObjStore_S3() {}
390 ~RGWSetRequestPayment_ObjStore_S3() override
{}
392 int get_params() override
;
393 void send_response() override
;
396 class RGWInitMultipart_ObjStore_S3
: public RGWInitMultipart_ObjStore
{
398 std::map
<std::string
, std::string
> crypt_http_responses
;
400 RGWInitMultipart_ObjStore_S3() {}
401 ~RGWInitMultipart_ObjStore_S3() override
{}
403 int get_params() override
;
404 void send_response() override
;
405 int prepare_encryption(map
<string
, bufferlist
>& attrs
) override
;
408 class RGWCompleteMultipart_ObjStore_S3
: public RGWCompleteMultipart_ObjStore
{
410 RGWCompleteMultipart_ObjStore_S3() {}
411 ~RGWCompleteMultipart_ObjStore_S3() override
{}
413 int get_params() override
;
414 void send_response() override
;
417 class RGWAbortMultipart_ObjStore_S3
: public RGWAbortMultipart_ObjStore
{
419 RGWAbortMultipart_ObjStore_S3() {}
420 ~RGWAbortMultipart_ObjStore_S3() override
{}
422 void send_response() override
;
425 class RGWListMultipart_ObjStore_S3
: public RGWListMultipart_ObjStore
{
427 RGWListMultipart_ObjStore_S3() {}
428 ~RGWListMultipart_ObjStore_S3() override
{}
430 void send_response() override
;
433 class RGWListBucketMultiparts_ObjStore_S3
: public RGWListBucketMultiparts_ObjStore
{
435 RGWListBucketMultiparts_ObjStore_S3() {
438 ~RGWListBucketMultiparts_ObjStore_S3() override
{}
440 void send_response() override
;
443 class RGWDeleteMultiObj_ObjStore_S3
: public RGWDeleteMultiObj_ObjStore
{
445 RGWDeleteMultiObj_ObjStore_S3() {}
446 ~RGWDeleteMultiObj_ObjStore_S3() override
{}
448 int get_params() override
;
449 void send_status() override
;
450 void begin_response() override
;
451 void send_partial_response(rgw_obj_key
& key
, bool delete_marker
,
452 const string
& marker_version_id
, int ret
) override
;
453 void end_response() override
;
456 class RGWPutBucketObjectLock_ObjStore_S3
: public RGWPutBucketObjectLock_ObjStore
{
458 RGWPutBucketObjectLock_ObjStore_S3() {}
459 ~RGWPutBucketObjectLock_ObjStore_S3() override
{}
460 void send_response() override
;
463 class RGWGetBucketObjectLock_ObjStore_S3
: public RGWGetBucketObjectLock_ObjStore
{
465 RGWGetBucketObjectLock_ObjStore_S3() {}
466 ~RGWGetBucketObjectLock_ObjStore_S3() {}
467 void send_response() override
;
470 class RGWPutObjRetention_ObjStore_S3
: public RGWPutObjRetention_ObjStore
{
472 RGWPutObjRetention_ObjStore_S3() {}
473 ~RGWPutObjRetention_ObjStore_S3() {}
474 int get_params() override
;
475 void send_response() override
;
478 class RGWGetObjRetention_ObjStore_S3
: public RGWGetObjRetention_ObjStore
{
480 RGWGetObjRetention_ObjStore_S3() {}
481 ~RGWGetObjRetention_ObjStore_S3() {}
482 void send_response() override
;
485 class RGWPutObjLegalHold_ObjStore_S3
: public RGWPutObjLegalHold_ObjStore
{
487 RGWPutObjLegalHold_ObjStore_S3() {}
488 ~RGWPutObjLegalHold_ObjStore_S3() {}
489 void send_response() override
;
492 class RGWGetObjLegalHold_ObjStore_S3
: public RGWGetObjLegalHold_ObjStore
{
494 RGWGetObjLegalHold_ObjStore_S3() {}
495 ~RGWGetObjLegalHold_ObjStore_S3() {}
496 void send_response() override
;
499 class RGWGetObjLayout_ObjStore_S3
: public RGWGetObjLayout
{
501 RGWGetObjLayout_ObjStore_S3() {}
502 ~RGWGetObjLayout_ObjStore_S3() {}
504 void send_response() override
;
507 class RGWConfigBucketMetaSearch_ObjStore_S3
: public RGWConfigBucketMetaSearch
{
509 RGWConfigBucketMetaSearch_ObjStore_S3() {}
510 ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
512 int get_params() override
;
513 void send_response() override
;
516 class RGWGetBucketMetaSearch_ObjStore_S3
: public RGWGetBucketMetaSearch
{
518 RGWGetBucketMetaSearch_ObjStore_S3() {}
519 ~RGWGetBucketMetaSearch_ObjStore_S3() {}
521 void send_response() override
;
524 class RGWDelBucketMetaSearch_ObjStore_S3
: public RGWDelBucketMetaSearch
{
526 RGWDelBucketMetaSearch_ObjStore_S3() {}
527 ~RGWDelBucketMetaSearch_ObjStore_S3() {}
529 void send_response() override
;
534 static int authorize(const DoutPrefixProvider
*dpp
,
536 const rgw::auth::StrategyRegistry
& auth_registry
,
537 struct req_state
*s
);
540 class RGWHandler_Auth_S3
: public RGWHandler_REST
{
541 friend class RGWRESTMgr_S3
;
543 const rgw::auth::StrategyRegistry
& auth_registry
;
546 explicit RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry
& auth_registry
)
548 auth_registry(auth_registry
) {
550 ~RGWHandler_Auth_S3() override
= default;
552 static int validate_bucket_name(const string
& bucket
);
553 static int validate_object_name(const string
& bucket
);
555 int init(RGWRados
*store
,
557 rgw::io::BasicClient
*cio
) override
;
558 int authorize(const DoutPrefixProvider
*dpp
) override
{
559 return RGW_Auth_S3::authorize(dpp
, store
, auth_registry
, s
);
561 int postauth_init() override
{ return 0; }
564 class RGWHandler_REST_S3
: public RGWHandler_REST
{
565 friend class RGWRESTMgr_S3
;
567 const rgw::auth::StrategyRegistry
& auth_registry
;
569 static int init_from_header(struct req_state
*s
, int default_formatter
, bool configurable_format
);
571 explicit RGWHandler_REST_S3(const rgw::auth::StrategyRegistry
& auth_registry
)
573 auth_registry(auth_registry
) {
575 ~RGWHandler_REST_S3() override
= default;
577 int init(RGWRados
*store
,
579 rgw::io::BasicClient
*cio
) override
;
580 int authorize(const DoutPrefixProvider
*dpp
) override
;
581 int postauth_init() override
;
584 class RGWHandler_REST_Service_S3
: public RGWHandler_REST_S3
{
586 const bool isSTSenabled
;
587 const bool isPSenabled
;
589 return s
->info
.args
.exists("usage");
591 RGWOp
*op_get() override
;
592 RGWOp
*op_head() override
;
593 RGWOp
*op_post() override
;
595 RGWHandler_REST_Service_S3(const rgw::auth::StrategyRegistry
& auth_registry
,
596 bool _isSTSenabled
, bool _isPSenabled
) :
597 RGWHandler_REST_S3(auth_registry
), isSTSenabled(_isSTSenabled
), isPSenabled(_isPSenabled
) {}
598 ~RGWHandler_REST_Service_S3() override
= default;
601 class RGWHandler_REST_Bucket_S3
: public RGWHandler_REST_S3
{
602 const bool enable_pubsub
;
605 return s
->info
.args
.exists("acl");
608 return s
->info
.args
.exists("cors");
611 return s
->info
.args
.exists("lifecycle");
613 bool is_obj_update_op() override
{
614 return is_acl_op() || is_cors_op();
616 bool is_request_payment_op() {
617 return s
->info
.args
.exists("requestPayment");
619 bool is_policy_op() {
620 return s
->info
.args
.exists("policy");
622 bool is_object_lock_op() {
623 return s
->info
.args
.exists("object-lock");
625 bool is_notification_op() const {
627 return s
->info
.args
.exists("notification");
631 RGWOp
*get_obj_op(bool get_data
);
633 RGWOp
*op_get() override
;
634 RGWOp
*op_head() override
;
635 RGWOp
*op_put() override
;
636 RGWOp
*op_delete() override
;
637 RGWOp
*op_post() override
;
638 RGWOp
*op_options() override
;
640 RGWHandler_REST_Bucket_S3(const rgw::auth::StrategyRegistry
& auth_registry
, bool _enable_pubsub
) :
641 RGWHandler_REST_S3(auth_registry
), enable_pubsub(_enable_pubsub
) {}
642 ~RGWHandler_REST_Bucket_S3() override
= default;
645 class RGWHandler_REST_Obj_S3
: public RGWHandler_REST_S3
{
648 return s
->info
.args
.exists("acl");
650 bool is_tagging_op() {
651 return s
->info
.args
.exists("tagging");
653 bool is_obj_retention_op() {
654 return s
->info
.args
.exists("retention");
656 bool is_obj_legal_hold_op() {
657 return s
->info
.args
.exists("legal-hold");
660 bool is_obj_update_op() override
{
661 return is_acl_op() || is_tagging_op() || is_obj_retention_op() || is_obj_legal_hold_op();
663 RGWOp
*get_obj_op(bool get_data
);
665 RGWOp
*op_get() override
;
666 RGWOp
*op_head() override
;
667 RGWOp
*op_put() override
;
668 RGWOp
*op_delete() override
;
669 RGWOp
*op_post() override
;
670 RGWOp
*op_options() override
;
672 using RGWHandler_REST_S3::RGWHandler_REST_S3
;
673 ~RGWHandler_REST_Obj_S3() override
= default;
676 class RGWRESTMgr_S3
: public RGWRESTMgr
{
678 bool enable_s3website
;
680 const bool enable_pubsub
;
682 explicit RGWRESTMgr_S3(bool enable_s3website
= false, bool enable_sts
= false, bool _enable_pubsub
= false)
683 : enable_s3website(enable_s3website
),
684 enable_sts(enable_sts
),
685 enable_pubsub(_enable_pubsub
) {
688 ~RGWRESTMgr_S3() override
= default;
690 RGWHandler_REST
*get_handler(struct req_state
* s
,
691 const rgw::auth::StrategyRegistry
& auth_registry
,
692 const std::string
& frontend_prefix
) override
;
695 class RGWHandler_REST_Obj_S3Website
;
697 static inline bool looks_like_ip_address(const char *bucket
)
700 bool expect_period
= false;
701 for (const char *b
= bucket
; *b
; ++b
) {
708 expect_period
= false;
710 else if (isdigit(*b
)) {
711 expect_period
= true;
717 return (num_periods
== 3);
720 static inline int valid_s3_object_name(const string
& name
) {
721 if (name
.size() > 1024) {
722 return -ERR_INVALID_OBJECT_NAME
;
724 if (check_utf8(name
.c_str(), name
.size())) {
725 return -ERR_INVALID_OBJECT_NAME
;
730 static inline int valid_s3_bucket_name(const string
& name
, bool relaxed
=false)
732 // This function enforces Amazon's spec for bucket names.
733 // (The requirements, not the recommendations.)
734 int len
= name
.size();
737 return -ERR_INVALID_BUCKET_NAME
;
738 } else if (len
> 255) {
740 return -ERR_INVALID_BUCKET_NAME
;
743 // bucket names must start with a number, letter, or underscore
744 if (!(isalpha(name
[0]) || isdigit(name
[0]))) {
746 return -ERR_INVALID_BUCKET_NAME
;
747 else if (!(name
[0] == '_' || name
[0] == '.' || name
[0] == '-'))
748 return -ERR_INVALID_BUCKET_NAME
;
751 for (const char *s
= name
.c_str(); *s
; ++s
) {
753 if (isdigit(c
) || (c
== '.'))
757 if ((c
== '-') || (c
== '_'))
760 return -ERR_INVALID_BUCKET_NAME
;
763 if (looks_like_ip_address(name
.c_str()))
764 return -ERR_INVALID_BUCKET_NAME
;
774 class AWSEngine
: public rgw::auth::Engine
{
776 class VersionAbstractor
{
777 static constexpr size_t DIGEST_SIZE_V2
= CEPH_CRYPTO_HMACSHA1_DIGESTSIZE
;
778 static constexpr size_t DIGEST_SIZE_V4
= CEPH_CRYPTO_HMACSHA256_DIGESTSIZE
;
780 /* Knowing the signature max size allows us to employ the sstring, and thus
781 * avoid dynamic allocations. The multiplier comes from representing digest
782 * in the base64-encoded form. */
783 static constexpr size_t SIGNATURE_MAX_SIZE
= \
784 std::max(DIGEST_SIZE_V2
, DIGEST_SIZE_V4
) * 2 + sizeof('\0');
787 virtual ~VersionAbstractor() {};
789 using access_key_id_t
= boost::string_view
;
790 using client_signature_t
= boost::string_view
;
791 using session_token_t
= boost::string_view
;
792 using server_signature_t
= basic_sstring
<char, uint16_t, SIGNATURE_MAX_SIZE
>;
793 using string_to_sign_t
= std::string
;
795 /* Transformation for crafting the AWS signature at server side which is
796 * used later to compare with the user-provided one. The methodology for
797 * doing that depends on AWS auth version. */
798 using signature_factory_t
= \
799 std::function
<server_signature_t(CephContext
* cct
,
800 const std::string
& secret_key
,
801 const string_to_sign_t
& string_to_sign
)>;
803 /* Return an instance of Completer for verifying the payload's fingerprint
804 * if necessary. Otherwise caller gets nullptr. Caller may provide secret
806 using completer_factory_t
= \
807 std::function
<rgw::auth::Completer::cmplptr_t(
808 const boost::optional
<std::string
>& secret_key
)>;
811 access_key_id_t access_key_id
;
812 client_signature_t client_signature
;
813 session_token_t session_token
;
814 string_to_sign_t string_to_sign
;
815 signature_factory_t signature_factory
;
816 completer_factory_t completer_factory
;
819 virtual auth_data_t
get_auth_data(const req_state
* s
) const = 0;
824 const VersionAbstractor
& ver_abstractor
;
826 AWSEngine(CephContext
* const cct
, const VersionAbstractor
& ver_abstractor
)
828 ver_abstractor(ver_abstractor
) {
831 using result_t
= rgw::auth::Engine::result_t
;
832 using string_to_sign_t
= VersionAbstractor::string_to_sign_t
;
833 using signature_factory_t
= VersionAbstractor::signature_factory_t
;
834 using completer_factory_t
= VersionAbstractor::completer_factory_t
;
836 /* TODO(rzarzynski): clean up. We've too many input parameter hee. Also
837 * the signature get_auth_data() of VersionAbstractor is too complicated.
838 * Replace these thing with a simple, dedicated structure. */
839 virtual result_t
authenticate(const DoutPrefixProvider
* dpp
,
840 const boost::string_view
& access_key_id
,
841 const boost::string_view
& signature
,
842 const boost::string_view
& session_token
,
843 const string_to_sign_t
& string_to_sign
,
844 const signature_factory_t
& signature_factory
,
845 const completer_factory_t
& completer_factory
,
846 const req_state
* s
) const = 0;
849 result_t
authenticate(const DoutPrefixProvider
* dpp
, const req_state
* const s
) const final
;
853 class AWSGeneralAbstractor
: public AWSEngine::VersionAbstractor
{
854 CephContext
* const cct
;
856 virtual boost::optional
<std::string
>
857 get_v4_canonical_headers(const req_info
& info
,
858 const boost::string_view
& signedheaders
,
859 const bool using_qs
) const;
861 auth_data_t
get_auth_data_v2(const req_state
* s
) const;
862 auth_data_t
get_auth_data_v4(const req_state
* s
, const bool using_qs
) const;
865 explicit AWSGeneralAbstractor(CephContext
* const cct
)
869 auth_data_t
get_auth_data(const req_state
* s
) const override
;
872 class AWSGeneralBoto2Abstractor
: public AWSGeneralAbstractor
{
873 boost::optional
<std::string
>
874 get_v4_canonical_headers(const req_info
& info
,
875 const boost::string_view
& signedheaders
,
876 const bool using_qs
) const override
;
879 using AWSGeneralAbstractor::AWSGeneralAbstractor
;
882 class AWSBrowserUploadAbstractor
: public AWSEngine::VersionAbstractor
{
883 static std::string
to_string(ceph::bufferlist bl
) {
884 return std::string(bl
.c_str(),
885 static_cast<std::string::size_type
>(bl
.length()));
888 auth_data_t
get_auth_data_v2(const req_state
* s
) const;
889 auth_data_t
get_auth_data_v4(const req_state
* s
) const;
892 explicit AWSBrowserUploadAbstractor(CephContext
*) {
895 auth_data_t
get_auth_data(const req_state
* s
) const override
;
899 class LDAPEngine
: public AWSEngine
{
900 static rgw::LDAPHelper
* ldh
;
901 static std::mutex mtx
;
903 static void init(CephContext
* const cct
);
905 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
906 using auth_info_t
= rgw::auth::RemoteApplier::AuthInfo
;
907 using result_t
= rgw::auth::Engine::result_t
;
910 RGWRados
* const store
;
911 const rgw::auth::RemoteApplier::Factory
* const apl_factory
;
913 acl_strategy_t
get_acl_strategy() const;
914 auth_info_t
get_creds_info(const rgw::RGWToken
& token
) const noexcept
;
916 result_t
authenticate(const DoutPrefixProvider
* dpp
,
917 const boost::string_view
& access_key_id
,
918 const boost::string_view
& signature
,
919 const boost::string_view
& session_token
,
920 const string_to_sign_t
& string_to_sign
,
921 const signature_factory_t
&,
922 const completer_factory_t
& completer_factory
,
923 const req_state
* s
) const override
;
925 LDAPEngine(CephContext
* const cct
,
926 RGWRados
* const store
,
927 const VersionAbstractor
& ver_abstractor
,
928 const rgw::auth::RemoteApplier::Factory
* const apl_factory
)
929 : AWSEngine(cct
, ver_abstractor
),
931 apl_factory(apl_factory
) {
935 using AWSEngine::authenticate
;
937 const char* get_name() const noexcept override
{
938 return "rgw::auth::s3::LDAPEngine";
942 static void shutdown();
945 class LocalEngine
: public AWSEngine
{
946 RGWRados
* const store
;
947 const rgw::auth::LocalApplier::Factory
* const apl_factory
;
949 result_t
authenticate(const DoutPrefixProvider
* dpp
,
950 const boost::string_view
& access_key_id
,
951 const boost::string_view
& signature
,
952 const boost::string_view
& session_token
,
953 const string_to_sign_t
& string_to_sign
,
954 const signature_factory_t
& signature_factory
,
955 const completer_factory_t
& completer_factory
,
956 const req_state
* s
) const override
;
958 LocalEngine(CephContext
* const cct
,
959 RGWRados
* const store
,
960 const VersionAbstractor
& ver_abstractor
,
961 const rgw::auth::LocalApplier::Factory
* const apl_factory
)
962 : AWSEngine(cct
, ver_abstractor
),
964 apl_factory(apl_factory
) {
967 using AWSEngine::authenticate
;
969 const char* get_name() const noexcept override
{
970 return "rgw::auth::s3::LocalEngine";
974 class STSEngine
: public AWSEngine
{
975 RGWRados
* const store
;
976 const rgw::auth::LocalApplier::Factory
* const local_apl_factory
;
977 const rgw::auth::RemoteApplier::Factory
* const remote_apl_factory
;
978 const rgw::auth::RoleApplier::Factory
* const role_apl_factory
;
980 using acl_strategy_t
= rgw::auth::RemoteApplier::acl_strategy_t
;
981 using auth_info_t
= rgw::auth::RemoteApplier::AuthInfo
;
983 acl_strategy_t
get_acl_strategy() const { return nullptr; };
984 auth_info_t
get_creds_info(const STS::SessionToken
& token
) const noexcept
;
986 int get_session_token(const boost::string_view
& session_token
,
987 STS::SessionToken
& token
) const;
989 result_t
authenticate(const DoutPrefixProvider
* dpp
,
990 const boost::string_view
& access_key_id
,
991 const boost::string_view
& signature
,
992 const boost::string_view
& session_token
,
993 const string_to_sign_t
& string_to_sign
,
994 const signature_factory_t
& signature_factory
,
995 const completer_factory_t
& completer_factory
,
996 const req_state
* s
) const override
;
998 STSEngine(CephContext
* const cct
,
999 RGWRados
* const store
,
1000 const VersionAbstractor
& ver_abstractor
,
1001 const rgw::auth::LocalApplier::Factory
* const local_apl_factory
,
1002 const rgw::auth::RemoteApplier::Factory
* const remote_apl_factory
,
1003 const rgw::auth::RoleApplier::Factory
* const role_apl_factory
)
1004 : AWSEngine(cct
, ver_abstractor
),
1006 local_apl_factory(local_apl_factory
),
1007 remote_apl_factory(remote_apl_factory
),
1008 role_apl_factory(role_apl_factory
) {
1011 using AWSEngine::authenticate
;
1013 const char* get_name() const noexcept override
{
1014 return "rgw::auth::s3::STSEngine";
1018 class S3AnonymousEngine
: public rgw::auth::AnonymousEngine
{
1019 bool is_applicable(const req_state
* s
) const noexcept override
;
1022 /* Let's reuse the parent class' constructor. */
1023 using rgw::auth::AnonymousEngine::AnonymousEngine
;
1025 const char* get_name() const noexcept override
{
1026 return "rgw::auth::s3::S3AnonymousEngine";
1031 class S3AuthFactory
: public rgw::auth::RemoteApplier::Factory
,
1032 public rgw::auth::LocalApplier::Factory
{
1033 typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t
;
1034 RGWRados
* const store
;
1037 explicit S3AuthFactory(RGWRados
* const store
)
1041 aplptr_t
create_apl_remote(CephContext
* const cct
,
1042 const req_state
* const s
,
1043 rgw::auth::RemoteApplier::acl_strategy_t
&& acl_alg
,
1044 const rgw::auth::RemoteApplier::AuthInfo
&info
1047 new rgw::auth::RemoteApplier(cct
, store
, std::move(acl_alg
), info
,
1048 cct
->_conf
->rgw_keystone_implicit_tenants
));
1051 aplptr_t
create_apl_local(CephContext
* const cct
,
1052 const req_state
* const s
,
1053 const RGWUserInfo
& user_info
,
1054 const std::string
& subuser
,
1055 const boost::optional
<uint32_t>& perm_mask
) const override
{
1057 new rgw::auth::LocalApplier(cct
, user_info
, subuser
, perm_mask
));
1062 } /* namespace s3 */
1063 } /* namespace auth */
1064 } /* namespace rgw */
1067 #endif /* CEPH_RGW_REST_S3_H */