1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
5 #define TIME_BUF_SIZE 128
9 #include <boost/optional.hpp>
10 #include <boost/utility/typed_in_place_factory.hpp>
14 #include "rgw_swift_auth.h"
15 #include "rgw_http_errors.h"
18 class RGWGetObj_ObjStore_SWIFT
: public RGWGetObj_ObjStore
{
19 int custom_http_ret
= 0;
21 RGWGetObj_ObjStore_SWIFT() {}
22 ~RGWGetObj_ObjStore_SWIFT() override
{}
24 int verify_permission(optional_yield y
) override
;
25 int get_params(optional_yield y
) override
;
26 int send_response_data_error(optional_yield y
) override
;
27 int send_response_data(bufferlist
& bl
, off_t ofs
, off_t len
) override
;
29 void set_custom_http_response(const int http_ret
) {
30 custom_http_ret
= http_ret
;
33 bool need_object_expiration() override
{
38 class RGWListBuckets_ObjStore_SWIFT
: public RGWListBuckets_ObjStore
{
42 std::vector
<rgw::sal::BucketList
> reverse_buffer
;
44 uint64_t get_default_max() const override
{
49 RGWListBuckets_ObjStore_SWIFT()
51 wants_reversed(false) {
53 ~RGWListBuckets_ObjStore_SWIFT() override
{}
55 int get_params(optional_yield y
) override
;
56 void handle_listing_chunk(rgw::sal::BucketList
&& buckets
) override
;
57 void send_response_begin(bool has_buckets
) override
;
58 void send_response_data(rgw::sal::BucketList
& buckets
) override
;
59 void send_response_data_reversed(rgw::sal::BucketList
& buckets
);
60 void dump_bucket_entry(const rgw::sal::Bucket
& obj
);
61 void send_response_end() override
;
63 bool should_get_stats() override
{ return need_stats
; }
64 bool supports_account_metadata() override
{ return true; }
67 class RGWListBucket_ObjStore_SWIFT
: public RGWListBucket_ObjStore
{
70 RGWListBucket_ObjStore_SWIFT() {
73 ~RGWListBucket_ObjStore_SWIFT() override
{}
75 int get_params(optional_yield y
) override
;
76 void send_response() override
;
77 bool need_container_stats() override
{ return true; }
80 class RGWStatAccount_ObjStore_SWIFT
: public RGWStatAccount_ObjStore
{
81 std::map
<std::string
, bufferlist
> attrs
;
83 RGWStatAccount_ObjStore_SWIFT() {
85 ~RGWStatAccount_ObjStore_SWIFT() override
{}
87 void execute(optional_yield y
) override
;
88 void send_response() override
;
91 class RGWStatBucket_ObjStore_SWIFT
: public RGWStatBucket_ObjStore
{
93 RGWStatBucket_ObjStore_SWIFT() {}
94 ~RGWStatBucket_ObjStore_SWIFT() override
{}
96 void send_response() override
;
99 class RGWCreateBucket_ObjStore_SWIFT
: public RGWCreateBucket_ObjStore
{
101 bool need_metadata_upload() const override
{ return true; }
103 RGWCreateBucket_ObjStore_SWIFT() {}
104 ~RGWCreateBucket_ObjStore_SWIFT() override
{}
106 int get_params(optional_yield y
) override
;
107 void send_response() override
;
110 class RGWDeleteBucket_ObjStore_SWIFT
: public RGWDeleteBucket_ObjStore
{
112 RGWDeleteBucket_ObjStore_SWIFT() {}
113 ~RGWDeleteBucket_ObjStore_SWIFT() override
{}
115 void send_response() override
;
118 class RGWPutObj_ObjStore_SWIFT
: public RGWPutObj_ObjStore
{
121 RGWPutObj_ObjStore_SWIFT() {}
122 ~RGWPutObj_ObjStore_SWIFT() override
{}
124 int update_slo_segment_size(rgw_slo_entry
& entry
);
126 int verify_permission(optional_yield y
) override
;
127 int get_params(optional_yield y
) override
;
128 void send_response() override
;
131 class RGWPutMetadataAccount_ObjStore_SWIFT
: public RGWPutMetadataAccount_ObjStore
{
133 RGWPutMetadataAccount_ObjStore_SWIFT() {}
134 ~RGWPutMetadataAccount_ObjStore_SWIFT() override
{}
136 int get_params(optional_yield y
) override
;
137 void send_response() override
;
140 class RGWPutMetadataBucket_ObjStore_SWIFT
: public RGWPutMetadataBucket_ObjStore
{
142 RGWPutMetadataBucket_ObjStore_SWIFT() {}
143 ~RGWPutMetadataBucket_ObjStore_SWIFT() override
{}
145 int get_params(optional_yield y
) override
;
146 void send_response() override
;
149 class RGWPutMetadataObject_ObjStore_SWIFT
: public RGWPutMetadataObject_ObjStore
{
151 RGWPutMetadataObject_ObjStore_SWIFT() {}
152 ~RGWPutMetadataObject_ObjStore_SWIFT() override
{}
154 int get_params(optional_yield y
) override
;
155 void send_response() override
;
156 bool need_object_expiration() override
{ return true; }
159 class RGWDeleteObj_ObjStore_SWIFT
: public RGWDeleteObj_ObjStore
{
161 RGWDeleteObj_ObjStore_SWIFT() {}
162 ~RGWDeleteObj_ObjStore_SWIFT() override
{}
164 int verify_permission(optional_yield y
) override
;
165 int get_params(optional_yield y
) override
;
166 bool need_object_expiration() override
{ return true; }
167 void send_response() override
;
170 class RGWCopyObj_ObjStore_SWIFT
: public RGWCopyObj_ObjStore
{
173 void dump_copy_info();
175 RGWCopyObj_ObjStore_SWIFT() : sent_header(false) {}
176 ~RGWCopyObj_ObjStore_SWIFT() override
{}
178 int init_dest_policy() override
;
179 int get_params(optional_yield y
) override
;
180 void send_response() override
;
181 void send_partial_response(off_t ofs
) override
;
184 class RGWGetACLs_ObjStore_SWIFT
: public RGWGetACLs_ObjStore
{
186 RGWGetACLs_ObjStore_SWIFT() {}
187 ~RGWGetACLs_ObjStore_SWIFT() override
{}
189 void send_response() override
{}
192 class RGWPutACLs_ObjStore_SWIFT
: public RGWPutACLs_ObjStore
{
194 RGWPutACLs_ObjStore_SWIFT() : RGWPutACLs_ObjStore() {}
195 ~RGWPutACLs_ObjStore_SWIFT() override
{}
197 void send_response() override
{}
200 class RGWOptionsCORS_ObjStore_SWIFT
: public RGWOptionsCORS_ObjStore
{
202 RGWOptionsCORS_ObjStore_SWIFT() {}
203 ~RGWOptionsCORS_ObjStore_SWIFT() override
{}
205 void send_response() override
;
208 class RGWBulkDelete_ObjStore_SWIFT
: public RGWBulkDelete_ObjStore
{
210 RGWBulkDelete_ObjStore_SWIFT() {}
211 ~RGWBulkDelete_ObjStore_SWIFT() override
{}
213 int get_data(std::list
<RGWBulkDelete::acct_path_t
>& items
,
214 bool * is_truncated
) override
;
215 void send_response() override
;
218 class RGWBulkUploadOp_ObjStore_SWIFT
: public RGWBulkUploadOp_ObjStore
{
223 RGWBulkUploadOp_ObjStore_SWIFT()
227 ~RGWBulkUploadOp_ObjStore_SWIFT() = default;
229 std::unique_ptr
<StreamGetter
> create_stream() override
;
230 void send_response() override
;
233 class RGWInfo_ObjStore_SWIFT
: public RGWInfo_ObjStore
{
238 std::function
<void (Formatter
&, const ConfigProxy
&, rgw::sal::Store
*)> list_data
;
241 static const std::vector
<std::pair
<std::string
, struct info
>> swift_info
;
243 RGWInfo_ObjStore_SWIFT() {}
244 ~RGWInfo_ObjStore_SWIFT() override
{}
246 void execute(optional_yield y
) override
;
247 void send_response() override
;
248 static void list_swift_data(Formatter
& formatter
, const ConfigProxy
& config
, rgw::sal::Store
* store
);
249 static void list_tempauth_data(Formatter
& formatter
, const ConfigProxy
& config
, rgw::sal::Store
* store
);
250 static void list_tempurl_data(Formatter
& formatter
, const ConfigProxy
& config
, rgw::sal::Store
* store
);
251 static void list_slo_data(Formatter
& formatter
, const ConfigProxy
& config
, rgw::sal::Store
* store
);
252 static bool is_expired(const std::string
& expires
, const DoutPrefixProvider
* dpp
);
256 class RGWFormPost
: public RGWPostObj_ObjStore
{
257 std::string
get_current_filename() const override
;
258 std::string
get_current_content_type() const override
;
259 std::size_t get_max_file_size() /*const*/;
260 bool is_next_file_to_upload() override
;
262 bool is_non_expired();
263 void get_owner_info(const req_state
* s
,
264 RGWUserInfo
& owner_info
) const;
266 parts_collection_t ctrl_parts
;
267 boost::optional
<post_form_part
> current_data_part
;
269 bool stream_done
= false;
271 class SignatureHelper
;
273 RGWFormPost() = default;
274 ~RGWFormPost() = default;
276 void init(rgw::sal::Store
* store
,
278 RGWHandler
* dialect_handler
) override
;
280 int get_params(optional_yield y
) override
;
281 int get_data(ceph::bufferlist
& bl
, bool& again
) override
;
282 void send_response() override
;
284 static bool is_formpost_req(req_state
* const s
);
287 class RGWFormPost::SignatureHelper
290 static constexpr uint32_t output_size
=
291 CEPH_CRYPTO_HMACSHA1_DIGESTSIZE
* 2 + 1;
293 unsigned char dest
[CEPH_CRYPTO_HMACSHA1_DIGESTSIZE
]; // 20
294 char dest_str
[output_size
];
297 SignatureHelper() = default;
299 const char* calc(const std::string
& key
,
300 const std::string_view
& path_info
,
301 const std::string_view
& redirect
,
302 const std::string_view
& max_file_size
,
303 const std::string_view
& max_file_count
,
304 const std::string_view
& expires
) {
305 using ceph::crypto::HMACSHA1
;
306 using UCHARPTR
= const unsigned char*;
308 HMACSHA1
hmac((UCHARPTR
) key
.data(), key
.size());
310 hmac
.Update((UCHARPTR
) path_info
.data(), path_info
.size());
311 hmac
.Update((UCHARPTR
) "\n", 1);
313 hmac
.Update((UCHARPTR
) redirect
.data(), redirect
.size());
314 hmac
.Update((UCHARPTR
) "\n", 1);
316 hmac
.Update((UCHARPTR
) max_file_size
.data(), max_file_size
.size());
317 hmac
.Update((UCHARPTR
) "\n", 1);
319 hmac
.Update((UCHARPTR
) max_file_count
.data(), max_file_count
.size());
320 hmac
.Update((UCHARPTR
) "\n", 1);
322 hmac
.Update((UCHARPTR
) expires
.data(), expires
.size());
326 buf_to_hex((UCHARPTR
) dest
, sizeof(dest
), dest_str
);
331 const char* get_signature() const {
335 bool is_equal_to(const std::string
& rhs
) const {
336 /* never allow out-of-range exception */
337 if (rhs
.size() < (output_size
- 1)) {
340 return rhs
.compare(0 /* pos */, output_size
, dest_str
) == 0;
343 }; /* RGWFormPost::SignatureHelper */
346 class RGWSwiftWebsiteHandler
{
347 rgw::sal::Store
* const store
;
349 RGWHandler_REST
* const handler
;
351 bool is_web_mode() const;
352 bool can_be_website_req() const;
353 bool is_web_dir() const;
354 bool is_index_present(const std::string
& index
) const;
356 int serve_errordoc(int http_ret
, std::string error_doc
, optional_yield y
);
358 RGWOp
* get_ws_redirect_op();
359 RGWOp
* get_ws_index_op();
360 RGWOp
* get_ws_listing_op();
362 RGWSwiftWebsiteHandler(rgw::sal::Store
* const store
,
364 RGWHandler_REST
* const handler
)
370 int error_handler(const int err_no
,
371 std::string
* const error_content
,
373 int retarget_bucket(RGWOp
* op
, RGWOp
** new_op
);
374 int retarget_object(RGWOp
* op
, RGWOp
** new_op
);
378 class RGWHandler_REST_SWIFT
: public RGWHandler_REST
{
379 friend class RGWRESTMgr_SWIFT
;
380 friend class RGWRESTMgr_SWIFT_Info
;
382 const rgw::auth::Strategy
& auth_strategy
;
384 virtual bool is_acl_op() const {
388 static int init_from_header(rgw::sal::Store
* store
, struct req_state
* s
,
389 const std::string
& frontend_prefix
);
391 explicit RGWHandler_REST_SWIFT(const rgw::auth::Strategy
& auth_strategy
)
392 : auth_strategy(auth_strategy
) {
394 ~RGWHandler_REST_SWIFT() override
= default;
396 int validate_bucket_name(const std::string
& bucket
);
398 int init(rgw::sal::Store
* store
, struct req_state
*s
, rgw::io::BasicClient
*cio
) override
;
399 int authorize(const DoutPrefixProvider
*dpp
, optional_yield y
) override
;
400 int postauth_init(optional_yield y
) override
;
402 RGWAccessControlPolicy
*alloc_policy() { return nullptr; /* return new RGWAccessControlPolicy_SWIFT; */ }
403 void free_policy(RGWAccessControlPolicy
*policy
) { delete policy
; }
406 class RGWHandler_REST_Service_SWIFT
: public RGWHandler_REST_SWIFT
{
408 RGWOp
*op_get() override
;
409 RGWOp
*op_head() override
;
410 RGWOp
*op_put() override
;
411 RGWOp
*op_post() override
;
412 RGWOp
*op_delete() override
;
414 using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT
;
415 ~RGWHandler_REST_Service_SWIFT() override
= default;
418 class RGWHandler_REST_Bucket_SWIFT
: public RGWHandler_REST_SWIFT
{
419 /* We need the boost::optional here only because of handler's late
420 * initialization (see the init() method). */
421 boost::optional
<RGWSwiftWebsiteHandler
> website_handler
;
423 bool is_obj_update_op() const override
{
424 return s
->op
== OP_POST
;
427 RGWOp
*get_obj_op(bool get_data
);
428 RGWOp
*op_get() override
;
429 RGWOp
*op_head() override
;
430 RGWOp
*op_put() override
;
431 RGWOp
*op_delete() override
;
432 RGWOp
*op_post() override
;
433 RGWOp
*op_options() override
;
435 using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT
;
436 ~RGWHandler_REST_Bucket_SWIFT() override
= default;
438 int error_handler(int err_no
, std::string
*error_content
, optional_yield y
) override
{
439 return website_handler
->error_handler(err_no
, error_content
, y
);
442 int retarget(RGWOp
* op
, RGWOp
** new_op
, optional_yield
) override
{
443 return website_handler
->retarget_bucket(op
, new_op
);
446 int init(rgw::sal::Store
* const store
,
447 struct req_state
* const s
,
448 rgw::io::BasicClient
* const cio
) override
{
449 website_handler
= boost::in_place
<RGWSwiftWebsiteHandler
>(store
, s
, this);
450 return RGWHandler_REST_SWIFT::init(store
, s
, cio
);
454 class RGWHandler_REST_Obj_SWIFT
: public RGWHandler_REST_SWIFT
{
455 /* We need the boost::optional here only because of handler's late
456 * initialization (see the init() method). */
457 boost::optional
<RGWSwiftWebsiteHandler
> website_handler
;
459 bool is_obj_update_op() const override
{
460 return s
->op
== OP_POST
;
463 RGWOp
*get_obj_op(bool get_data
);
464 RGWOp
*op_get() override
;
465 RGWOp
*op_head() override
;
466 RGWOp
*op_put() override
;
467 RGWOp
*op_delete() override
;
468 RGWOp
*op_post() override
;
469 RGWOp
*op_copy() override
;
470 RGWOp
*op_options() override
;
473 using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT
;
474 ~RGWHandler_REST_Obj_SWIFT() override
= default;
476 int error_handler(int err_no
, std::string
*error_content
,
477 optional_yield y
) override
{
478 return website_handler
->error_handler(err_no
, error_content
, y
);
481 int retarget(RGWOp
* op
, RGWOp
** new_op
, optional_yield
) override
{
482 return website_handler
->retarget_object(op
, new_op
);
485 int init(rgw::sal::Store
* const store
,
486 struct req_state
* const s
,
487 rgw::io::BasicClient
* const cio
) override
{
488 website_handler
= boost::in_place
<RGWSwiftWebsiteHandler
>(store
, s
, this);
489 return RGWHandler_REST_SWIFT::init(store
, s
, cio
);
493 class RGWRESTMgr_SWIFT
: public RGWRESTMgr
{
495 RGWRESTMgr
* get_resource_mgr_as_default(struct req_state
* const s
,
496 const std::string
& uri
,
497 std::string
* const out_uri
) override
{
498 return this->get_resource_mgr(s
, uri
, out_uri
);
502 RGWRESTMgr_SWIFT() = default;
503 ~RGWRESTMgr_SWIFT() override
= default;
505 RGWHandler_REST
*get_handler(rgw::sal::Store
* store
,
507 const rgw::auth::StrategyRegistry
& auth_registry
,
508 const std::string
& frontend_prefix
) override
;
512 class RGWGetCrossDomainPolicy_ObjStore_SWIFT
513 : public RGWGetCrossDomainPolicy_ObjStore
{
515 RGWGetCrossDomainPolicy_ObjStore_SWIFT() = default;
516 ~RGWGetCrossDomainPolicy_ObjStore_SWIFT() override
= default;
518 void send_response() override
;
521 class RGWGetHealthCheck_ObjStore_SWIFT
522 : public RGWGetHealthCheck_ObjStore
{
524 RGWGetHealthCheck_ObjStore_SWIFT() = default;
525 ~RGWGetHealthCheck_ObjStore_SWIFT() override
= default;
527 void send_response() override
;
530 class RGWHandler_SWIFT_CrossDomain
: public RGWHandler_REST
{
532 RGWHandler_SWIFT_CrossDomain() = default;
533 ~RGWHandler_SWIFT_CrossDomain() override
= default;
535 RGWOp
*op_get() override
{
536 return new RGWGetCrossDomainPolicy_ObjStore_SWIFT();
539 int init(rgw::sal::Store
* const store
,
540 struct req_state
* const state
,
541 rgw::io::BasicClient
* const cio
) override
{
542 state
->dialect
= "swift";
543 state
->formatter
= new JSONFormatter
;
544 state
->format
= RGW_FORMAT_JSON
;
546 return RGWHandler::init(store
, state
, cio
);
549 int authorize(const DoutPrefixProvider
*dpp
, optional_yield
) override
{
553 int postauth_init(optional_yield
) override
{
557 int read_permissions(RGWOp
*, optional_yield y
) override
{
561 virtual RGWAccessControlPolicy
*alloc_policy() { return nullptr; }
562 virtual void free_policy(RGWAccessControlPolicy
*policy
) {}
565 class RGWRESTMgr_SWIFT_CrossDomain
: public RGWRESTMgr
{
567 RGWRESTMgr
*get_resource_mgr(struct req_state
* const s
,
568 const std::string
& uri
,
569 std::string
* const out_uri
) override
{
574 RGWRESTMgr_SWIFT_CrossDomain() = default;
575 ~RGWRESTMgr_SWIFT_CrossDomain() override
= default;
577 RGWHandler_REST
* get_handler(rgw::sal::Store
* store
,
578 struct req_state
* const s
,
579 const rgw::auth::StrategyRegistry
&,
580 const std::string
&) override
{
581 s
->prot_flags
|= RGW_REST_SWIFT
;
582 return new RGWHandler_SWIFT_CrossDomain
;
587 class RGWHandler_SWIFT_HealthCheck
: public RGWHandler_REST
{
589 RGWHandler_SWIFT_HealthCheck() = default;
590 ~RGWHandler_SWIFT_HealthCheck() override
= default;
592 RGWOp
*op_get() override
{
593 return new RGWGetHealthCheck_ObjStore_SWIFT();
596 int init(rgw::sal::Store
* const store
,
597 struct req_state
* const state
,
598 rgw::io::BasicClient
* const cio
) override
{
599 state
->dialect
= "swift";
600 state
->formatter
= new JSONFormatter
;
601 state
->format
= RGW_FORMAT_JSON
;
603 return RGWHandler::init(store
, state
, cio
);
606 int authorize(const DoutPrefixProvider
*dpp
, optional_yield y
) override
{
610 int postauth_init(optional_yield
) override
{
614 int read_permissions(RGWOp
*, optional_yield y
) override
{
618 virtual RGWAccessControlPolicy
*alloc_policy() { return nullptr; }
619 virtual void free_policy(RGWAccessControlPolicy
*policy
) {}
622 class RGWRESTMgr_SWIFT_HealthCheck
: public RGWRESTMgr
{
624 RGWRESTMgr
*get_resource_mgr(struct req_state
* const s
,
625 const std::string
& uri
,
626 std::string
* const out_uri
) override
{
631 RGWRESTMgr_SWIFT_HealthCheck() = default;
632 ~RGWRESTMgr_SWIFT_HealthCheck() override
= default;
634 RGWHandler_REST
* get_handler(rgw::sal::Store
* store
,
635 struct req_state
* const s
,
636 const rgw::auth::StrategyRegistry
&,
637 const std::string
&) override
{
638 s
->prot_flags
|= RGW_REST_SWIFT
;
639 return new RGWHandler_SWIFT_HealthCheck
;
644 class RGWHandler_REST_SWIFT_Info
: public RGWHandler_REST_SWIFT
{
646 using RGWHandler_REST_SWIFT::RGWHandler_REST_SWIFT
;
647 ~RGWHandler_REST_SWIFT_Info() override
= default;
649 RGWOp
*op_get() override
{
650 return new RGWInfo_ObjStore_SWIFT();
653 int init(rgw::sal::Store
* const store
,
654 struct req_state
* const state
,
655 rgw::io::BasicClient
* const cio
) override
{
656 state
->dialect
= "swift";
657 state
->formatter
= new JSONFormatter
;
658 state
->format
= RGW_FORMAT_JSON
;
660 return RGWHandler::init(store
, state
, cio
);
663 int authorize(const DoutPrefixProvider
*dpp
, optional_yield
) override
{
667 int postauth_init(optional_yield
) override
{
671 int read_permissions(RGWOp
*, optional_yield y
) override
{
676 class RGWRESTMgr_SWIFT_Info
: public RGWRESTMgr
{
678 RGWRESTMgr_SWIFT_Info() = default;
679 ~RGWRESTMgr_SWIFT_Info() override
= default;
681 RGWHandler_REST
*get_handler(rgw::sal::Store
* store
,
683 const rgw::auth::StrategyRegistry
& auth_registry
,
684 const std::string
& frontend_prefix
) override
;