]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_s3.h
8c59174efe0f23f805416912e90abd15e5e4d83a
[ceph.git] / ceph / src / rgw / rgw_rest_s3.h
1 // -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*-
2 // vim: ts=8 sw=2 smarttab ft=cpp
3
4 #pragma once
5
6 #define TIME_BUF_SIZE 128
7
8 #include <mutex>
9 #include <string_view>
10
11 #include <boost/container/static_vector.hpp>
12 #include <boost/crc.hpp>
13
14 #include "common/sstring.hh"
15 #include "rgw_op.h"
16 #include "rgw_rest.h"
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"
23 #include "rgw_ldap.h"
24
25 #include "rgw_token.h"
26 #include "include/ceph_assert.h"
27
28 #include "rgw_auth.h"
29 #include "rgw_auth_filters.h"
30 #include "rgw_sts.h"
31
32 struct rgw_http_error {
33 int http_ret;
34 const char *s3_code;
35 };
36
37 void rgw_get_errno_s3(struct rgw_http_error *e, int err_no);
38
39 class RGWGetObj_ObjStore_S3 : public RGWGetObj_ObjStore
40 {
41 protected:
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);
47 public:
48 RGWGetObj_ObjStore_S3() {}
49 ~RGWGetObj_ObjStore_S3() override {}
50
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,
57 RGWGetObj_Filter* cb,
58 bufferlist* manifest_bl) override;
59 };
60
61 class RGWGetObjTags_ObjStore_S3 : public RGWGetObjTags_ObjStore
62 {
63 public:
64 RGWGetObjTags_ObjStore_S3() {}
65 ~RGWGetObjTags_ObjStore_S3() {}
66
67 void send_response_data(bufferlist &bl) override;
68 };
69
70 class RGWPutObjTags_ObjStore_S3 : public RGWPutObjTags_ObjStore
71 {
72 public:
73 RGWPutObjTags_ObjStore_S3() {}
74 ~RGWPutObjTags_ObjStore_S3() {}
75
76 int get_params(optional_yield y) override;
77 void send_response() override;
78 };
79
80 class RGWDeleteObjTags_ObjStore_S3 : public RGWDeleteObjTags
81 {
82 public:
83 ~RGWDeleteObjTags_ObjStore_S3() override {}
84 void send_response() override;
85 };
86
87 class RGWGetBucketTags_ObjStore_S3 : public RGWGetBucketTags_ObjStore
88 {
89 bufferlist tags_bl;
90 public:
91 void send_response_data(bufferlist &bl) override;
92 };
93
94 class RGWPutBucketTags_ObjStore_S3 : public RGWPutBucketTags_ObjStore
95 {
96 public:
97 int get_params(optional_yield y) override;
98 void send_response() override;
99 };
100
101 class RGWDeleteBucketTags_ObjStore_S3 : public RGWDeleteBucketTags
102 {
103 public:
104 void send_response() override;
105 };
106
107 class RGWGetBucketReplication_ObjStore_S3 : public RGWGetBucketReplication_ObjStore
108 {
109 public:
110 void send_response_data() override;
111 };
112
113 class RGWPutBucketReplication_ObjStore_S3 : public RGWPutBucketReplication_ObjStore
114 {
115 public:
116 int get_params(optional_yield y) override;
117 void send_response() override;
118 };
119
120 class RGWDeleteBucketReplication_ObjStore_S3 : public RGWDeleteBucketReplication_ObjStore
121 {
122 protected:
123 void update_sync_policy(rgw_sync_policy_info *policy) override;
124 public:
125 void send_response() override;
126 };
127
128 class RGWListBuckets_ObjStore_S3 : public RGWListBuckets_ObjStore {
129 public:
130 RGWListBuckets_ObjStore_S3() {}
131 ~RGWListBuckets_ObjStore_S3() override {}
132
133 int get_params(optional_yield y) override {
134 limit = -1; /* no limit */
135 return 0;
136 }
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;
140 };
141
142 class RGWGetUsage_ObjStore_S3 : public RGWGetUsage_ObjStore {
143 public:
144 RGWGetUsage_ObjStore_S3() {}
145 ~RGWGetUsage_ObjStore_S3() override {}
146
147 int get_params(optional_yield y) override ;
148 void send_response() override;
149 };
150
151 class RGWListBucket_ObjStore_S3 : public RGWListBucket_ObjStore {
152 protected:
153 bool objs_container;
154 bool encode_key {false};
155 int get_common_params();
156 void send_common_response();
157 void send_common_versioned_response();
158 public:
159 RGWListBucket_ObjStore_S3() : objs_container(false) {
160 default_max = 1000;
161 }
162 ~RGWListBucket_ObjStore_S3() override {}
163
164 int get_params(optional_yield y) override;
165 void send_response() override;
166 void send_versioned_response();
167 };
168
169 class RGWListBucket_ObjStore_S3v2 : public RGWListBucket_ObjStore_S3 {
170 bool fetchOwner;
171 bool start_after_exist;
172 bool continuation_token_exist;
173 string startAfter;
174 string continuation_token;
175 public:
176 RGWListBucket_ObjStore_S3v2() : fetchOwner(false) {
177 }
178 ~RGWListBucket_ObjStore_S3v2() override {}
179
180 int get_params(optional_yield y) override;
181 void send_response() override;
182 void send_versioned_response();
183 };
184
185 class RGWGetBucketLogging_ObjStore_S3 : public RGWGetBucketLogging {
186 public:
187 RGWGetBucketLogging_ObjStore_S3() {}
188 ~RGWGetBucketLogging_ObjStore_S3() override {}
189
190 void send_response() override;
191 };
192
193 class RGWGetBucketLocation_ObjStore_S3 : public RGWGetBucketLocation {
194 public:
195 RGWGetBucketLocation_ObjStore_S3() {}
196 ~RGWGetBucketLocation_ObjStore_S3() override {}
197
198 void send_response() override;
199 };
200
201 class RGWGetBucketVersioning_ObjStore_S3 : public RGWGetBucketVersioning {
202 public:
203 RGWGetBucketVersioning_ObjStore_S3() {}
204 ~RGWGetBucketVersioning_ObjStore_S3() override {}
205
206 void send_response() override;
207 };
208
209 class RGWSetBucketVersioning_ObjStore_S3 : public RGWSetBucketVersioning {
210 public:
211 RGWSetBucketVersioning_ObjStore_S3() {}
212 ~RGWSetBucketVersioning_ObjStore_S3() override {}
213
214 int get_params(optional_yield y) override;
215 void send_response() override;
216 };
217
218 class RGWGetBucketWebsite_ObjStore_S3 : public RGWGetBucketWebsite {
219 public:
220 RGWGetBucketWebsite_ObjStore_S3() {}
221 ~RGWGetBucketWebsite_ObjStore_S3() override {}
222
223 void send_response() override;
224 };
225
226 class RGWSetBucketWebsite_ObjStore_S3 : public RGWSetBucketWebsite {
227 public:
228 RGWSetBucketWebsite_ObjStore_S3() {}
229 ~RGWSetBucketWebsite_ObjStore_S3() override {}
230
231 int get_params(optional_yield y) override;
232 void send_response() override;
233 };
234
235 class RGWDeleteBucketWebsite_ObjStore_S3 : public RGWDeleteBucketWebsite {
236 public:
237 RGWDeleteBucketWebsite_ObjStore_S3() {}
238 ~RGWDeleteBucketWebsite_ObjStore_S3() override {}
239
240 void send_response() override;
241 };
242
243 class RGWStatBucket_ObjStore_S3 : public RGWStatBucket_ObjStore {
244 public:
245 RGWStatBucket_ObjStore_S3() {}
246 ~RGWStatBucket_ObjStore_S3() override {}
247
248 void send_response() override;
249 };
250
251 class RGWCreateBucket_ObjStore_S3 : public RGWCreateBucket_ObjStore {
252 public:
253 RGWCreateBucket_ObjStore_S3() {}
254 ~RGWCreateBucket_ObjStore_S3() override {}
255
256 int get_params(optional_yield y) override;
257 void send_response() override;
258 };
259
260 class RGWDeleteBucket_ObjStore_S3 : public RGWDeleteBucket_ObjStore {
261 public:
262 RGWDeleteBucket_ObjStore_S3() {}
263 ~RGWDeleteBucket_ObjStore_S3() override {}
264
265 void send_response() override;
266 };
267
268 class RGWPutObj_ObjStore_S3 : public RGWPutObj_ObjStore {
269 private:
270 std::map<std::string, std::string> crypt_http_responses;
271
272 public:
273 RGWPutObj_ObjStore_S3() {}
274 ~RGWPutObj_ObjStore_S3() override {}
275
276 int get_params(optional_yield y) override;
277 int get_data(bufferlist& bl) override;
278 void send_response() override;
279
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;
286 };
287
288 class RGWPostObj_ObjStore_S3 : public RGWPostObj_ObjStore {
289 parts_collection_t parts;
290 std::string filename;
291 std::string content_type;
292 RGWPolicyEnv env;
293 RGWPolicy post_policy;
294 map<string, string> crypt_http_responses;
295
296 const rgw::auth::StrategyRegistry* auth_registry_ptr = nullptr;
297
298 int get_policy(optional_yield y);
299 int get_tags();
300 void rebuild_key(rgw::sal::RGWObject* obj);
301
302 std::string get_current_filename() const override;
303 std::string get_current_content_type() const override;
304
305 public:
306 RGWPostObj_ObjStore_S3() {}
307 ~RGWPostObj_ObjStore_S3() override {}
308
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);
312 }
313
314 int get_params(optional_yield y) override;
315 int complete_get_params();
316
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;
321 };
322
323 class RGWDeleteObj_ObjStore_S3 : public RGWDeleteObj_ObjStore {
324 public:
325 RGWDeleteObj_ObjStore_S3() {}
326 ~RGWDeleteObj_ObjStore_S3() override {}
327
328 int get_params(optional_yield y) override;
329 void send_response() override;
330 };
331
332 class RGWCopyObj_ObjStore_S3 : public RGWCopyObj_ObjStore {
333 bool sent_header;
334 public:
335 RGWCopyObj_ObjStore_S3() : sent_header(false) {}
336 ~RGWCopyObj_ObjStore_S3() override {}
337
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;
343 };
344
345 class RGWGetACLs_ObjStore_S3 : public RGWGetACLs_ObjStore {
346 public:
347 RGWGetACLs_ObjStore_S3() {}
348 ~RGWGetACLs_ObjStore_S3() override {}
349
350 void send_response() override;
351 };
352
353 class RGWPutACLs_ObjStore_S3 : public RGWPutACLs_ObjStore {
354 public:
355 RGWPutACLs_ObjStore_S3() {}
356 ~RGWPutACLs_ObjStore_S3() override {}
357
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;
361 };
362
363 class RGWGetLC_ObjStore_S3 : public RGWGetLC_ObjStore {
364 protected:
365 RGWLifecycleConfiguration_S3 config;
366 public:
367 RGWGetLC_ObjStore_S3() {}
368 ~RGWGetLC_ObjStore_S3() override {}
369 void execute(optional_yield y) override;
370
371 void send_response() override;
372 };
373
374 class RGWPutLC_ObjStore_S3 : public RGWPutLC_ObjStore {
375 public:
376 RGWPutLC_ObjStore_S3() {}
377 ~RGWPutLC_ObjStore_S3() override {}
378
379 void send_response() override;
380 };
381
382 class RGWDeleteLC_ObjStore_S3 : public RGWDeleteLC_ObjStore {
383 public:
384 RGWDeleteLC_ObjStore_S3() {}
385 ~RGWDeleteLC_ObjStore_S3() override {}
386
387 void send_response() override;
388 };
389
390 class RGWGetCORS_ObjStore_S3 : public RGWGetCORS_ObjStore {
391 public:
392 RGWGetCORS_ObjStore_S3() {}
393 ~RGWGetCORS_ObjStore_S3() override {}
394
395 void send_response() override;
396 };
397
398 class RGWPutCORS_ObjStore_S3 : public RGWPutCORS_ObjStore {
399 public:
400 RGWPutCORS_ObjStore_S3() {}
401 ~RGWPutCORS_ObjStore_S3() override {}
402
403 int get_params(optional_yield y) override;
404 void send_response() override;
405 };
406
407 class RGWDeleteCORS_ObjStore_S3 : public RGWDeleteCORS_ObjStore {
408 public:
409 RGWDeleteCORS_ObjStore_S3() {}
410 ~RGWDeleteCORS_ObjStore_S3() override {}
411
412 void send_response() override;
413 };
414
415 class RGWOptionsCORS_ObjStore_S3 : public RGWOptionsCORS_ObjStore {
416 public:
417 RGWOptionsCORS_ObjStore_S3() {}
418 ~RGWOptionsCORS_ObjStore_S3() override {}
419
420 void send_response() override;
421 };
422
423 class RGWGetRequestPayment_ObjStore_S3 : public RGWGetRequestPayment {
424 public:
425 RGWGetRequestPayment_ObjStore_S3() {}
426 ~RGWGetRequestPayment_ObjStore_S3() override {}
427
428 void send_response() override;
429 };
430
431 class RGWSetRequestPayment_ObjStore_S3 : public RGWSetRequestPayment {
432 public:
433 RGWSetRequestPayment_ObjStore_S3() {}
434 ~RGWSetRequestPayment_ObjStore_S3() override {}
435
436 int get_params(optional_yield y) override;
437 void send_response() override;
438 };
439
440 class RGWInitMultipart_ObjStore_S3 : public RGWInitMultipart_ObjStore {
441 private:
442 std::map<std::string, std::string> crypt_http_responses;
443 public:
444 RGWInitMultipart_ObjStore_S3() {}
445 ~RGWInitMultipart_ObjStore_S3() override {}
446
447 int get_params(optional_yield y) override;
448 void send_response() override;
449 int prepare_encryption(map<string, bufferlist>& attrs) override;
450 };
451
452 class RGWCompleteMultipart_ObjStore_S3 : public RGWCompleteMultipart_ObjStore {
453 public:
454 RGWCompleteMultipart_ObjStore_S3() {}
455 ~RGWCompleteMultipart_ObjStore_S3() override {}
456
457 int get_params(optional_yield y) override;
458 void send_response() override;
459 };
460
461 class RGWAbortMultipart_ObjStore_S3 : public RGWAbortMultipart_ObjStore {
462 public:
463 RGWAbortMultipart_ObjStore_S3() {}
464 ~RGWAbortMultipart_ObjStore_S3() override {}
465
466 void send_response() override;
467 };
468
469 class RGWListMultipart_ObjStore_S3 : public RGWListMultipart_ObjStore {
470 public:
471 RGWListMultipart_ObjStore_S3() {}
472 ~RGWListMultipart_ObjStore_S3() override {}
473
474 void send_response() override;
475 };
476
477 class RGWListBucketMultiparts_ObjStore_S3 : public RGWListBucketMultiparts_ObjStore {
478 public:
479 RGWListBucketMultiparts_ObjStore_S3() {
480 default_max = 1000;
481 }
482 ~RGWListBucketMultiparts_ObjStore_S3() override {}
483
484 void send_response() override;
485 };
486
487 class RGWDeleteMultiObj_ObjStore_S3 : public RGWDeleteMultiObj_ObjStore {
488 public:
489 RGWDeleteMultiObj_ObjStore_S3() {}
490 ~RGWDeleteMultiObj_ObjStore_S3() override {}
491
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;
498 };
499
500 class RGWPutBucketObjectLock_ObjStore_S3 : public RGWPutBucketObjectLock_ObjStore {
501 public:
502 RGWPutBucketObjectLock_ObjStore_S3() {}
503 ~RGWPutBucketObjectLock_ObjStore_S3() override {}
504 void send_response() override;
505 };
506
507 class RGWGetBucketObjectLock_ObjStore_S3 : public RGWGetBucketObjectLock_ObjStore {
508 public:
509 RGWGetBucketObjectLock_ObjStore_S3() {}
510 ~RGWGetBucketObjectLock_ObjStore_S3() {}
511 void send_response() override;
512 };
513
514 class RGWPutObjRetention_ObjStore_S3 : public RGWPutObjRetention_ObjStore {
515 public:
516 RGWPutObjRetention_ObjStore_S3() {}
517 ~RGWPutObjRetention_ObjStore_S3() {}
518 int get_params(optional_yield y) override;
519 void send_response() override;
520 };
521
522 class RGWGetObjRetention_ObjStore_S3 : public RGWGetObjRetention_ObjStore {
523 public:
524 RGWGetObjRetention_ObjStore_S3() {}
525 ~RGWGetObjRetention_ObjStore_S3() {}
526 void send_response() override;
527 };
528
529 class RGWPutObjLegalHold_ObjStore_S3 : public RGWPutObjLegalHold_ObjStore {
530 public:
531 RGWPutObjLegalHold_ObjStore_S3() {}
532 ~RGWPutObjLegalHold_ObjStore_S3() {}
533 void send_response() override;
534 };
535
536 class RGWGetObjLegalHold_ObjStore_S3 : public RGWGetObjLegalHold_ObjStore {
537 public:
538 RGWGetObjLegalHold_ObjStore_S3() {}
539 ~RGWGetObjLegalHold_ObjStore_S3() {}
540 void send_response() override;
541 };
542
543 class RGWGetObjLayout_ObjStore_S3 : public RGWGetObjLayout {
544 public:
545 RGWGetObjLayout_ObjStore_S3() {}
546 ~RGWGetObjLayout_ObjStore_S3() {}
547
548 void send_response() override;
549 };
550
551 class RGWConfigBucketMetaSearch_ObjStore_S3 : public RGWConfigBucketMetaSearch {
552 public:
553 RGWConfigBucketMetaSearch_ObjStore_S3() {}
554 ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
555
556 int get_params(optional_yield y) override;
557 void send_response() override;
558 };
559
560 class RGWGetBucketMetaSearch_ObjStore_S3 : public RGWGetBucketMetaSearch {
561 public:
562 RGWGetBucketMetaSearch_ObjStore_S3() {}
563 ~RGWGetBucketMetaSearch_ObjStore_S3() {}
564
565 void send_response() override;
566 };
567
568 class RGWDelBucketMetaSearch_ObjStore_S3 : public RGWDelBucketMetaSearch {
569 public:
570 RGWDelBucketMetaSearch_ObjStore_S3() {}
571 ~RGWDelBucketMetaSearch_ObjStore_S3() {}
572
573 void send_response() override;
574 };
575
576 class RGWGetBucketPolicyStatus_ObjStore_S3 : public RGWGetBucketPolicyStatus {
577 public:
578 void send_response() override;
579 };
580
581 class RGWPutBucketPublicAccessBlock_ObjStore_S3 : public RGWPutBucketPublicAccessBlock {
582 public:
583 void send_response() override;
584 };
585
586 class RGWGetBucketPublicAccessBlock_ObjStore_S3 : public RGWGetBucketPublicAccessBlock {
587 public:
588 void send_response() override;
589 };
590
591 class RGW_Auth_S3 {
592 public:
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);
597 };
598
599 class RGWHandler_Auth_S3 : public RGWHandler_REST {
600 friend class RGWRESTMgr_S3;
601
602 const rgw::auth::StrategyRegistry& auth_registry;
603
604 public:
605 explicit RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry& auth_registry)
606 : RGWHandler_REST(),
607 auth_registry(auth_registry) {
608 }
609 ~RGWHandler_Auth_S3() override = default;
610
611 static int validate_bucket_name(const string& bucket);
612 static int validate_object_name(const string& bucket);
613
614 int init(rgw::sal::RGWRadosStore *store,
615 struct req_state *s,
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);
619 }
620 int postauth_init(optional_yield) override { return 0; }
621 };
622
623 class RGWHandler_REST_S3 : public RGWHandler_REST {
624 friend class RGWRESTMgr_S3;
625 protected:
626 const rgw::auth::StrategyRegistry& auth_registry;
627 public:
628 static int init_from_header(rgw::sal::RGWRadosStore *store, struct req_state *s, int default_formatter, bool configurable_format);
629
630 explicit RGWHandler_REST_S3(const rgw::auth::StrategyRegistry& auth_registry)
631 : RGWHandler_REST(),
632 auth_registry(auth_registry) {
633 }
634 ~RGWHandler_REST_S3() override = default;
635
636 int init(rgw::sal::RGWRadosStore *store,
637 struct req_state *s,
638 rgw::io::BasicClient *cio) override;
639 int authorize(const DoutPrefixProvider *dpp, optional_yield y) override;
640 int postauth_init(optional_yield y) override;
641 };
642
643 class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
644 protected:
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");
650 }
651 RGWOp *op_get() override;
652 RGWOp *op_head() override;
653 RGWOp *op_post() override;
654 public:
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;
659 };
660
661 class RGWHandler_REST_Bucket_S3 : public RGWHandler_REST_S3 {
662 const bool enable_pubsub;
663 protected:
664 bool is_acl_op() const {
665 return s->info.args.exists("acl");
666 }
667 bool is_cors_op() const {
668 return s->info.args.exists("cors");
669 }
670 bool is_lc_op() const {
671 return s->info.args.exists("lifecycle");
672 }
673 bool is_obj_update_op() const override {
674 return is_acl_op() || is_cors_op();
675 }
676 bool is_tagging_op() const {
677 return s->info.args.exists("tagging");
678 }
679 bool is_request_payment_op() const {
680 return s->info.args.exists("requestPayment");
681 }
682 bool is_policy_op() const {
683 return s->info.args.exists("policy");
684 }
685 bool is_object_lock_op() const {
686 return s->info.args.exists("object-lock");
687 }
688 bool is_notification_op() const {
689 if (enable_pubsub) {
690 return s->info.args.exists("notification");
691 }
692 return false;
693 }
694 bool is_replication_op() const {
695 return s->info.args.exists("replication");
696 }
697 bool is_policy_status_op() {
698 return s->info.args.exists("policyStatus");
699 }
700 bool is_block_public_access_op() {
701 return s->info.args.exists("publicAccessBlock");
702 }
703
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;
711 public:
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;
715 };
716
717 class RGWHandler_REST_Obj_S3 : public RGWHandler_REST_S3 {
718 protected:
719 bool is_acl_op() const {
720 return s->info.args.exists("acl");
721 }
722 bool is_tagging_op() const {
723 return s->info.args.exists("tagging");
724 }
725 bool is_obj_retention_op() const {
726 return s->info.args.exists("retention");
727 }
728 bool is_obj_legal_hold_op() const {
729 return s->info.args.exists("legal-hold");
730 }
731
732 bool is_select_op() const {
733 return s->info.args.exists("select-type");
734 }
735
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();
738 }
739 RGWOp *get_obj_op(bool get_data);
740
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;
747 public:
748 using RGWHandler_REST_S3::RGWHandler_REST_S3;
749 ~RGWHandler_REST_Obj_S3() override = default;
750 };
751
752 class RGWRESTMgr_S3 : public RGWRESTMgr {
753 private:
754 const bool enable_s3website;
755 const bool enable_sts;
756 const bool enable_iam;
757 const bool enable_pubsub;
758 public:
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) {
764 }
765
766 ~RGWRESTMgr_S3() override = default;
767
768 RGWHandler_REST *get_handler(rgw::sal::RGWRadosStore *store,
769 struct req_state* s,
770 const rgw::auth::StrategyRegistry& auth_registry,
771 const std::string& frontend_prefix) override;
772 };
773
774 class RGWHandler_REST_Obj_S3Website;
775
776 static inline bool looks_like_ip_address(const char *bucket)
777 {
778 struct in6_addr a;
779 if (inet_pton(AF_INET6, bucket, static_cast<void*>(&a)) == 1) {
780 return true;
781 }
782 int num_periods = 0;
783 bool expect_period = false;
784 for (const char *b = bucket; *b; ++b) {
785 if (*b == '.') {
786 if (!expect_period)
787 return false;
788 ++num_periods;
789 if (num_periods > 3)
790 return false;
791 expect_period = false;
792 }
793 else if (isdigit(*b)) {
794 expect_period = true;
795 }
796 else {
797 return false;
798 }
799 }
800 return (num_periods == 3);
801 }
802
803 inline int valid_s3_object_name(const string& name) {
804 if (name.size() > 1024) {
805 return -ERR_INVALID_OBJECT_NAME;
806 }
807 if (check_utf8(name.c_str(), name.size())) {
808 return -ERR_INVALID_OBJECT_NAME;
809 }
810 return 0;
811 }
812
813 inline int valid_s3_bucket_name(const string& name, bool relaxed=false)
814 {
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);
819
820 if (len < 3) {
821 // Name too short
822 return -ERR_INVALID_BUCKET_NAME;
823 } else if (len > max) {
824 // Name too long
825 return -ERR_INVALID_BUCKET_NAME;
826 }
827
828 // bucket names must start with a number or letter
829 if (!(isalpha(name[0]) || isdigit(name[0]))) {
830 if (!relaxed)
831 return -ERR_INVALID_BUCKET_NAME;
832 else if (!(name[0] == '_' || name[0] == '.' || name[0] == '-'))
833 return -ERR_INVALID_BUCKET_NAME;
834 }
835
836 // bucket names must end with a number or letter
837 if (!(isalpha(name[len-1]) || isdigit(name[len-1])))
838 if (!relaxed)
839 return -ERR_INVALID_BUCKET_NAME;
840
841 for (const char *s = name.c_str(); *s; ++s) {
842 char c = *s;
843 if (isdigit(c))
844 continue;
845
846 if (isalpha(c)) {
847 // name cannot contain uppercase letters
848 if (relaxed || islower(c))
849 continue;
850 }
851
852 if (c == '_')
853 // name cannot contain underscore
854 if (relaxed)
855 continue;
856
857 if (c == '-')
858 continue;
859
860 if (c == '.') {
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
865 char p = *(s-1);
866 char n = *(s+1);
867 if ((p != '-') && (n != '.') && (n != '-'))
868 continue;
869 } else {
870 continue;
871 }
872 }
873
874 // Invalid character
875 return -ERR_INVALID_BUCKET_NAME;
876 }
877
878 if (looks_like_ip_address(name.c_str()))
879 return -ERR_INVALID_BUCKET_NAME;
880
881 return 0;
882 }
883
884 namespace s3selectEngine
885 {
886 class s3select;
887 class csv_object;
888 }
889
890 class RGWSelectObj_ObjStore_S3 : public RGWGetObj_ObjStore_S3
891 {
892
893 private:
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;
899 std::string m_quot;
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;
906
907 public:
908 unsigned int chunk_number;
909
910 enum header_name_En
911 {
912 EVENT_TYPE,
913 CONTENT_TYPE,
914 MESSAGE_TYPE
915 };
916 static const char* header_name_str[3];
917
918 enum header_value_En
919 {
920 RECORDS,
921 OCTET_STREAM,
922 EVENT
923 };
924 static const char* header_value_str[3];
925
926 RGWSelectObj_ObjStore_S3();
927 virtual ~RGWSelectObj_ObjStore_S3();
928
929 virtual int send_response_data(bufferlist& bl, off_t ofs, off_t len) override;
930
931 virtual int get_params(optional_yield y) override;
932
933 private:
934 void encode_short(char* buff, uint16_t s, int& i);
935
936 void encode_int(char* buff, u_int32_t s, int& i);
937
938 int create_header_records(char* buff);
939
940 std::unique_ptr<boost::crc_32_type> crc32;
941
942 int create_message(std::string&, u_int32_t result_len, u_int32_t header_len);
943
944 int run_s3select(const char* query, const char* input, size_t input_length);
945
946 int extract_by_tag(std::string tag_name, std::string& result);
947
948 void convert_escape_seq(std::string& esc);
949
950 int handle_aws_cli_parameters(std::string& sql_query);
951 };
952
953
954 namespace rgw::auth::s3 {
955
956 class AWSEngine : public rgw::auth::Engine {
957 public:
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;
961
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');
967
968 public:
969 virtual ~VersionAbstractor() {};
970
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;
976
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)>;
984
985 /* Return an instance of Completer for verifying the payload's fingerprint
986 * if necessary. Otherwise caller gets nullptr. Caller may provide secret
987 * key */
988 using completer_factory_t = \
989 std::function<rgw::auth::Completer::cmplptr_t(
990 const boost::optional<std::string>& secret_key)>;
991
992 struct auth_data_t {
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;
999 };
1000
1001 virtual auth_data_t get_auth_data(const req_state* s) const = 0;
1002 };
1003
1004 protected:
1005 CephContext* cct;
1006 const VersionAbstractor& ver_abstractor;
1007
1008 AWSEngine(CephContext* const cct, const VersionAbstractor& ver_abstractor)
1009 : cct(cct),
1010 ver_abstractor(ver_abstractor) {
1011 }
1012
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;
1017
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,
1028 const req_state* s,
1029 optional_yield y) const = 0;
1030
1031 public:
1032 result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s,
1033 optional_yield y) const final;
1034 };
1035
1036
1037 class AWSGeneralAbstractor : public AWSEngine::VersionAbstractor {
1038 CephContext* const cct;
1039
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;
1044
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;
1047
1048 public:
1049 explicit AWSGeneralAbstractor(CephContext* const cct)
1050 : cct(cct) {
1051 }
1052
1053 auth_data_t get_auth_data(const req_state* s) const override;
1054 };
1055
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;
1061
1062 public:
1063 using AWSGeneralAbstractor::AWSGeneralAbstractor;
1064 };
1065
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()));
1070 }
1071
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;
1074
1075 public:
1076 explicit AWSBrowserUploadAbstractor(CephContext*) {
1077 }
1078
1079 auth_data_t get_auth_data(const req_state* s) const override;
1080 };
1081
1082
1083 class LDAPEngine : public AWSEngine {
1084 static rgw::LDAPHelper* ldh;
1085 static std::mutex mtx;
1086
1087 static void init(CephContext* const cct);
1088
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;
1092
1093 protected:
1094 RGWCtl* const ctl;
1095 const rgw::auth::RemoteApplier::Factory* const apl_factory;
1096
1097 acl_strategy_t get_acl_strategy() const;
1098 auth_info_t get_creds_info(const rgw::RGWToken& token) const noexcept;
1099
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,
1107 const req_state* s,
1108 optional_yield y) const override;
1109 public:
1110 LDAPEngine(CephContext* const cct,
1111 RGWCtl* const ctl,
1112 const VersionAbstractor& ver_abstractor,
1113 const rgw::auth::RemoteApplier::Factory* const apl_factory)
1114 : AWSEngine(cct, ver_abstractor),
1115 ctl(ctl),
1116 apl_factory(apl_factory) {
1117 init(cct);
1118 }
1119
1120 using AWSEngine::authenticate;
1121
1122 const char* get_name() const noexcept override {
1123 return "rgw::auth::s3::LDAPEngine";
1124 }
1125
1126 static bool valid();
1127 static void shutdown();
1128 };
1129
1130 class LocalEngine : public AWSEngine {
1131 RGWCtl* const ctl;
1132 const rgw::auth::LocalApplier::Factory* const apl_factory;
1133
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,
1141 const req_state* s,
1142 optional_yield y) const override;
1143 public:
1144 LocalEngine(CephContext* const cct,
1145 RGWCtl* const ctl,
1146 const VersionAbstractor& ver_abstractor,
1147 const rgw::auth::LocalApplier::Factory* const apl_factory)
1148 : AWSEngine(cct, ver_abstractor),
1149 ctl(ctl),
1150 apl_factory(apl_factory) {
1151 }
1152
1153 using AWSEngine::authenticate;
1154
1155 const char* get_name() const noexcept override {
1156 return "rgw::auth::s3::LocalEngine";
1157 }
1158 };
1159
1160 class STSEngine : public AWSEngine {
1161 RGWCtl* const ctl;
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;
1165
1166 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
1167 using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
1168
1169 acl_strategy_t get_acl_strategy() const { return nullptr; };
1170 auth_info_t get_creds_info(const STS::SessionToken& token) const noexcept;
1171
1172 int get_session_token(const DoutPrefixProvider* dpp, const std::string_view& session_token,
1173 STS::SessionToken& token) const;
1174
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,
1182 const req_state* s,
1183 optional_yield y) const override;
1184 public:
1185 STSEngine(CephContext* const cct,
1186 RGWCtl* const ctl,
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),
1192 ctl(ctl),
1193 local_apl_factory(local_apl_factory),
1194 remote_apl_factory(remote_apl_factory),
1195 role_apl_factory(role_apl_factory) {
1196 }
1197
1198 using AWSEngine::authenticate;
1199
1200 const char* get_name() const noexcept override {
1201 return "rgw::auth::s3::STSEngine";
1202 }
1203 };
1204
1205 class S3AnonymousEngine : public rgw::auth::AnonymousEngine {
1206 bool is_applicable(const req_state* s) const noexcept override;
1207
1208 public:
1209 /* Let's reuse the parent class' constructor. */
1210 using rgw::auth::AnonymousEngine::AnonymousEngine;
1211
1212 const char* get_name() const noexcept override {
1213 return "rgw::auth::s3::S3AnonymousEngine";
1214 }
1215 };
1216
1217
1218 } // namespace rgw::auth::s3