]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_s3.h
bump version to 18.2.2-pve1
[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(const DoutPrefixProvider *dpp, 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::BucketList& 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 std::string startAfter;
174 std::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::sal::DataProcessor> *filter,
281 rgw::sal::DataProcessor *cb) override;
282 int get_decrypt_filter(std::unique_ptr<RGWGetObj_Filter>* filter,
283 RGWGetObj_Filter* cb,
284 std::map<std::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 std::map<std::string, std::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::Object* 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::sal::DataProcessor> *filter,
320 rgw::sal::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::Driver* driver, req_state *s, std::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 RGWGetBucketEncryption_ObjStore_S3 : public RGWGetBucketEncryption_ObjStore {
424 public:
425 RGWGetBucketEncryption_ObjStore_S3() {}
426 ~RGWGetBucketEncryption_ObjStore_S3() override {}
427
428 void send_response() override;
429 };
430
431 class RGWPutBucketEncryption_ObjStore_S3 : public RGWPutBucketEncryption_ObjStore {
432 public:
433 RGWPutBucketEncryption_ObjStore_S3() {}
434 ~RGWPutBucketEncryption_ObjStore_S3() override {}
435
436 void send_response() override;
437 };
438
439 class RGWDeleteBucketEncryption_ObjStore_S3 : public RGWDeleteBucketEncryption_ObjStore {
440 public:
441 RGWDeleteBucketEncryption_ObjStore_S3() {}
442 ~RGWDeleteBucketEncryption_ObjStore_S3() override {}
443
444 void send_response() override;
445 };
446
447 class RGWGetRequestPayment_ObjStore_S3 : public RGWGetRequestPayment {
448 public:
449 RGWGetRequestPayment_ObjStore_S3() {}
450 ~RGWGetRequestPayment_ObjStore_S3() override {}
451
452 void send_response() override;
453 };
454
455 class RGWSetRequestPayment_ObjStore_S3 : public RGWSetRequestPayment {
456 public:
457 RGWSetRequestPayment_ObjStore_S3() {}
458 ~RGWSetRequestPayment_ObjStore_S3() override {}
459
460 int get_params(optional_yield y) override;
461 void send_response() override;
462 };
463
464 class RGWInitMultipart_ObjStore_S3 : public RGWInitMultipart_ObjStore {
465 private:
466 std::map<std::string, std::string> crypt_http_responses;
467 public:
468 RGWInitMultipart_ObjStore_S3() {}
469 ~RGWInitMultipart_ObjStore_S3() override {}
470
471 int get_params(optional_yield y) override;
472 void send_response() override;
473 int prepare_encryption(std::map<std::string, bufferlist>& attrs) override;
474 };
475
476 class RGWCompleteMultipart_ObjStore_S3 : public RGWCompleteMultipart_ObjStore {
477 public:
478 RGWCompleteMultipart_ObjStore_S3() {}
479 ~RGWCompleteMultipart_ObjStore_S3() override {}
480
481 int get_params(optional_yield y) override;
482 void send_response() override;
483 };
484
485 class RGWAbortMultipart_ObjStore_S3 : public RGWAbortMultipart_ObjStore {
486 public:
487 RGWAbortMultipart_ObjStore_S3() {}
488 ~RGWAbortMultipart_ObjStore_S3() override {}
489
490 void send_response() override;
491 };
492
493 class RGWListMultipart_ObjStore_S3 : public RGWListMultipart_ObjStore {
494 public:
495 RGWListMultipart_ObjStore_S3() {}
496 ~RGWListMultipart_ObjStore_S3() override {}
497
498 void send_response() override;
499 };
500
501 class RGWListBucketMultiparts_ObjStore_S3 : public RGWListBucketMultiparts_ObjStore {
502 public:
503 RGWListBucketMultiparts_ObjStore_S3() {
504 default_max = 1000;
505 }
506 ~RGWListBucketMultiparts_ObjStore_S3() override {}
507
508 void send_response() override;
509 };
510
511 class RGWDeleteMultiObj_ObjStore_S3 : public RGWDeleteMultiObj_ObjStore {
512 public:
513 RGWDeleteMultiObj_ObjStore_S3() {}
514 ~RGWDeleteMultiObj_ObjStore_S3() override {}
515
516 int get_params(optional_yield y) override;
517 void send_status() override;
518 void begin_response() override;
519 void send_partial_response(const rgw_obj_key& key, bool delete_marker,
520 const std::string& marker_version_id, int ret,
521 boost::asio::deadline_timer *formatter_flush_cond) override;
522 void end_response() override;
523 };
524
525 class RGWPutBucketObjectLock_ObjStore_S3 : public RGWPutBucketObjectLock_ObjStore {
526 public:
527 RGWPutBucketObjectLock_ObjStore_S3() {}
528 ~RGWPutBucketObjectLock_ObjStore_S3() override {}
529 void send_response() override;
530 };
531
532 class RGWGetBucketObjectLock_ObjStore_S3 : public RGWGetBucketObjectLock_ObjStore {
533 public:
534 RGWGetBucketObjectLock_ObjStore_S3() {}
535 ~RGWGetBucketObjectLock_ObjStore_S3() {}
536 void send_response() override;
537 };
538
539 class RGWPutObjRetention_ObjStore_S3 : public RGWPutObjRetention_ObjStore {
540 public:
541 RGWPutObjRetention_ObjStore_S3() {}
542 ~RGWPutObjRetention_ObjStore_S3() {}
543 int get_params(optional_yield y) override;
544 void send_response() override;
545 };
546
547 class RGWGetObjRetention_ObjStore_S3 : public RGWGetObjRetention_ObjStore {
548 public:
549 RGWGetObjRetention_ObjStore_S3() {}
550 ~RGWGetObjRetention_ObjStore_S3() {}
551 void send_response() override;
552 };
553
554 class RGWPutObjLegalHold_ObjStore_S3 : public RGWPutObjLegalHold_ObjStore {
555 public:
556 RGWPutObjLegalHold_ObjStore_S3() {}
557 ~RGWPutObjLegalHold_ObjStore_S3() {}
558 void send_response() override;
559 };
560
561 class RGWGetObjLegalHold_ObjStore_S3 : public RGWGetObjLegalHold_ObjStore {
562 public:
563 RGWGetObjLegalHold_ObjStore_S3() {}
564 ~RGWGetObjLegalHold_ObjStore_S3() {}
565 void send_response() override;
566 };
567
568 class RGWGetObjLayout_ObjStore_S3 : public RGWGetObjLayout {
569 public:
570 RGWGetObjLayout_ObjStore_S3() {}
571 ~RGWGetObjLayout_ObjStore_S3() {}
572
573 void send_response() override;
574 };
575
576 class RGWConfigBucketMetaSearch_ObjStore_S3 : public RGWConfigBucketMetaSearch {
577 public:
578 RGWConfigBucketMetaSearch_ObjStore_S3() {}
579 ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
580
581 int get_params(optional_yield y) override;
582 void send_response() override;
583 };
584
585 class RGWGetBucketMetaSearch_ObjStore_S3 : public RGWGetBucketMetaSearch {
586 public:
587 RGWGetBucketMetaSearch_ObjStore_S3() {}
588 ~RGWGetBucketMetaSearch_ObjStore_S3() {}
589
590 void send_response() override;
591 };
592
593 class RGWDelBucketMetaSearch_ObjStore_S3 : public RGWDelBucketMetaSearch {
594 public:
595 RGWDelBucketMetaSearch_ObjStore_S3() {}
596 ~RGWDelBucketMetaSearch_ObjStore_S3() {}
597
598 void send_response() override;
599 };
600
601 class RGWGetBucketPolicyStatus_ObjStore_S3 : public RGWGetBucketPolicyStatus {
602 public:
603 void send_response() override;
604 };
605
606 class RGWPutBucketPublicAccessBlock_ObjStore_S3 : public RGWPutBucketPublicAccessBlock {
607 public:
608 void send_response() override;
609 };
610
611 class RGWGetBucketPublicAccessBlock_ObjStore_S3 : public RGWGetBucketPublicAccessBlock {
612 public:
613 void send_response() override;
614 };
615
616 class RGW_Auth_S3 {
617 public:
618 static int authorize(const DoutPrefixProvider *dpp,
619 rgw::sal::Driver* driver,
620 const rgw::auth::StrategyRegistry& auth_registry,
621 req_state *s, optional_yield y);
622 };
623
624 class RGWHandler_Auth_S3 : public RGWHandler_REST {
625 friend class RGWRESTMgr_S3;
626
627 const rgw::auth::StrategyRegistry& auth_registry;
628
629 public:
630 explicit RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry& auth_registry)
631 : RGWHandler_REST(),
632 auth_registry(auth_registry) {
633 }
634 ~RGWHandler_Auth_S3() override = default;
635
636 static int validate_bucket_name(const std::string& bucket);
637 static int validate_object_name(const std::string& bucket);
638
639 int init(rgw::sal::Driver* driver,
640 req_state *s,
641 rgw::io::BasicClient *cio) override;
642 int authorize(const DoutPrefixProvider *dpp, optional_yield y) override {
643 return RGW_Auth_S3::authorize(dpp, driver, auth_registry, s, y);
644 }
645 int postauth_init(optional_yield) override { return 0; }
646 };
647
648 class RGWHandler_REST_S3 : public RGWHandler_REST {
649 friend class RGWRESTMgr_S3;
650 protected:
651 const rgw::auth::StrategyRegistry& auth_registry;
652 public:
653 static int init_from_header(rgw::sal::Driver* driver, req_state *s, RGWFormat default_formatter,
654 bool configurable_format);
655
656 explicit RGWHandler_REST_S3(const rgw::auth::StrategyRegistry& auth_registry)
657 : RGWHandler_REST(),
658 auth_registry(auth_registry) {
659 }
660 ~RGWHandler_REST_S3() override = default;
661
662 int init(rgw::sal::Driver* driver,
663 req_state *s,
664 rgw::io::BasicClient *cio) override;
665 int authorize(const DoutPrefixProvider *dpp, optional_yield y) override;
666 int postauth_init(optional_yield y) override;
667 };
668
669 class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
670 protected:
671 bool is_usage_op() const {
672 return s->info.args.exists("usage");
673 }
674 RGWOp *op_get() override;
675 RGWOp *op_head() override;
676 public:
677 RGWHandler_REST_Service_S3(const rgw::auth::StrategyRegistry& auth_registry) :
678 RGWHandler_REST_S3(auth_registry) {}
679 ~RGWHandler_REST_Service_S3() override = default;
680 };
681
682 class RGWHandler_REST_Bucket_S3 : public RGWHandler_REST_S3 {
683 const bool enable_pubsub;
684 protected:
685 bool is_acl_op() const {
686 return s->info.args.exists("acl");
687 }
688 bool is_cors_op() const {
689 return s->info.args.exists("cors");
690 }
691 bool is_lc_op() const {
692 return s->info.args.exists("lifecycle");
693 }
694 bool is_obj_update_op() const override {
695 return is_acl_op() || is_cors_op();
696 }
697 bool is_tagging_op() const {
698 return s->info.args.exists("tagging");
699 }
700 bool is_request_payment_op() const {
701 return s->info.args.exists("requestPayment");
702 }
703 bool is_policy_op() const {
704 return s->info.args.exists("policy");
705 }
706 bool is_object_lock_op() const {
707 return s->info.args.exists("object-lock");
708 }
709 bool is_notification_op() const {
710 if (enable_pubsub) {
711 return s->info.args.exists("notification");
712 }
713 return false;
714 }
715 bool is_replication_op() const {
716 return s->info.args.exists("replication");
717 }
718 bool is_policy_status_op() {
719 return s->info.args.exists("policyStatus");
720 }
721 bool is_block_public_access_op() {
722 return s->info.args.exists("publicAccessBlock");
723 }
724 bool is_bucket_encryption_op() {
725 return s->info.args.exists("encryption");
726 }
727
728 RGWOp *get_obj_op(bool get_data) const;
729 RGWOp *op_get() override;
730 RGWOp *op_head() override;
731 RGWOp *op_put() override;
732 RGWOp *op_delete() override;
733 RGWOp *op_post() override;
734 RGWOp *op_options() override;
735 public:
736 RGWHandler_REST_Bucket_S3(const rgw::auth::StrategyRegistry& auth_registry, bool _enable_pubsub) :
737 RGWHandler_REST_S3(auth_registry), enable_pubsub(_enable_pubsub) {}
738 ~RGWHandler_REST_Bucket_S3() override = default;
739 };
740
741 class RGWHandler_REST_Obj_S3 : public RGWHandler_REST_S3 {
742 protected:
743 bool is_acl_op() const {
744 return s->info.args.exists("acl");
745 }
746 bool is_tagging_op() const {
747 return s->info.args.exists("tagging");
748 }
749 bool is_obj_retention_op() const {
750 return s->info.args.exists("retention");
751 }
752 bool is_obj_legal_hold_op() const {
753 return s->info.args.exists("legal-hold");
754 }
755
756 bool is_select_op() const {
757 return s->info.args.exists("select-type");
758 }
759
760 bool is_obj_update_op() const override {
761 return is_acl_op() || is_tagging_op() || is_obj_retention_op() || is_obj_legal_hold_op() || is_select_op();
762 }
763 RGWOp *get_obj_op(bool get_data);
764
765 RGWOp *op_get() override;
766 RGWOp *op_head() override;
767 RGWOp *op_put() override;
768 RGWOp *op_delete() override;
769 RGWOp *op_post() override;
770 RGWOp *op_options() override;
771 public:
772 using RGWHandler_REST_S3::RGWHandler_REST_S3;
773 ~RGWHandler_REST_Obj_S3() override = default;
774 };
775
776 class RGWRESTMgr_S3 : public RGWRESTMgr {
777 private:
778 const bool enable_s3website;
779 const bool enable_sts;
780 const bool enable_iam;
781 const bool enable_pubsub;
782 public:
783 explicit RGWRESTMgr_S3(bool _enable_s3website=false, bool _enable_sts=false, bool _enable_iam=false, bool _enable_pubsub=false)
784 : enable_s3website(_enable_s3website),
785 enable_sts(_enable_sts),
786 enable_iam(_enable_iam),
787 enable_pubsub(_enable_pubsub) {
788 }
789
790 ~RGWRESTMgr_S3() override = default;
791
792 RGWHandler_REST *get_handler(rgw::sal::Driver* driver,
793 req_state* s,
794 const rgw::auth::StrategyRegistry& auth_registry,
795 const std::string& frontend_prefix) override;
796 };
797
798 class RGWHandler_REST_Obj_S3Website;
799
800 static inline bool looks_like_ip_address(const char *bucket)
801 {
802 struct in6_addr a;
803 if (inet_pton(AF_INET6, bucket, static_cast<void*>(&a)) == 1) {
804 return true;
805 }
806 int num_periods = 0;
807 bool expect_period = false;
808 for (const char *b = bucket; *b; ++b) {
809 if (*b == '.') {
810 if (!expect_period)
811 return false;
812 ++num_periods;
813 if (num_periods > 3)
814 return false;
815 expect_period = false;
816 }
817 else if (isdigit(*b)) {
818 expect_period = true;
819 }
820 else {
821 return false;
822 }
823 }
824 return (num_periods == 3);
825 }
826
827 inline int valid_s3_object_name(const std::string& name) {
828 if (name.size() > 1024) {
829 return -ERR_INVALID_OBJECT_NAME;
830 }
831 if (check_utf8(name.c_str(), name.size())) {
832 return -ERR_INVALID_OBJECT_NAME;
833 }
834 return 0;
835 }
836
837 inline int valid_s3_bucket_name(const std::string& name, bool relaxed=false)
838 {
839 // This function enforces Amazon's spec for bucket names.
840 // (The requirements, not the recommendations.)
841 int len = name.size();
842 int max = (relaxed ? 255 : 63);
843
844 if (len < 3) {
845 // Name too short
846 return -ERR_INVALID_BUCKET_NAME;
847 } else if (len > max) {
848 // Name too long
849 return -ERR_INVALID_BUCKET_NAME;
850 }
851
852 // bucket names must start with a number or letter
853 if (!(isalpha(name[0]) || isdigit(name[0]))) {
854 if (!relaxed)
855 return -ERR_INVALID_BUCKET_NAME;
856 else if (!(name[0] == '_' || name[0] == '.' || name[0] == '-'))
857 return -ERR_INVALID_BUCKET_NAME;
858 }
859
860 // bucket names must end with a number or letter
861 if (!(isalpha(name[len-1]) || isdigit(name[len-1])))
862 if (!relaxed)
863 return -ERR_INVALID_BUCKET_NAME;
864
865 for (const char *s = name.c_str(); *s; ++s) {
866 char c = *s;
867 if (isdigit(c))
868 continue;
869
870 if (isalpha(c)) {
871 // name cannot contain uppercase letters
872 if (relaxed || islower(c))
873 continue;
874 }
875
876 if (c == '_')
877 // name cannot contain underscore
878 if (relaxed)
879 continue;
880
881 if (c == '-')
882 continue;
883
884 if (c == '.') {
885 if (!relaxed && s && *s) {
886 // name cannot have consecutive periods or dashes
887 // adjacent to periods
888 // ensure s is neither the first nor the last character
889 char p = *(s-1);
890 char n = *(s+1);
891 if ((p != '-') && (n != '.') && (n != '-'))
892 continue;
893 } else {
894 continue;
895 }
896 }
897
898 // Invalid character
899 return -ERR_INVALID_BUCKET_NAME;
900 }
901
902 if (looks_like_ip_address(name.c_str()))
903 return -ERR_INVALID_BUCKET_NAME;
904
905 return 0;
906 }
907
908 namespace rgw::auth::s3 {
909
910 class AWSEngine : public rgw::auth::Engine {
911 public:
912 class VersionAbstractor {
913 static constexpr size_t DIGEST_SIZE_V2 = CEPH_CRYPTO_HMACSHA1_DIGESTSIZE;
914 static constexpr size_t DIGEST_SIZE_V4 = CEPH_CRYPTO_HMACSHA256_DIGESTSIZE;
915
916 /* Knowing the signature max size allows us to employ the sstring, and thus
917 * avoid dynamic allocations. The multiplier comes from representing digest
918 * in the base64-encoded form. */
919 static constexpr size_t SIGNATURE_MAX_SIZE = \
920 std::max(DIGEST_SIZE_V2, DIGEST_SIZE_V4) * 2 + sizeof('\0');
921
922 public:
923 virtual ~VersionAbstractor() {};
924
925 using access_key_id_t = std::string_view;
926 using client_signature_t = std::string_view;
927 using session_token_t = std::string_view;
928 using server_signature_t = basic_sstring<char, uint16_t, SIGNATURE_MAX_SIZE>;
929 using string_to_sign_t = std::string;
930
931 /* Transformation for crafting the AWS signature at server side which is
932 * used later to compare with the user-provided one. The methodology for
933 * doing that depends on AWS auth version. */
934 using signature_factory_t = \
935 std::function<server_signature_t(CephContext* cct,
936 const std::string& secret_key,
937 const string_to_sign_t& string_to_sign)>;
938
939 /* Return an instance of Completer for verifying the payload's fingerprint
940 * if necessary. Otherwise caller gets nullptr. Caller may provide secret
941 * key */
942 using completer_factory_t = \
943 std::function<rgw::auth::Completer::cmplptr_t(
944 const boost::optional<std::string>& secret_key)>;
945
946 struct auth_data_t {
947 access_key_id_t access_key_id;
948 client_signature_t client_signature;
949 session_token_t session_token;
950 string_to_sign_t string_to_sign;
951 signature_factory_t signature_factory;
952 completer_factory_t completer_factory;
953 };
954
955 virtual auth_data_t get_auth_data(const req_state* s) const = 0;
956 };
957
958 protected:
959 CephContext* cct;
960 const VersionAbstractor& ver_abstractor;
961
962 AWSEngine(CephContext* const cct, const VersionAbstractor& ver_abstractor)
963 : cct(cct),
964 ver_abstractor(ver_abstractor) {
965 }
966
967 using result_t = rgw::auth::Engine::result_t;
968 using string_to_sign_t = VersionAbstractor::string_to_sign_t;
969 using signature_factory_t = VersionAbstractor::signature_factory_t;
970 using completer_factory_t = VersionAbstractor::completer_factory_t;
971
972 /* TODO(rzarzynski): clean up. We've too many input parameter hee. Also
973 * the signature get_auth_data() of VersionAbstractor is too complicated.
974 * Replace these thing with a simple, dedicated structure. */
975 virtual result_t authenticate(const DoutPrefixProvider* dpp,
976 const std::string_view& access_key_id,
977 const std::string_view& signature,
978 const std::string_view& session_token,
979 const string_to_sign_t& string_to_sign,
980 const signature_factory_t& signature_factory,
981 const completer_factory_t& completer_factory,
982 const req_state* s,
983 optional_yield y) const = 0;
984
985 public:
986 result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s,
987 optional_yield y) const final;
988 };
989
990
991 class AWSGeneralAbstractor : public AWSEngine::VersionAbstractor {
992 CephContext* const cct;
993
994 virtual boost::optional<std::string>
995 get_v4_canonical_headers(const req_info& info,
996 const std::string_view& signedheaders,
997 const bool using_qs) const;
998
999 auth_data_t get_auth_data_v2(const req_state* s) const;
1000 auth_data_t get_auth_data_v4(const req_state* s, const bool using_qs) const;
1001
1002 public:
1003 explicit AWSGeneralAbstractor(CephContext* const cct)
1004 : cct(cct) {
1005 }
1006
1007 auth_data_t get_auth_data(const req_state* s) const override;
1008 };
1009
1010 class AWSGeneralBoto2Abstractor : public AWSGeneralAbstractor {
1011 boost::optional<std::string>
1012 get_v4_canonical_headers(const req_info& info,
1013 const std::string_view& signedheaders,
1014 const bool using_qs) const override;
1015
1016 public:
1017 using AWSGeneralAbstractor::AWSGeneralAbstractor;
1018 };
1019
1020 class AWSBrowserUploadAbstractor : public AWSEngine::VersionAbstractor {
1021 static std::string to_string(ceph::bufferlist bl) {
1022 return std::string(bl.c_str(),
1023 static_cast<std::string::size_type>(bl.length()));
1024 }
1025
1026 auth_data_t get_auth_data_v2(const req_state* s) const;
1027 auth_data_t get_auth_data_v4(const req_state* s) const;
1028
1029 public:
1030 explicit AWSBrowserUploadAbstractor(CephContext*) {
1031 }
1032
1033 auth_data_t get_auth_data(const req_state* s) const override;
1034 };
1035
1036 class AWSSignerV4 {
1037 const DoutPrefixProvider *dpp;
1038 CephContext *cct;
1039
1040 public:
1041 AWSSignerV4(const DoutPrefixProvider *_dpp) : dpp(_dpp),
1042 cct(_dpp->get_cct()) {}
1043
1044 using access_key_id_t = std::string_view;
1045 using string_to_sign_t = AWSEngine::VersionAbstractor::string_to_sign_t;
1046 using signature_headers_t = std::map<std::string, std::string>;
1047
1048 struct prepare_result_t;
1049
1050 using signature_factory_t = \
1051 std::function<signature_headers_t(const DoutPrefixProvider* dpp,
1052 const std::string& secret_key,
1053 const prepare_result_t&)>;
1054
1055 struct prepare_result_t {
1056 access_key_id_t access_key_id;
1057 std::string date;
1058 std::string scope;
1059 std::string signed_headers;
1060 string_to_sign_t string_to_sign;
1061 std::map<std::string, std::string> extra_headers;
1062 signature_factory_t signature_factory;
1063 };
1064
1065 static prepare_result_t prepare(const DoutPrefixProvider *dpp,
1066 const std::string& access_key_id,
1067 const string& region,
1068 const string& service,
1069 const req_info& info,
1070 const bufferlist *opt_content,
1071 bool s3_op);
1072 };
1073
1074
1075 extern AWSSignerV4::signature_headers_t
1076 gen_v4_signature(const DoutPrefixProvider *dpp,
1077 const std::string_view& secret_key,
1078 const AWSSignerV4::prepare_result_t& sig_info);
1079
1080 class LDAPEngine : public AWSEngine {
1081 static rgw::LDAPHelper* ldh;
1082 static std::mutex mtx;
1083
1084 static void init(CephContext* const cct);
1085
1086 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
1087 using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
1088 using result_t = rgw::auth::Engine::result_t;
1089
1090 protected:
1091 rgw::sal::Driver* driver;
1092 const rgw::auth::RemoteApplier::Factory* const apl_factory;
1093
1094 acl_strategy_t get_acl_strategy() const;
1095 auth_info_t get_creds_info(const rgw::RGWToken& token) const noexcept;
1096
1097 result_t authenticate(const DoutPrefixProvider* dpp,
1098 const std::string_view& access_key_id,
1099 const std::string_view& signature,
1100 const std::string_view& session_token,
1101 const string_to_sign_t& string_to_sign,
1102 const signature_factory_t&,
1103 const completer_factory_t& completer_factory,
1104 const req_state* s,
1105 optional_yield y) const override;
1106 public:
1107 LDAPEngine(CephContext* const cct,
1108 rgw::sal::Driver* driver,
1109 const VersionAbstractor& ver_abstractor,
1110 const rgw::auth::RemoteApplier::Factory* const apl_factory)
1111 : AWSEngine(cct, ver_abstractor),
1112 driver(driver),
1113 apl_factory(apl_factory) {
1114 init(cct);
1115 }
1116
1117 using AWSEngine::authenticate;
1118
1119 const char* get_name() const noexcept override {
1120 return "rgw::auth::s3::LDAPEngine";
1121 }
1122
1123 static bool valid();
1124 static void shutdown();
1125 };
1126
1127 class LocalEngine : public AWSEngine {
1128 rgw::sal::Driver* driver;
1129 const rgw::auth::LocalApplier::Factory* const apl_factory;
1130
1131 result_t authenticate(const DoutPrefixProvider* dpp,
1132 const std::string_view& access_key_id,
1133 const std::string_view& signature,
1134 const std::string_view& session_token,
1135 const string_to_sign_t& string_to_sign,
1136 const signature_factory_t& signature_factory,
1137 const completer_factory_t& completer_factory,
1138 const req_state* s,
1139 optional_yield y) const override;
1140 public:
1141 LocalEngine(CephContext* const cct,
1142 rgw::sal::Driver* driver,
1143 const VersionAbstractor& ver_abstractor,
1144 const rgw::auth::LocalApplier::Factory* const apl_factory)
1145 : AWSEngine(cct, ver_abstractor),
1146 driver(driver),
1147 apl_factory(apl_factory) {
1148 }
1149
1150 using AWSEngine::authenticate;
1151
1152 const char* get_name() const noexcept override {
1153 return "rgw::auth::s3::LocalEngine";
1154 }
1155 };
1156
1157 class STSEngine : public AWSEngine {
1158 rgw::sal::Driver* driver;
1159 const rgw::auth::LocalApplier::Factory* const local_apl_factory;
1160 const rgw::auth::RemoteApplier::Factory* const remote_apl_factory;
1161 const rgw::auth::RoleApplier::Factory* const role_apl_factory;
1162
1163 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
1164 using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
1165
1166 acl_strategy_t get_acl_strategy() const { return nullptr; };
1167 auth_info_t get_creds_info(const STS::SessionToken& token) const noexcept;
1168
1169 int get_session_token(const DoutPrefixProvider* dpp, const std::string_view& session_token,
1170 STS::SessionToken& token) const;
1171
1172 result_t authenticate(const DoutPrefixProvider* dpp,
1173 const std::string_view& access_key_id,
1174 const std::string_view& signature,
1175 const std::string_view& session_token,
1176 const string_to_sign_t& string_to_sign,
1177 const signature_factory_t& signature_factory,
1178 const completer_factory_t& completer_factory,
1179 const req_state* s,
1180 optional_yield y) const override;
1181 public:
1182 STSEngine(CephContext* const cct,
1183 rgw::sal::Driver* driver,
1184 const VersionAbstractor& ver_abstractor,
1185 const rgw::auth::LocalApplier::Factory* const local_apl_factory,
1186 const rgw::auth::RemoteApplier::Factory* const remote_apl_factory,
1187 const rgw::auth::RoleApplier::Factory* const role_apl_factory)
1188 : AWSEngine(cct, ver_abstractor),
1189 driver(driver),
1190 local_apl_factory(local_apl_factory),
1191 remote_apl_factory(remote_apl_factory),
1192 role_apl_factory(role_apl_factory) {
1193 }
1194
1195 using AWSEngine::authenticate;
1196
1197 const char* get_name() const noexcept override {
1198 return "rgw::auth::s3::STSEngine";
1199 }
1200 };
1201
1202 class S3AnonymousEngine : public rgw::auth::AnonymousEngine {
1203 bool is_applicable(const req_state* s) const noexcept override;
1204
1205 public:
1206 /* Let's reuse the parent class' constructor. */
1207 using rgw::auth::AnonymousEngine::AnonymousEngine;
1208
1209 const char* get_name() const noexcept override {
1210 return "rgw::auth::s3::S3AnonymousEngine";
1211 }
1212 };
1213
1214
1215 } // namespace rgw::auth::s3