]> git.proxmox.com Git - ceph.git/blame - ceph/src/rgw/rgw_rest_s3.h
import 15.2.5
[ceph.git] / ceph / src / rgw / rgw_rest_s3.h
CommitLineData
7c673cae 1// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
9f95a23c 2// vim: ts=8 sw=2 smarttab ft=cpp
7c673cae 3
9f95a23c 4#pragma once
7c673cae 5
7c673cae
FG
6#define TIME_BUF_SIZE 128
7
8#include <mutex>
9
31f18b77
FG
10#include <boost/utility/string_view.hpp>
11#include <boost/container/static_vector.hpp>
12
31f18b77 13#include "common/sstring.hh"
7c673cae
FG
14#include "rgw_op.h"
15#include "rgw_rest.h"
16#include "rgw_http_errors.h"
17#include "rgw_acl_s3.h"
18#include "rgw_policy_s3.h"
19#include "rgw_lc_s3.h"
20#include "rgw_keystone.h"
21#include "rgw_rest_conn.h"
22#include "rgw_ldap.h"
7c673cae
FG
23
24#include "rgw_token.h"
11fdf7f2 25#include "include/ceph_assert.h"
7c673cae
FG
26
27#include "rgw_auth.h"
28#include "rgw_auth_filters.h"
11fdf7f2 29#include "rgw_sts.h"
7c673cae 30
31f18b77
FG
31struct rgw_http_error {
32 int http_ret;
33 const char *s3_code;
34};
35
36void rgw_get_errno_s3(struct rgw_http_error *e, int err_no);
7c673cae
FG
37
38class RGWGetObj_ObjStore_S3 : public RGWGetObj_ObjStore
39{
40protected:
41 // Serving a custom error page from an object is really a 200 response with
42 // just the status line altered.
43 int custom_http_ret = 0;
44 std::map<std::string, std::string> crypt_http_responses;
f6b5b4d7 45 int override_range_hdr(const rgw::auth::StrategyRegistry& auth_registry);
7c673cae
FG
46public:
47 RGWGetObj_ObjStore_S3() {}
48 ~RGWGetObj_ObjStore_S3() override {}
49
f6b5b4d7 50 int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) override;
7c673cae
FG
51 int get_params() override;
52 int send_response_data_error() override;
53 int send_response_data(bufferlist& bl, off_t ofs, off_t len) override;
54 void set_custom_http_response(int http_ret) { custom_http_ret = http_ret; }
11fdf7f2
TL
55 int get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>* filter,
56 RGWGetObj_Filter* cb,
7c673cae
FG
57 bufferlist* manifest_bl) override;
58};
59
224ce89b
WB
60class RGWGetObjTags_ObjStore_S3 : public RGWGetObjTags_ObjStore
61{
224ce89b
WB
62public:
63 RGWGetObjTags_ObjStore_S3() {}
64 ~RGWGetObjTags_ObjStore_S3() {}
65
66 void send_response_data(bufferlist &bl) override;
67};
68
69class RGWPutObjTags_ObjStore_S3 : public RGWPutObjTags_ObjStore
70{
71public:
72 RGWPutObjTags_ObjStore_S3() {}
73 ~RGWPutObjTags_ObjStore_S3() {}
74
75 int get_params() override;
76 void send_response() override;
77};
78
79class RGWDeleteObjTags_ObjStore_S3 : public RGWDeleteObjTags
80{
81public:
82 ~RGWDeleteObjTags_ObjStore_S3() override {}
83 void send_response() override;
84};
85
9f95a23c
TL
86class RGWGetBucketTags_ObjStore_S3 : public RGWGetBucketTags_ObjStore
87{
88 bufferlist tags_bl;
89public:
90 void send_response_data(bufferlist &bl) override;
91};
92
93class RGWPutBucketTags_ObjStore_S3 : public RGWPutBucketTags_ObjStore
94{
95public:
96 int get_params() override;
97 void send_response() override;
98};
99
100class RGWDeleteBucketTags_ObjStore_S3 : public RGWDeleteBucketTags
101{
102public:
103 void send_response() override;
104};
105
106class RGWGetBucketReplication_ObjStore_S3 : public RGWGetBucketReplication_ObjStore
107{
108public:
109 void send_response_data() override;
110};
111
112class RGWPutBucketReplication_ObjStore_S3 : public RGWPutBucketReplication_ObjStore
113{
114public:
115 int get_params() override;
116 void send_response() override;
117};
118
119class RGWDeleteBucketReplication_ObjStore_S3 : public RGWDeleteBucketReplication_ObjStore
120{
121protected:
122 void update_sync_policy(rgw_sync_policy_info *policy) override;
123public:
124 void send_response() override;
125};
126
7c673cae
FG
127class RGWListBuckets_ObjStore_S3 : public RGWListBuckets_ObjStore {
128public:
129 RGWListBuckets_ObjStore_S3() {}
130 ~RGWListBuckets_ObjStore_S3() override {}
131
132 int get_params() override {
133 limit = -1; /* no limit */
134 return 0;
135 }
136 void send_response_begin(bool has_buckets) override;
9f95a23c 137 void send_response_data(rgw::sal::RGWBucketList& buckets) override;
7c673cae
FG
138 void send_response_end() override;
139};
140
141class RGWGetUsage_ObjStore_S3 : public RGWGetUsage_ObjStore {
142public:
143 RGWGetUsage_ObjStore_S3() {}
144 ~RGWGetUsage_ObjStore_S3() override {}
145
146 int get_params() override ;
147 void send_response() override;
148};
149
150class RGWListBucket_ObjStore_S3 : public RGWListBucket_ObjStore {
92f5a8d4
TL
151protected:
152 bool objs_container;
153 bool encode_key {false};
eafe8130
TL
154 int get_common_params();
155 void send_common_response();
156 void send_common_versioned_response();
157 public:
7c673cae
FG
158 RGWListBucket_ObjStore_S3() : objs_container(false) {
159 default_max = 1000;
160 }
161 ~RGWListBucket_ObjStore_S3() override {}
162
163 int get_params() override;
164 void send_response() override;
165 void send_versioned_response();
166};
167
eafe8130
TL
168class RGWListBucket_ObjStore_S3v2 : public RGWListBucket_ObjStore_S3 {
169 bool fetchOwner;
170 bool start_after_exist;
171 bool continuation_token_exist;
172 string startAfter;
173 string continuation_token;
174public:
175 RGWListBucket_ObjStore_S3v2() : fetchOwner(false) {
176 }
177 ~RGWListBucket_ObjStore_S3v2() override {}
178
179 int get_params() override;
180 void send_response() override;
181 void send_versioned_response();
182};
183
7c673cae
FG
184class RGWGetBucketLogging_ObjStore_S3 : public RGWGetBucketLogging {
185public:
186 RGWGetBucketLogging_ObjStore_S3() {}
187 ~RGWGetBucketLogging_ObjStore_S3() override {}
188
189 void send_response() override;
190};
191
192class RGWGetBucketLocation_ObjStore_S3 : public RGWGetBucketLocation {
193public:
194 RGWGetBucketLocation_ObjStore_S3() {}
195 ~RGWGetBucketLocation_ObjStore_S3() override {}
196
197 void send_response() override;
198};
199
200class RGWGetBucketVersioning_ObjStore_S3 : public RGWGetBucketVersioning {
201public:
202 RGWGetBucketVersioning_ObjStore_S3() {}
203 ~RGWGetBucketVersioning_ObjStore_S3() override {}
204
205 void send_response() override;
206};
207
208class RGWSetBucketVersioning_ObjStore_S3 : public RGWSetBucketVersioning {
209public:
210 RGWSetBucketVersioning_ObjStore_S3() {}
211 ~RGWSetBucketVersioning_ObjStore_S3() override {}
212
213 int get_params() override;
214 void send_response() override;
215};
216
217class RGWGetBucketWebsite_ObjStore_S3 : public RGWGetBucketWebsite {
218public:
219 RGWGetBucketWebsite_ObjStore_S3() {}
220 ~RGWGetBucketWebsite_ObjStore_S3() override {}
221
222 void send_response() override;
223};
224
225class RGWSetBucketWebsite_ObjStore_S3 : public RGWSetBucketWebsite {
226public:
227 RGWSetBucketWebsite_ObjStore_S3() {}
228 ~RGWSetBucketWebsite_ObjStore_S3() override {}
229
230 int get_params() override;
231 void send_response() override;
232};
233
234class RGWDeleteBucketWebsite_ObjStore_S3 : public RGWDeleteBucketWebsite {
235public:
236 RGWDeleteBucketWebsite_ObjStore_S3() {}
237 ~RGWDeleteBucketWebsite_ObjStore_S3() override {}
238
239 void send_response() override;
240};
241
242class RGWStatBucket_ObjStore_S3 : public RGWStatBucket_ObjStore {
243public:
244 RGWStatBucket_ObjStore_S3() {}
245 ~RGWStatBucket_ObjStore_S3() override {}
246
247 void send_response() override;
248};
249
250class RGWCreateBucket_ObjStore_S3 : public RGWCreateBucket_ObjStore {
251public:
252 RGWCreateBucket_ObjStore_S3() {}
253 ~RGWCreateBucket_ObjStore_S3() override {}
254
255 int get_params() override;
256 void send_response() override;
257};
258
259class RGWDeleteBucket_ObjStore_S3 : public RGWDeleteBucket_ObjStore {
260public:
261 RGWDeleteBucket_ObjStore_S3() {}
262 ~RGWDeleteBucket_ObjStore_S3() override {}
263
264 void send_response() override;
265};
266
267class RGWPutObj_ObjStore_S3 : public RGWPutObj_ObjStore {
268private:
269 std::map<std::string, std::string> crypt_http_responses;
270
271public:
272 RGWPutObj_ObjStore_S3() {}
273 ~RGWPutObj_ObjStore_S3() override {}
274
275 int get_params() override;
276 int get_data(bufferlist& bl) override;
277 void send_response() override;
278
11fdf7f2
TL
279 int get_encrypt_filter(std::unique_ptr<rgw::putobj::DataProcessor> *filter,
280 rgw::putobj::DataProcessor *cb) override;
281 int get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>* filter,
282 RGWGetObj_Filter* cb,
7c673cae
FG
283 map<string, bufferlist>& attrs,
284 bufferlist* manifest_bl) override;
285};
286
287class RGWPostObj_ObjStore_S3 : public RGWPostObj_ObjStore {
288 parts_collection_t parts;
289 std::string filename;
290 std::string content_type;
291 RGWPolicyEnv env;
292 RGWPolicy post_policy;
293 map<string, string> crypt_http_responses;
294
295 const rgw::auth::StrategyRegistry* auth_registry_ptr = nullptr;
296
297 int get_policy();
224ce89b 298 int get_tags();
7c673cae
FG
299 void rebuild_key(string& key);
300
301 std::string get_current_filename() const override;
302 std::string get_current_content_type() const override;
303
304public:
305 RGWPostObj_ObjStore_S3() {}
306 ~RGWPostObj_ObjStore_S3() override {}
307
11fdf7f2 308 int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) override {
7c673cae
FG
309 auth_registry_ptr = &auth_registry;
310 return RGWPostObj_ObjStore::verify_requester(auth_registry);
311 }
312
313 int get_params() override;
314 int complete_get_params();
315
316 void send_response() override;
317 int get_data(ceph::bufferlist& bl, bool& again) override;
11fdf7f2
TL
318 int get_encrypt_filter(std::unique_ptr<rgw::putobj::DataProcessor> *filter,
319 rgw::putobj::DataProcessor *cb) override;
7c673cae
FG
320};
321
322class RGWDeleteObj_ObjStore_S3 : public RGWDeleteObj_ObjStore {
323public:
324 RGWDeleteObj_ObjStore_S3() {}
325 ~RGWDeleteObj_ObjStore_S3() override {}
326
327 int get_params() override;
328 void send_response() override;
329};
330
331class RGWCopyObj_ObjStore_S3 : public RGWCopyObj_ObjStore {
332 bool sent_header;
333public:
334 RGWCopyObj_ObjStore_S3() : sent_header(false) {}
335 ~RGWCopyObj_ObjStore_S3() override {}
336
337 int init_dest_policy() override;
338 int get_params() override;
11fdf7f2 339 int check_storage_class(const rgw_placement_rule& src_placement);
7c673cae
FG
340 void send_partial_response(off_t ofs) override;
341 void send_response() override;
342};
343
344class RGWGetACLs_ObjStore_S3 : public RGWGetACLs_ObjStore {
345public:
346 RGWGetACLs_ObjStore_S3() {}
347 ~RGWGetACLs_ObjStore_S3() override {}
348
349 void send_response() override;
350};
351
352class RGWPutACLs_ObjStore_S3 : public RGWPutACLs_ObjStore {
353public:
354 RGWPutACLs_ObjStore_S3() {}
355 ~RGWPutACLs_ObjStore_S3() override {}
356
9f95a23c 357 int get_policy_from_state(rgw::sal::RGWRadosStore *store, struct req_state *s, stringstream& ss) override;
7c673cae
FG
358 void send_response() override;
359 int get_params() override;
360};
361
362class RGWGetLC_ObjStore_S3 : public RGWGetLC_ObjStore {
363protected:
11fdf7f2 364 RGWLifecycleConfiguration_S3 config;
7c673cae
FG
365public:
366 RGWGetLC_ObjStore_S3() {}
367 ~RGWGetLC_ObjStore_S3() override {}
368 void execute() override;
369
370 void send_response() override;
371};
372
373class RGWPutLC_ObjStore_S3 : public RGWPutLC_ObjStore {
374public:
375 RGWPutLC_ObjStore_S3() {}
376 ~RGWPutLC_ObjStore_S3() override {}
377
378 void send_response() override;
379};
380
381class RGWDeleteLC_ObjStore_S3 : public RGWDeleteLC_ObjStore {
382public:
383 RGWDeleteLC_ObjStore_S3() {}
384 ~RGWDeleteLC_ObjStore_S3() override {}
385
386 void send_response() override;
387};
388
389class RGWGetCORS_ObjStore_S3 : public RGWGetCORS_ObjStore {
390public:
391 RGWGetCORS_ObjStore_S3() {}
392 ~RGWGetCORS_ObjStore_S3() override {}
393
394 void send_response() override;
395};
396
397class RGWPutCORS_ObjStore_S3 : public RGWPutCORS_ObjStore {
398public:
399 RGWPutCORS_ObjStore_S3() {}
400 ~RGWPutCORS_ObjStore_S3() override {}
401
402 int get_params() override;
403 void send_response() override;
404};
405
406class RGWDeleteCORS_ObjStore_S3 : public RGWDeleteCORS_ObjStore {
407public:
408 RGWDeleteCORS_ObjStore_S3() {}
409 ~RGWDeleteCORS_ObjStore_S3() override {}
410
411 void send_response() override;
412};
413
414class RGWOptionsCORS_ObjStore_S3 : public RGWOptionsCORS_ObjStore {
415public:
416 RGWOptionsCORS_ObjStore_S3() {}
417 ~RGWOptionsCORS_ObjStore_S3() override {}
418
419 void send_response() override;
420};
421
422class RGWGetRequestPayment_ObjStore_S3 : public RGWGetRequestPayment {
423public:
424 RGWGetRequestPayment_ObjStore_S3() {}
425 ~RGWGetRequestPayment_ObjStore_S3() override {}
426
427 void send_response() override;
428};
429
430class RGWSetRequestPayment_ObjStore_S3 : public RGWSetRequestPayment {
431public:
432 RGWSetRequestPayment_ObjStore_S3() {}
433 ~RGWSetRequestPayment_ObjStore_S3() override {}
434
435 int get_params() override;
436 void send_response() override;
437};
438
439class RGWInitMultipart_ObjStore_S3 : public RGWInitMultipart_ObjStore {
440private:
441 std::map<std::string, std::string> crypt_http_responses;
442public:
443 RGWInitMultipart_ObjStore_S3() {}
444 ~RGWInitMultipart_ObjStore_S3() override {}
445
446 int get_params() override;
447 void send_response() override;
448 int prepare_encryption(map<string, bufferlist>& attrs) override;
449};
450
451class RGWCompleteMultipart_ObjStore_S3 : public RGWCompleteMultipart_ObjStore {
452public:
453 RGWCompleteMultipart_ObjStore_S3() {}
454 ~RGWCompleteMultipart_ObjStore_S3() override {}
455
456 int get_params() override;
457 void send_response() override;
458};
459
460class RGWAbortMultipart_ObjStore_S3 : public RGWAbortMultipart_ObjStore {
461public:
462 RGWAbortMultipart_ObjStore_S3() {}
463 ~RGWAbortMultipart_ObjStore_S3() override {}
464
465 void send_response() override;
466};
467
468class RGWListMultipart_ObjStore_S3 : public RGWListMultipart_ObjStore {
469public:
470 RGWListMultipart_ObjStore_S3() {}
471 ~RGWListMultipart_ObjStore_S3() override {}
472
473 void send_response() override;
474};
475
476class RGWListBucketMultiparts_ObjStore_S3 : public RGWListBucketMultiparts_ObjStore {
477public:
478 RGWListBucketMultiparts_ObjStore_S3() {
479 default_max = 1000;
480 }
481 ~RGWListBucketMultiparts_ObjStore_S3() override {}
482
483 void send_response() override;
484};
485
486class RGWDeleteMultiObj_ObjStore_S3 : public RGWDeleteMultiObj_ObjStore {
487public:
488 RGWDeleteMultiObj_ObjStore_S3() {}
489 ~RGWDeleteMultiObj_ObjStore_S3() override {}
490
491 int get_params() override;
492 void send_status() override;
493 void begin_response() override;
494 void send_partial_response(rgw_obj_key& key, bool delete_marker,
495 const string& marker_version_id, int ret) override;
496 void end_response() override;
497};
498
eafe8130
TL
499class RGWPutBucketObjectLock_ObjStore_S3 : public RGWPutBucketObjectLock_ObjStore {
500public:
501 RGWPutBucketObjectLock_ObjStore_S3() {}
502 ~RGWPutBucketObjectLock_ObjStore_S3() override {}
503 void send_response() override;
504};
505
506class RGWGetBucketObjectLock_ObjStore_S3 : public RGWGetBucketObjectLock_ObjStore {
507public:
508 RGWGetBucketObjectLock_ObjStore_S3() {}
509 ~RGWGetBucketObjectLock_ObjStore_S3() {}
510 void send_response() override;
511};
512
513class RGWPutObjRetention_ObjStore_S3 : public RGWPutObjRetention_ObjStore {
514public:
515 RGWPutObjRetention_ObjStore_S3() {}
516 ~RGWPutObjRetention_ObjStore_S3() {}
517 int get_params() override;
518 void send_response() override;
519};
520
521class RGWGetObjRetention_ObjStore_S3 : public RGWGetObjRetention_ObjStore {
522public:
523 RGWGetObjRetention_ObjStore_S3() {}
524 ~RGWGetObjRetention_ObjStore_S3() {}
525 void send_response() override;
526};
527
528class RGWPutObjLegalHold_ObjStore_S3 : public RGWPutObjLegalHold_ObjStore {
529public:
530 RGWPutObjLegalHold_ObjStore_S3() {}
531 ~RGWPutObjLegalHold_ObjStore_S3() {}
532 void send_response() override;
533};
534
535class RGWGetObjLegalHold_ObjStore_S3 : public RGWGetObjLegalHold_ObjStore {
536public:
537 RGWGetObjLegalHold_ObjStore_S3() {}
538 ~RGWGetObjLegalHold_ObjStore_S3() {}
539 void send_response() override;
540};
541
7c673cae
FG
542class RGWGetObjLayout_ObjStore_S3 : public RGWGetObjLayout {
543public:
544 RGWGetObjLayout_ObjStore_S3() {}
545 ~RGWGetObjLayout_ObjStore_S3() {}
546
11fdf7f2 547 void send_response() override;
7c673cae
FG
548};
549
31f18b77
FG
550class RGWConfigBucketMetaSearch_ObjStore_S3 : public RGWConfigBucketMetaSearch {
551public:
552 RGWConfigBucketMetaSearch_ObjStore_S3() {}
553 ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
554
555 int get_params() override;
556 void send_response() override;
557};
558
559class RGWGetBucketMetaSearch_ObjStore_S3 : public RGWGetBucketMetaSearch {
560public:
561 RGWGetBucketMetaSearch_ObjStore_S3() {}
562 ~RGWGetBucketMetaSearch_ObjStore_S3() {}
563
564 void send_response() override;
565};
566
567class RGWDelBucketMetaSearch_ObjStore_S3 : public RGWDelBucketMetaSearch {
568public:
569 RGWDelBucketMetaSearch_ObjStore_S3() {}
570 ~RGWDelBucketMetaSearch_ObjStore_S3() {}
571
572 void send_response() override;
573};
7c673cae 574
9f95a23c
TL
575class RGWGetBucketPolicyStatus_ObjStore_S3 : public RGWGetBucketPolicyStatus {
576public:
577 void send_response() override;
578};
579
580class RGWPutBucketPublicAccessBlock_ObjStore_S3 : public RGWPutBucketPublicAccessBlock {
581public:
582 void send_response() override;
583};
584
585class RGWGetBucketPublicAccessBlock_ObjStore_S3 : public RGWGetBucketPublicAccessBlock {
586public:
587 void send_response() override;
588};
589
7c673cae 590class RGW_Auth_S3 {
7c673cae 591public:
11fdf7f2 592 static int authorize(const DoutPrefixProvider *dpp,
9f95a23c 593 rgw::sal::RGWRadosStore *store,
7c673cae
FG
594 const rgw::auth::StrategyRegistry& auth_registry,
595 struct req_state *s);
7c673cae
FG
596};
597
598class RGWHandler_Auth_S3 : public RGWHandler_REST {
599 friend class RGWRESTMgr_S3;
600
601 const rgw::auth::StrategyRegistry& auth_registry;
602
603public:
11fdf7f2 604 explicit RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry& auth_registry)
7c673cae
FG
605 : RGWHandler_REST(),
606 auth_registry(auth_registry) {
607 }
608 ~RGWHandler_Auth_S3() override = default;
609
610 static int validate_bucket_name(const string& bucket);
611 static int validate_object_name(const string& bucket);
612
9f95a23c 613 int init(rgw::sal::RGWRadosStore *store,
7c673cae
FG
614 struct req_state *s,
615 rgw::io::BasicClient *cio) override;
11fdf7f2
TL
616 int authorize(const DoutPrefixProvider *dpp) override {
617 return RGW_Auth_S3::authorize(dpp, store, auth_registry, s);
7c673cae
FG
618 }
619 int postauth_init() override { return 0; }
620};
621
622class RGWHandler_REST_S3 : public RGWHandler_REST {
623 friend class RGWRESTMgr_S3;
11fdf7f2 624protected:
7c673cae
FG
625 const rgw::auth::StrategyRegistry& auth_registry;
626public:
627 static int init_from_header(struct req_state *s, int default_formatter, bool configurable_format);
628
11fdf7f2 629 explicit RGWHandler_REST_S3(const rgw::auth::StrategyRegistry& auth_registry)
7c673cae
FG
630 : RGWHandler_REST(),
631 auth_registry(auth_registry) {
11fdf7f2 632 }
7c673cae
FG
633 ~RGWHandler_REST_S3() override = default;
634
9f95a23c 635 int init(rgw::sal::RGWRadosStore *store,
7c673cae
FG
636 struct req_state *s,
637 rgw::io::BasicClient *cio) override;
11fdf7f2 638 int authorize(const DoutPrefixProvider *dpp) override;
7c673cae
FG
639 int postauth_init() override;
640};
641
642class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
643protected:
9f95a23c
TL
644 const bool isSTSEnabled;
645 const bool isIAMEnabled;
646 const bool isPSEnabled;
647 bool is_usage_op() const {
7c673cae
FG
648 return s->info.args.exists("usage");
649 }
650 RGWOp *op_get() override;
651 RGWOp *op_head() override;
652 RGWOp *op_post() override;
653public:
11fdf7f2 654 RGWHandler_REST_Service_S3(const rgw::auth::StrategyRegistry& auth_registry,
9f95a23c
TL
655 bool _isSTSEnabled, bool _isIAMEnabled, bool _isPSEnabled) :
656 RGWHandler_REST_S3(auth_registry), isSTSEnabled(_isSTSEnabled), isIAMEnabled(_isIAMEnabled), isPSEnabled(_isPSEnabled) {}
7c673cae
FG
657 ~RGWHandler_REST_Service_S3() override = default;
658};
659
660class RGWHandler_REST_Bucket_S3 : public RGWHandler_REST_S3 {
eafe8130 661 const bool enable_pubsub;
7c673cae 662protected:
9f95a23c 663 bool is_acl_op() const {
7c673cae
FG
664 return s->info.args.exists("acl");
665 }
9f95a23c 666 bool is_cors_op() const {
7c673cae
FG
667 return s->info.args.exists("cors");
668 }
9f95a23c 669 bool is_lc_op() const {
7c673cae
FG
670 return s->info.args.exists("lifecycle");
671 }
9f95a23c 672 bool is_obj_update_op() const override {
7c673cae
FG
673 return is_acl_op() || is_cors_op();
674 }
9f95a23c
TL
675 bool is_tagging_op() const {
676 return s->info.args.exists("tagging");
677 }
678 bool is_request_payment_op() const {
7c673cae
FG
679 return s->info.args.exists("requestPayment");
680 }
9f95a23c 681 bool is_policy_op() const {
31f18b77
FG
682 return s->info.args.exists("policy");
683 }
9f95a23c 684 bool is_object_lock_op() const {
eafe8130
TL
685 return s->info.args.exists("object-lock");
686 }
687 bool is_notification_op() const {
688 if (enable_pubsub) {
689 return s->info.args.exists("notification");
690 }
691 return false;
692 }
9f95a23c
TL
693 bool is_replication_op() const {
694 return s->info.args.exists("replication");
695 }
696 bool is_policy_status_op() {
697 return s->info.args.exists("policyStatus");
698 }
699 bool is_block_public_access_op() {
700 return s->info.args.exists("publicAccessBlock");
701 }
7c673cae 702
9f95a23c 703 RGWOp *get_obj_op(bool get_data) const;
7c673cae
FG
704 RGWOp *op_get() override;
705 RGWOp *op_head() override;
706 RGWOp *op_put() override;
707 RGWOp *op_delete() override;
708 RGWOp *op_post() override;
709 RGWOp *op_options() override;
710public:
eafe8130
TL
711 RGWHandler_REST_Bucket_S3(const rgw::auth::StrategyRegistry& auth_registry, bool _enable_pubsub) :
712 RGWHandler_REST_S3(auth_registry), enable_pubsub(_enable_pubsub) {}
7c673cae
FG
713 ~RGWHandler_REST_Bucket_S3() override = default;
714};
715
716class RGWHandler_REST_Obj_S3 : public RGWHandler_REST_S3 {
717protected:
9f95a23c 718 bool is_acl_op() const {
7c673cae
FG
719 return s->info.args.exists("acl");
720 }
9f95a23c 721 bool is_tagging_op() const {
224ce89b
WB
722 return s->info.args.exists("tagging");
723 }
9f95a23c 724 bool is_obj_retention_op() const {
eafe8130
TL
725 return s->info.args.exists("retention");
726 }
9f95a23c 727 bool is_obj_legal_hold_op() const {
eafe8130
TL
728 return s->info.args.exists("legal-hold");
729 }
730
9f95a23c 731 bool is_obj_update_op() const override {
eafe8130 732 return is_acl_op() || is_tagging_op() || is_obj_retention_op() || is_obj_legal_hold_op();
7c673cae
FG
733 }
734 RGWOp *get_obj_op(bool get_data);
735
736 RGWOp *op_get() override;
737 RGWOp *op_head() override;
738 RGWOp *op_put() override;
739 RGWOp *op_delete() override;
740 RGWOp *op_post() override;
741 RGWOp *op_options() override;
742public:
743 using RGWHandler_REST_S3::RGWHandler_REST_S3;
744 ~RGWHandler_REST_Obj_S3() override = default;
745};
746
747class RGWRESTMgr_S3 : public RGWRESTMgr {
748private:
9f95a23c
TL
749 const bool enable_s3website;
750 const bool enable_sts;
751 const bool enable_iam;
eafe8130 752 const bool enable_pubsub;
7c673cae 753public:
9f95a23c
TL
754 explicit RGWRESTMgr_S3(bool _enable_s3website=false, bool _enable_sts=false, bool _enable_iam=false, bool _enable_pubsub=false)
755 : enable_s3website(_enable_s3website),
756 enable_sts(_enable_sts),
757 enable_iam(_enable_iam),
eafe8130 758 enable_pubsub(_enable_pubsub) {
7c673cae
FG
759 }
760
761 ~RGWRESTMgr_S3() override = default;
762
763 RGWHandler_REST *get_handler(struct req_state* s,
764 const rgw::auth::StrategyRegistry& auth_registry,
765 const std::string& frontend_prefix) override;
766};
767
768class RGWHandler_REST_Obj_S3Website;
769
770static inline bool looks_like_ip_address(const char *bucket)
771{
9f95a23c
TL
772 struct in6_addr a;
773 if (inet_pton(AF_INET6, bucket, static_cast<void*>(&a)) == 1) {
774 return true;
775 }
7c673cae
FG
776 int num_periods = 0;
777 bool expect_period = false;
778 for (const char *b = bucket; *b; ++b) {
779 if (*b == '.') {
780 if (!expect_period)
781 return false;
782 ++num_periods;
783 if (num_periods > 3)
784 return false;
785 expect_period = false;
786 }
787 else if (isdigit(*b)) {
788 expect_period = true;
789 }
790 else {
791 return false;
792 }
793 }
794 return (num_periods == 3);
795}
796
797static inline int valid_s3_object_name(const string& name) {
798 if (name.size() > 1024) {
799 return -ERR_INVALID_OBJECT_NAME;
800 }
801 if (check_utf8(name.c_str(), name.size())) {
802 return -ERR_INVALID_OBJECT_NAME;
803 }
804 return 0;
805}
806
807static inline int valid_s3_bucket_name(const string& name, bool relaxed=false)
808{
809 // This function enforces Amazon's spec for bucket names.
810 // (The requirements, not the recommendations.)
811 int len = name.size();
9f95a23c
TL
812 int max = (relaxed ? 255 : 63);
813
7c673cae
FG
814 if (len < 3) {
815 // Name too short
816 return -ERR_INVALID_BUCKET_NAME;
9f95a23c 817 } else if (len > max) {
7c673cae
FG
818 // Name too long
819 return -ERR_INVALID_BUCKET_NAME;
820 }
821
9f95a23c 822 // bucket names must start with a number or letter
7c673cae
FG
823 if (!(isalpha(name[0]) || isdigit(name[0]))) {
824 if (!relaxed)
825 return -ERR_INVALID_BUCKET_NAME;
826 else if (!(name[0] == '_' || name[0] == '.' || name[0] == '-'))
827 return -ERR_INVALID_BUCKET_NAME;
828 }
829
9f95a23c
TL
830 // bucket names must end with a number or letter
831 if (!(isalpha(name[len-1]) || isdigit(name[len-1])))
832 if (!relaxed)
833 return -ERR_INVALID_BUCKET_NAME;
834
7c673cae
FG
835 for (const char *s = name.c_str(); *s; ++s) {
836 char c = *s;
9f95a23c 837 if (isdigit(c))
7c673cae 838 continue;
9f95a23c
TL
839
840 if (isalpha(c)) {
841 // name cannot contain uppercase letters
842 if (relaxed || islower(c))
843 continue;
844 }
845
846 if (c == '_')
847 // name cannot contain underscore
848 if (relaxed)
849 continue;
850
851 if (c == '-')
7c673cae 852 continue;
9f95a23c
TL
853
854 if (c == '.') {
855 if (!relaxed && s && *s) {
856 // name cannot have consecutive periods or dashes
857 // adjacent to periods
858 // ensure s is neither the first nor the last character
859 char p = *(s-1);
860 char n = *(s+1);
861 if ((p != '-') && (n != '.') && (n != '-'))
862 continue;
863 } else {
864 continue;
865 }
866 }
867
7c673cae
FG
868 // Invalid character
869 return -ERR_INVALID_BUCKET_NAME;
870 }
871
872 if (looks_like_ip_address(name.c_str()))
873 return -ERR_INVALID_BUCKET_NAME;
874
875 return 0;
876}
877
878
9f95a23c 879namespace rgw::auth::s3 {
7c673cae 880
31f18b77 881class AWSEngine : public rgw::auth::Engine {
7c673cae 882public:
31f18b77
FG
883 class VersionAbstractor {
884 static constexpr size_t DIGEST_SIZE_V2 = CEPH_CRYPTO_HMACSHA1_DIGESTSIZE;
885 static constexpr size_t DIGEST_SIZE_V4 = CEPH_CRYPTO_HMACSHA256_DIGESTSIZE;
886
887 /* Knowing the signature max size allows us to employ the sstring, and thus
888 * avoid dynamic allocations. The multiplier comes from representing digest
889 * in the base64-encoded form. */
890 static constexpr size_t SIGNATURE_MAX_SIZE = \
11fdf7f2 891 std::max(DIGEST_SIZE_V2, DIGEST_SIZE_V4) * 2 + sizeof('\0');
31f18b77 892
7c673cae 893 public:
31f18b77 894 virtual ~VersionAbstractor() {};
7c673cae 895
31f18b77
FG
896 using access_key_id_t = boost::string_view;
897 using client_signature_t = boost::string_view;
11fdf7f2 898 using session_token_t = boost::string_view;
31f18b77 899 using server_signature_t = basic_sstring<char, uint16_t, SIGNATURE_MAX_SIZE>;
7c673cae
FG
900 using string_to_sign_t = std::string;
901
31f18b77
FG
902 /* Transformation for crafting the AWS signature at server side which is
903 * used later to compare with the user-provided one. The methodology for
904 * doing that depends on AWS auth version. */
905 using signature_factory_t = \
906 std::function<server_signature_t(CephContext* cct,
907 const std::string& secret_key,
908 const string_to_sign_t& string_to_sign)>;
909
910 /* Return an instance of Completer for verifying the payload's fingerprint
911 * if necessary. Otherwise caller gets nullptr. Caller may provide secret
912 * key */
913 using completer_factory_t = \
914 std::function<rgw::auth::Completer::cmplptr_t(
915 const boost::optional<std::string>& secret_key)>;
916
224ce89b
WB
917 struct auth_data_t {
918 access_key_id_t access_key_id;
919 client_signature_t client_signature;
11fdf7f2 920 session_token_t session_token;
224ce89b
WB
921 string_to_sign_t string_to_sign;
922 signature_factory_t signature_factory;
923 completer_factory_t completer_factory;
924 };
925
926 virtual auth_data_t get_auth_data(const req_state* s) const = 0;
7c673cae
FG
927 };
928
929protected:
930 CephContext* cct;
31f18b77 931 const VersionAbstractor& ver_abstractor;
7c673cae 932
31f18b77 933 AWSEngine(CephContext* const cct, const VersionAbstractor& ver_abstractor)
7c673cae 934 : cct(cct),
31f18b77 935 ver_abstractor(ver_abstractor) {
7c673cae
FG
936 }
937
938 using result_t = rgw::auth::Engine::result_t;
31f18b77
FG
939 using string_to_sign_t = VersionAbstractor::string_to_sign_t;
940 using signature_factory_t = VersionAbstractor::signature_factory_t;
941 using completer_factory_t = VersionAbstractor::completer_factory_t;
942
943 /* TODO(rzarzynski): clean up. We've too many input parameter hee. Also
944 * the signature get_auth_data() of VersionAbstractor is too complicated.
945 * Replace these thing with a simple, dedicated structure. */
11fdf7f2
TL
946 virtual result_t authenticate(const DoutPrefixProvider* dpp,
947 const boost::string_view& access_key_id,
31f18b77 948 const boost::string_view& signature,
11fdf7f2 949 const boost::string_view& session_token,
31f18b77
FG
950 const string_to_sign_t& string_to_sign,
951 const signature_factory_t& signature_factory,
952 const completer_factory_t& completer_factory,
7c673cae
FG
953 const req_state* s) const = 0;
954
955public:
11fdf7f2 956 result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s) const final;
7c673cae
FG
957};
958
31f18b77
FG
959
960class AWSGeneralAbstractor : public AWSEngine::VersionAbstractor {
7c673cae
FG
961 CephContext* const cct;
962
31f18b77
FG
963 virtual boost::optional<std::string>
964 get_v4_canonical_headers(const req_info& info,
965 const boost::string_view& signedheaders,
966 const bool using_qs) const;
967
224ce89b 968 auth_data_t get_auth_data_v2(const req_state* s) const;
11fdf7f2 969 auth_data_t get_auth_data_v4(const req_state* s, const bool using_qs) const;
31f18b77 970
7c673cae 971public:
11fdf7f2 972 explicit AWSGeneralAbstractor(CephContext* const cct)
7c673cae
FG
973 : cct(cct) {
974 }
975
224ce89b 976 auth_data_t get_auth_data(const req_state* s) const override;
7c673cae
FG
977};
978
31f18b77
FG
979class AWSGeneralBoto2Abstractor : public AWSGeneralAbstractor {
980 boost::optional<std::string>
981 get_v4_canonical_headers(const req_info& info,
982 const boost::string_view& signedheaders,
983 const bool using_qs) const override;
984
985public:
986 using AWSGeneralAbstractor::AWSGeneralAbstractor;
987};
7c673cae 988
31f18b77 989class AWSBrowserUploadAbstractor : public AWSEngine::VersionAbstractor {
7c673cae
FG
990 static std::string to_string(ceph::bufferlist bl) {
991 return std::string(bl.c_str(),
992 static_cast<std::string::size_type>(bl.length()));
993 }
994
31f18b77
FG
995 auth_data_t get_auth_data_v2(const req_state* s) const;
996 auth_data_t get_auth_data_v4(const req_state* s) const;
997
7c673cae 998public:
11fdf7f2 999 explicit AWSBrowserUploadAbstractor(CephContext*) {
7c673cae
FG
1000 }
1001
224ce89b 1002 auth_data_t get_auth_data(const req_state* s) const override;
7c673cae
FG
1003};
1004
1005
31f18b77 1006class LDAPEngine : public AWSEngine {
7c673cae
FG
1007 static rgw::LDAPHelper* ldh;
1008 static std::mutex mtx;
1009
1010 static void init(CephContext* const cct);
1011
1012 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
1013 using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
1014 using result_t = rgw::auth::Engine::result_t;
1015
1016protected:
9f95a23c 1017 RGWCtl* const ctl;
7c673cae
FG
1018 const rgw::auth::RemoteApplier::Factory* const apl_factory;
1019
1020 acl_strategy_t get_acl_strategy() const;
1021 auth_info_t get_creds_info(const rgw::RGWToken& token) const noexcept;
1022
11fdf7f2
TL
1023 result_t authenticate(const DoutPrefixProvider* dpp,
1024 const boost::string_view& access_key_id,
31f18b77 1025 const boost::string_view& signature,
11fdf7f2 1026 const boost::string_view& session_token,
31f18b77
FG
1027 const string_to_sign_t& string_to_sign,
1028 const signature_factory_t&,
1029 const completer_factory_t& completer_factory,
7c673cae
FG
1030 const req_state* s) const override;
1031public:
1032 LDAPEngine(CephContext* const cct,
9f95a23c 1033 RGWCtl* const ctl,
31f18b77 1034 const VersionAbstractor& ver_abstractor,
7c673cae 1035 const rgw::auth::RemoteApplier::Factory* const apl_factory)
31f18b77 1036 : AWSEngine(cct, ver_abstractor),
9f95a23c 1037 ctl(ctl),
7c673cae
FG
1038 apl_factory(apl_factory) {
1039 init(cct);
1040 }
1041
31f18b77 1042 using AWSEngine::authenticate;
7c673cae
FG
1043
1044 const char* get_name() const noexcept override {
1045 return "rgw::auth::s3::LDAPEngine";
1046 }
a8e16298
TL
1047
1048 static bool valid();
11fdf7f2 1049 static void shutdown();
7c673cae
FG
1050};
1051
31f18b77 1052class LocalEngine : public AWSEngine {
9f95a23c 1053 RGWCtl* const ctl;
7c673cae
FG
1054 const rgw::auth::LocalApplier::Factory* const apl_factory;
1055
11fdf7f2
TL
1056 result_t authenticate(const DoutPrefixProvider* dpp,
1057 const boost::string_view& access_key_id,
31f18b77 1058 const boost::string_view& signature,
11fdf7f2 1059 const boost::string_view& session_token,
31f18b77
FG
1060 const string_to_sign_t& string_to_sign,
1061 const signature_factory_t& signature_factory,
1062 const completer_factory_t& completer_factory,
7c673cae
FG
1063 const req_state* s) const override;
1064public:
31f18b77 1065 LocalEngine(CephContext* const cct,
9f95a23c 1066 RGWCtl* const ctl,
31f18b77
FG
1067 const VersionAbstractor& ver_abstractor,
1068 const rgw::auth::LocalApplier::Factory* const apl_factory)
1069 : AWSEngine(cct, ver_abstractor),
9f95a23c 1070 ctl(ctl),
7c673cae
FG
1071 apl_factory(apl_factory) {
1072 }
1073
31f18b77 1074 using AWSEngine::authenticate;
7c673cae
FG
1075
1076 const char* get_name() const noexcept override {
31f18b77 1077 return "rgw::auth::s3::LocalEngine";
7c673cae
FG
1078 }
1079};
1080
11fdf7f2 1081class STSEngine : public AWSEngine {
9f95a23c 1082 RGWCtl* const ctl;
11fdf7f2
TL
1083 const rgw::auth::LocalApplier::Factory* const local_apl_factory;
1084 const rgw::auth::RemoteApplier::Factory* const remote_apl_factory;
1085 const rgw::auth::RoleApplier::Factory* const role_apl_factory;
1086
1087 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
1088 using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
1089
1090 acl_strategy_t get_acl_strategy() const { return nullptr; };
1091 auth_info_t get_creds_info(const STS::SessionToken& token) const noexcept;
1092
9f95a23c 1093 int get_session_token(const DoutPrefixProvider* dpp, const boost::string_view& session_token,
11fdf7f2
TL
1094 STS::SessionToken& token) const;
1095
1096 result_t authenticate(const DoutPrefixProvider* dpp,
1097 const boost::string_view& access_key_id,
1098 const boost::string_view& signature,
1099 const boost::string_view& session_token,
1100 const string_to_sign_t& string_to_sign,
1101 const signature_factory_t& signature_factory,
1102 const completer_factory_t& completer_factory,
1103 const req_state* s) const override;
1104public:
1105 STSEngine(CephContext* const cct,
9f95a23c 1106 RGWCtl* const ctl,
11fdf7f2
TL
1107 const VersionAbstractor& ver_abstractor,
1108 const rgw::auth::LocalApplier::Factory* const local_apl_factory,
1109 const rgw::auth::RemoteApplier::Factory* const remote_apl_factory,
1110 const rgw::auth::RoleApplier::Factory* const role_apl_factory)
1111 : AWSEngine(cct, ver_abstractor),
9f95a23c 1112 ctl(ctl),
11fdf7f2
TL
1113 local_apl_factory(local_apl_factory),
1114 remote_apl_factory(remote_apl_factory),
1115 role_apl_factory(role_apl_factory) {
1116 }
1117
1118 using AWSEngine::authenticate;
1119
1120 const char* get_name() const noexcept override {
1121 return "rgw::auth::s3::STSEngine";
1122 }
1123};
7c673cae 1124
d2e6a577
FG
1125class S3AnonymousEngine : public rgw::auth::AnonymousEngine {
1126 bool is_applicable(const req_state* s) const noexcept override;
1127
1128public:
1129 /* Let's reuse the parent class' constructor. */
1130 using rgw::auth::AnonymousEngine::AnonymousEngine;
1131
1132 const char* get_name() const noexcept override {
1133 return "rgw::auth::s3::S3AnonymousEngine";
1134 }
1135};
1136
1137
9f95a23c 1138} // namespace rgw::auth::s3