]> git.proxmox.com Git - ceph.git/blob - ceph/src/rgw/rgw_rest_s3.h
65d1b36ad1531139d3b5eb70c55f8a5b509c4e0b
[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
3
4 #ifndef CEPH_RGW_REST_S3_H
5
6 #define CEPH_RGW_REST_S3_H
7 #define TIME_BUF_SIZE 128
8
9 #include <mutex>
10
11 #include <boost/utility/string_view.hpp>
12 #include <boost/container/static_vector.hpp>
13
14 #include "common/backport14.h"
15 #include "common/sstring.hh"
16 #include "rgw_op.h"
17 #include "rgw_rest.h"
18 #include "rgw_http_errors.h"
19 #include "rgw_acl_s3.h"
20 #include "rgw_policy_s3.h"
21 #include "rgw_lc_s3.h"
22 #include "rgw_keystone.h"
23 #include "rgw_rest_conn.h"
24 #include "rgw_ldap.h"
25 #include "rgw_rest.h"
26
27 #include "rgw_token.h"
28 #include "include/assert.h"
29
30 #include "rgw_auth.h"
31 #include "rgw_auth_filters.h"
32
33 #define RGW_AUTH_GRACE_MINS 15
34
35 struct rgw_http_error {
36 int http_ret;
37 const char *s3_code;
38 };
39
40 void rgw_get_errno_s3(struct rgw_http_error *e, int err_no);
41
42 class RGWGetObj_ObjStore_S3 : public RGWGetObj_ObjStore
43 {
44 protected:
45 // Serving a custom error page from an object is really a 200 response with
46 // just the status line altered.
47 int custom_http_ret = 0;
48 std::map<std::string, std::string> crypt_http_responses;
49 public:
50 RGWGetObj_ObjStore_S3() {}
51 ~RGWGetObj_ObjStore_S3() override {}
52
53 int get_params() override;
54 int send_response_data_error() override;
55 int send_response_data(bufferlist& bl, off_t ofs, off_t len) override;
56 void set_custom_http_response(int http_ret) { custom_http_ret = http_ret; }
57 int get_decrypt_filter(std::unique_ptr<RGWGetDataCB>* filter,
58 RGWGetDataCB* cb,
59 bufferlist* manifest_bl) override;
60 };
61
62 class RGWListBuckets_ObjStore_S3 : public RGWListBuckets_ObjStore {
63 public:
64 RGWListBuckets_ObjStore_S3() {}
65 ~RGWListBuckets_ObjStore_S3() override {}
66
67 int get_params() override {
68 limit = -1; /* no limit */
69 return 0;
70 }
71 void send_response_begin(bool has_buckets) override;
72 void send_response_data(RGWUserBuckets& buckets) override;
73 void send_response_end() override;
74 };
75
76 class RGWGetUsage_ObjStore_S3 : public RGWGetUsage_ObjStore {
77 public:
78 RGWGetUsage_ObjStore_S3() {}
79 ~RGWGetUsage_ObjStore_S3() override {}
80
81 int get_params() override ;
82 void send_response() override;
83 };
84
85 class RGWListBucket_ObjStore_S3 : public RGWListBucket_ObjStore {
86 bool objs_container;
87 public:
88 RGWListBucket_ObjStore_S3() : objs_container(false) {
89 default_max = 1000;
90 }
91 ~RGWListBucket_ObjStore_S3() override {}
92
93 int get_params() override;
94 void send_response() override;
95 void send_versioned_response();
96 };
97
98 class RGWGetBucketLogging_ObjStore_S3 : public RGWGetBucketLogging {
99 public:
100 RGWGetBucketLogging_ObjStore_S3() {}
101 ~RGWGetBucketLogging_ObjStore_S3() override {}
102
103 void send_response() override;
104 };
105
106 class RGWGetBucketLocation_ObjStore_S3 : public RGWGetBucketLocation {
107 public:
108 RGWGetBucketLocation_ObjStore_S3() {}
109 ~RGWGetBucketLocation_ObjStore_S3() override {}
110
111 void send_response() override;
112 };
113
114 class RGWGetBucketVersioning_ObjStore_S3 : public RGWGetBucketVersioning {
115 public:
116 RGWGetBucketVersioning_ObjStore_S3() {}
117 ~RGWGetBucketVersioning_ObjStore_S3() override {}
118
119 void send_response() override;
120 };
121
122 class RGWSetBucketVersioning_ObjStore_S3 : public RGWSetBucketVersioning {
123 public:
124 RGWSetBucketVersioning_ObjStore_S3() {}
125 ~RGWSetBucketVersioning_ObjStore_S3() override {}
126
127 int get_params() override;
128 void send_response() override;
129 };
130
131 class RGWGetBucketWebsite_ObjStore_S3 : public RGWGetBucketWebsite {
132 public:
133 RGWGetBucketWebsite_ObjStore_S3() {}
134 ~RGWGetBucketWebsite_ObjStore_S3() override {}
135
136 void send_response() override;
137 };
138
139 class RGWSetBucketWebsite_ObjStore_S3 : public RGWSetBucketWebsite {
140 public:
141 RGWSetBucketWebsite_ObjStore_S3() {}
142 ~RGWSetBucketWebsite_ObjStore_S3() override {}
143
144 int get_params() override;
145 void send_response() override;
146 };
147
148 class RGWDeleteBucketWebsite_ObjStore_S3 : public RGWDeleteBucketWebsite {
149 public:
150 RGWDeleteBucketWebsite_ObjStore_S3() {}
151 ~RGWDeleteBucketWebsite_ObjStore_S3() override {}
152
153 void send_response() override;
154 };
155
156 class RGWStatBucket_ObjStore_S3 : public RGWStatBucket_ObjStore {
157 public:
158 RGWStatBucket_ObjStore_S3() {}
159 ~RGWStatBucket_ObjStore_S3() override {}
160
161 void send_response() override;
162 };
163
164 class RGWCreateBucket_ObjStore_S3 : public RGWCreateBucket_ObjStore {
165 public:
166 RGWCreateBucket_ObjStore_S3() {}
167 ~RGWCreateBucket_ObjStore_S3() override {}
168
169 int get_params() override;
170 void send_response() override;
171 };
172
173 class RGWDeleteBucket_ObjStore_S3 : public RGWDeleteBucket_ObjStore {
174 public:
175 RGWDeleteBucket_ObjStore_S3() {}
176 ~RGWDeleteBucket_ObjStore_S3() override {}
177
178 void send_response() override;
179 };
180
181 class RGWPutObj_ObjStore_S3 : public RGWPutObj_ObjStore {
182 private:
183 std::map<std::string, std::string> crypt_http_responses;
184
185 public:
186 RGWPutObj_ObjStore_S3() {}
187 ~RGWPutObj_ObjStore_S3() override {}
188
189 int get_params() override;
190 int get_data(bufferlist& bl) override;
191 void send_response() override;
192
193 int get_encrypt_filter(std::unique_ptr<RGWPutObjDataProcessor>* filter,
194 RGWPutObjDataProcessor* cb) override;
195 int get_decrypt_filter(std::unique_ptr<RGWGetDataCB>* filter,
196 RGWGetDataCB* cb,
197 map<string, bufferlist>& attrs,
198 bufferlist* manifest_bl) override;
199 };
200
201 class RGWPostObj_ObjStore_S3 : public RGWPostObj_ObjStore {
202 parts_collection_t parts;
203 std::string filename;
204 std::string content_type;
205 RGWPolicyEnv env;
206 RGWPolicy post_policy;
207 map<string, string> crypt_http_responses;
208
209 const rgw::auth::StrategyRegistry* auth_registry_ptr = nullptr;
210
211 int get_policy();
212 void rebuild_key(string& key);
213
214 std::string get_current_filename() const override;
215 std::string get_current_content_type() const override;
216
217 public:
218 RGWPostObj_ObjStore_S3() {}
219 ~RGWPostObj_ObjStore_S3() override {}
220
221 int verify_requester(const rgw::auth::StrategyRegistry& auth_registry) {
222 auth_registry_ptr = &auth_registry;
223 return RGWPostObj_ObjStore::verify_requester(auth_registry);
224 }
225
226 int get_params() override;
227 int complete_get_params();
228
229 void send_response() override;
230 int get_data(ceph::bufferlist& bl, bool& again) override;
231 int get_encrypt_filter(std::unique_ptr<RGWPutObjDataProcessor>* filter,
232 RGWPutObjDataProcessor* cb) override;
233 };
234
235 class RGWDeleteObj_ObjStore_S3 : public RGWDeleteObj_ObjStore {
236 public:
237 RGWDeleteObj_ObjStore_S3() {}
238 ~RGWDeleteObj_ObjStore_S3() override {}
239
240 int get_params() override;
241 void send_response() override;
242 };
243
244 class RGWCopyObj_ObjStore_S3 : public RGWCopyObj_ObjStore {
245 bool sent_header;
246 public:
247 RGWCopyObj_ObjStore_S3() : sent_header(false) {}
248 ~RGWCopyObj_ObjStore_S3() override {}
249
250 int init_dest_policy() override;
251 int get_params() override;
252 void send_partial_response(off_t ofs) override;
253 void send_response() override;
254 };
255
256 class RGWGetACLs_ObjStore_S3 : public RGWGetACLs_ObjStore {
257 public:
258 RGWGetACLs_ObjStore_S3() {}
259 ~RGWGetACLs_ObjStore_S3() override {}
260
261 void send_response() override;
262 };
263
264 class RGWPutACLs_ObjStore_S3 : public RGWPutACLs_ObjStore {
265 public:
266 RGWPutACLs_ObjStore_S3() {}
267 ~RGWPutACLs_ObjStore_S3() override {}
268
269 int get_policy_from_state(RGWRados *store, struct req_state *s, stringstream& ss) override;
270 void send_response() override;
271 int get_params() override;
272 };
273
274 class RGWGetLC_ObjStore_S3 : public RGWGetLC_ObjStore {
275 protected:
276 RGWLifecycleConfiguration_S3 config;
277 public:
278 RGWGetLC_ObjStore_S3() {}
279 ~RGWGetLC_ObjStore_S3() override {}
280 void execute() override;
281
282 void send_response() override;
283 };
284
285 class RGWPutLC_ObjStore_S3 : public RGWPutLC_ObjStore {
286 public:
287 RGWPutLC_ObjStore_S3() {}
288 ~RGWPutLC_ObjStore_S3() override {}
289
290 void send_response() override;
291 };
292
293 class RGWDeleteLC_ObjStore_S3 : public RGWDeleteLC_ObjStore {
294 public:
295 RGWDeleteLC_ObjStore_S3() {}
296 ~RGWDeleteLC_ObjStore_S3() override {}
297
298 void send_response() override;
299 };
300
301 class RGWGetCORS_ObjStore_S3 : public RGWGetCORS_ObjStore {
302 public:
303 RGWGetCORS_ObjStore_S3() {}
304 ~RGWGetCORS_ObjStore_S3() override {}
305
306 void send_response() override;
307 };
308
309 class RGWPutCORS_ObjStore_S3 : public RGWPutCORS_ObjStore {
310 public:
311 RGWPutCORS_ObjStore_S3() {}
312 ~RGWPutCORS_ObjStore_S3() override {}
313
314 int get_params() override;
315 void send_response() override;
316 };
317
318 class RGWDeleteCORS_ObjStore_S3 : public RGWDeleteCORS_ObjStore {
319 public:
320 RGWDeleteCORS_ObjStore_S3() {}
321 ~RGWDeleteCORS_ObjStore_S3() override {}
322
323 void send_response() override;
324 };
325
326 class RGWOptionsCORS_ObjStore_S3 : public RGWOptionsCORS_ObjStore {
327 public:
328 RGWOptionsCORS_ObjStore_S3() {}
329 ~RGWOptionsCORS_ObjStore_S3() override {}
330
331 void send_response() override;
332 };
333
334 class RGWGetRequestPayment_ObjStore_S3 : public RGWGetRequestPayment {
335 public:
336 RGWGetRequestPayment_ObjStore_S3() {}
337 ~RGWGetRequestPayment_ObjStore_S3() override {}
338
339 void send_response() override;
340 };
341
342 class RGWSetRequestPayment_ObjStore_S3 : public RGWSetRequestPayment {
343 public:
344 RGWSetRequestPayment_ObjStore_S3() {}
345 ~RGWSetRequestPayment_ObjStore_S3() override {}
346
347 int get_params() override;
348 void send_response() override;
349 };
350
351 class RGWInitMultipart_ObjStore_S3 : public RGWInitMultipart_ObjStore {
352 private:
353 std::map<std::string, std::string> crypt_http_responses;
354 public:
355 RGWInitMultipart_ObjStore_S3() {}
356 ~RGWInitMultipart_ObjStore_S3() override {}
357
358 int get_params() override;
359 void send_response() override;
360 int prepare_encryption(map<string, bufferlist>& attrs) override;
361 };
362
363 class RGWCompleteMultipart_ObjStore_S3 : public RGWCompleteMultipart_ObjStore {
364 public:
365 RGWCompleteMultipart_ObjStore_S3() {}
366 ~RGWCompleteMultipart_ObjStore_S3() override {}
367
368 int get_params() override;
369 void send_response() override;
370 };
371
372 class RGWAbortMultipart_ObjStore_S3 : public RGWAbortMultipart_ObjStore {
373 public:
374 RGWAbortMultipart_ObjStore_S3() {}
375 ~RGWAbortMultipart_ObjStore_S3() override {}
376
377 void send_response() override;
378 };
379
380 class RGWListMultipart_ObjStore_S3 : public RGWListMultipart_ObjStore {
381 public:
382 RGWListMultipart_ObjStore_S3() {}
383 ~RGWListMultipart_ObjStore_S3() override {}
384
385 void send_response() override;
386 };
387
388 class RGWListBucketMultiparts_ObjStore_S3 : public RGWListBucketMultiparts_ObjStore {
389 public:
390 RGWListBucketMultiparts_ObjStore_S3() {
391 default_max = 1000;
392 }
393 ~RGWListBucketMultiparts_ObjStore_S3() override {}
394
395 void send_response() override;
396 };
397
398 class RGWDeleteMultiObj_ObjStore_S3 : public RGWDeleteMultiObj_ObjStore {
399 public:
400 RGWDeleteMultiObj_ObjStore_S3() {}
401 ~RGWDeleteMultiObj_ObjStore_S3() override {}
402
403 int get_params() override;
404 void send_status() override;
405 void begin_response() override;
406 void send_partial_response(rgw_obj_key& key, bool delete_marker,
407 const string& marker_version_id, int ret) override;
408 void end_response() override;
409 };
410
411 class RGWGetObjLayout_ObjStore_S3 : public RGWGetObjLayout {
412 public:
413 RGWGetObjLayout_ObjStore_S3() {}
414 ~RGWGetObjLayout_ObjStore_S3() {}
415
416 void send_response();
417 };
418
419 class RGWConfigBucketMetaSearch_ObjStore_S3 : public RGWConfigBucketMetaSearch {
420 public:
421 RGWConfigBucketMetaSearch_ObjStore_S3() {}
422 ~RGWConfigBucketMetaSearch_ObjStore_S3() {}
423
424 int get_params() override;
425 void send_response() override;
426 };
427
428 class RGWGetBucketMetaSearch_ObjStore_S3 : public RGWGetBucketMetaSearch {
429 public:
430 RGWGetBucketMetaSearch_ObjStore_S3() {}
431 ~RGWGetBucketMetaSearch_ObjStore_S3() {}
432
433 void send_response() override;
434 };
435
436 class RGWDelBucketMetaSearch_ObjStore_S3 : public RGWDelBucketMetaSearch {
437 public:
438 RGWDelBucketMetaSearch_ObjStore_S3() {}
439 ~RGWDelBucketMetaSearch_ObjStore_S3() {}
440
441 void send_response() override;
442 };
443
444 class RGW_Auth_S3 {
445 private:
446 static int authorize_v2(RGWRados *store,
447 const rgw::auth::StrategyRegistry& auth_registry,
448 struct req_state *s);
449 public:
450 static int authorize(RGWRados *store,
451 const rgw::auth::StrategyRegistry& auth_registry,
452 struct req_state *s);
453 };
454
455 class RGWHandler_Auth_S3 : public RGWHandler_REST {
456 friend class RGWRESTMgr_S3;
457
458 const rgw::auth::StrategyRegistry& auth_registry;
459
460 public:
461 RGWHandler_Auth_S3(const rgw::auth::StrategyRegistry& auth_registry)
462 : RGWHandler_REST(),
463 auth_registry(auth_registry) {
464 }
465 ~RGWHandler_Auth_S3() override = default;
466
467 static int validate_bucket_name(const string& bucket);
468 static int validate_object_name(const string& bucket);
469
470 int init(RGWRados *store,
471 struct req_state *s,
472 rgw::io::BasicClient *cio) override;
473 int authorize() override {
474 return RGW_Auth_S3::authorize(store, auth_registry, s);
475 }
476 int postauth_init() override { return 0; }
477 };
478
479 class RGWHandler_REST_S3 : public RGWHandler_REST {
480 friend class RGWRESTMgr_S3;
481
482 const rgw::auth::StrategyRegistry& auth_registry;
483 public:
484 static int init_from_header(struct req_state *s, int default_formatter, bool configurable_format);
485
486 RGWHandler_REST_S3(const rgw::auth::StrategyRegistry& auth_registry)
487 : RGWHandler_REST(),
488 auth_registry(auth_registry) {
489 }
490 ~RGWHandler_REST_S3() override = default;
491
492 int init(RGWRados *store,
493 struct req_state *s,
494 rgw::io::BasicClient *cio) override;
495 int authorize() override {
496 return RGW_Auth_S3::authorize(store, auth_registry, s);
497 }
498 int postauth_init() override;
499 };
500
501 class RGWHandler_REST_Service_S3 : public RGWHandler_REST_S3 {
502 protected:
503 bool is_usage_op() {
504 return s->info.args.exists("usage");
505 }
506 RGWOp *op_get() override;
507 RGWOp *op_head() override;
508 RGWOp *op_post() override;
509 public:
510 using RGWHandler_REST_S3::RGWHandler_REST_S3;
511 ~RGWHandler_REST_Service_S3() override = default;
512 };
513
514 class RGWHandler_REST_Bucket_S3 : public RGWHandler_REST_S3 {
515 protected:
516 bool is_acl_op() {
517 return s->info.args.exists("acl");
518 }
519 bool is_cors_op() {
520 return s->info.args.exists("cors");
521 }
522 bool is_lc_op() {
523 return s->info.args.exists("lifecycle");
524 }
525 bool is_obj_update_op() override {
526 return is_acl_op() || is_cors_op();
527 }
528 bool is_request_payment_op() {
529 return s->info.args.exists("requestPayment");
530 }
531 bool is_policy_op() {
532 return s->info.args.exists("policy");
533 }
534 RGWOp *get_obj_op(bool get_data);
535
536 RGWOp *op_get() override;
537 RGWOp *op_head() override;
538 RGWOp *op_put() override;
539 RGWOp *op_delete() override;
540 RGWOp *op_post() override;
541 RGWOp *op_options() override;
542 public:
543 using RGWHandler_REST_S3::RGWHandler_REST_S3;
544 ~RGWHandler_REST_Bucket_S3() override = default;
545 };
546
547 class RGWHandler_REST_Obj_S3 : public RGWHandler_REST_S3 {
548 protected:
549 bool is_acl_op() {
550 return s->info.args.exists("acl");
551 }
552 bool is_cors_op() {
553 return s->info.args.exists("cors");
554 }
555 bool is_obj_update_op() override {
556 return is_acl_op();
557 }
558 RGWOp *get_obj_op(bool get_data);
559
560 RGWOp *op_get() override;
561 RGWOp *op_head() override;
562 RGWOp *op_put() override;
563 RGWOp *op_delete() override;
564 RGWOp *op_post() override;
565 RGWOp *op_options() override;
566 public:
567 using RGWHandler_REST_S3::RGWHandler_REST_S3;
568 ~RGWHandler_REST_Obj_S3() override = default;
569 };
570
571 class RGWRESTMgr_S3 : public RGWRESTMgr {
572 private:
573 bool enable_s3website;
574 public:
575 explicit RGWRESTMgr_S3(bool enable_s3website = false)
576 : enable_s3website(enable_s3website) {
577 }
578
579 ~RGWRESTMgr_S3() override = default;
580
581 RGWHandler_REST *get_handler(struct req_state* s,
582 const rgw::auth::StrategyRegistry& auth_registry,
583 const std::string& frontend_prefix) override;
584 };
585
586 class RGWHandler_REST_Obj_S3Website;
587
588 static inline bool looks_like_ip_address(const char *bucket)
589 {
590 int num_periods = 0;
591 bool expect_period = false;
592 for (const char *b = bucket; *b; ++b) {
593 if (*b == '.') {
594 if (!expect_period)
595 return false;
596 ++num_periods;
597 if (num_periods > 3)
598 return false;
599 expect_period = false;
600 }
601 else if (isdigit(*b)) {
602 expect_period = true;
603 }
604 else {
605 return false;
606 }
607 }
608 return (num_periods == 3);
609 }
610
611 static inline int valid_s3_object_name(const string& name) {
612 if (name.size() > 1024) {
613 return -ERR_INVALID_OBJECT_NAME;
614 }
615 if (check_utf8(name.c_str(), name.size())) {
616 return -ERR_INVALID_OBJECT_NAME;
617 }
618 return 0;
619 }
620
621 static inline int valid_s3_bucket_name(const string& name, bool relaxed=false)
622 {
623 // This function enforces Amazon's spec for bucket names.
624 // (The requirements, not the recommendations.)
625 int len = name.size();
626 if (len < 3) {
627 // Name too short
628 return -ERR_INVALID_BUCKET_NAME;
629 } else if (len > 255) {
630 // Name too long
631 return -ERR_INVALID_BUCKET_NAME;
632 }
633
634 // bucket names must start with a number, letter, or underscore
635 if (!(isalpha(name[0]) || isdigit(name[0]))) {
636 if (!relaxed)
637 return -ERR_INVALID_BUCKET_NAME;
638 else if (!(name[0] == '_' || name[0] == '.' || name[0] == '-'))
639 return -ERR_INVALID_BUCKET_NAME;
640 }
641
642 for (const char *s = name.c_str(); *s; ++s) {
643 char c = *s;
644 if (isdigit(c) || (c == '.'))
645 continue;
646 if (isalpha(c))
647 continue;
648 if ((c == '-') || (c == '_'))
649 continue;
650 // Invalid character
651 return -ERR_INVALID_BUCKET_NAME;
652 }
653
654 if (looks_like_ip_address(name.c_str()))
655 return -ERR_INVALID_BUCKET_NAME;
656
657 return 0;
658 }
659
660
661 namespace rgw {
662 namespace auth {
663 namespace s3 {
664
665 class AWSEngine : public rgw::auth::Engine {
666 public:
667 class VersionAbstractor {
668 static constexpr size_t DIGEST_SIZE_V2 = CEPH_CRYPTO_HMACSHA1_DIGESTSIZE;
669 static constexpr size_t DIGEST_SIZE_V4 = CEPH_CRYPTO_HMACSHA256_DIGESTSIZE;
670
671 /* Knowing the signature max size allows us to employ the sstring, and thus
672 * avoid dynamic allocations. The multiplier comes from representing digest
673 * in the base64-encoded form. */
674 static constexpr size_t SIGNATURE_MAX_SIZE = \
675 ceph::max(DIGEST_SIZE_V2, DIGEST_SIZE_V4) * 2 + sizeof('\0');
676
677 public:
678 virtual ~VersionAbstractor() {};
679
680 using access_key_id_t = boost::string_view;
681 using client_signature_t = boost::string_view;
682 using server_signature_t = basic_sstring<char, uint16_t, SIGNATURE_MAX_SIZE>;
683 using string_to_sign_t = std::string;
684
685 /* Transformation for crafting the AWS signature at server side which is
686 * used later to compare with the user-provided one. The methodology for
687 * doing that depends on AWS auth version. */
688 using signature_factory_t = \
689 std::function<server_signature_t(CephContext* cct,
690 const std::string& secret_key,
691 const string_to_sign_t& string_to_sign)>;
692
693 /* Return an instance of Completer for verifying the payload's fingerprint
694 * if necessary. Otherwise caller gets nullptr. Caller may provide secret
695 * key */
696 using completer_factory_t = \
697 std::function<rgw::auth::Completer::cmplptr_t(
698 const boost::optional<std::string>& secret_key)>;
699
700 virtual std::tuple<access_key_id_t,
701 client_signature_t,
702 string_to_sign_t,
703 signature_factory_t,
704 completer_factory_t>
705 get_auth_data(const req_state* s) const = 0;
706 };
707
708 protected:
709 CephContext* cct;
710 const VersionAbstractor& ver_abstractor;
711
712 AWSEngine(CephContext* const cct, const VersionAbstractor& ver_abstractor)
713 : cct(cct),
714 ver_abstractor(ver_abstractor) {
715 }
716
717 using result_t = rgw::auth::Engine::result_t;
718 using string_to_sign_t = VersionAbstractor::string_to_sign_t;
719 using signature_factory_t = VersionAbstractor::signature_factory_t;
720 using completer_factory_t = VersionAbstractor::completer_factory_t;
721
722 /* TODO(rzarzynski): clean up. We've too many input parameter hee. Also
723 * the signature get_auth_data() of VersionAbstractor is too complicated.
724 * Replace these thing with a simple, dedicated structure. */
725 virtual result_t authenticate(const boost::string_view& access_key_id,
726 const boost::string_view& signature,
727 const string_to_sign_t& string_to_sign,
728 const signature_factory_t& signature_factory,
729 const completer_factory_t& completer_factory,
730 const req_state* s) const = 0;
731
732 public:
733 result_t authenticate(const req_state* const s) const final;
734 };
735
736
737 class AWSGeneralAbstractor : public AWSEngine::VersionAbstractor {
738 CephContext* const cct;
739
740 bool is_time_skew_ok(const utime_t& header_time,
741 const bool qsr) const;
742
743 virtual boost::optional<std::string>
744 get_v4_canonical_headers(const req_info& info,
745 const boost::string_view& signedheaders,
746 const bool using_qs) const;
747
748 std::tuple<access_key_id_t,
749 client_signature_t,
750 string_to_sign_t,
751 signature_factory_t,
752 completer_factory_t>
753 get_auth_data_v2(const req_state* s) const;
754
755 std::tuple<access_key_id_t,
756 client_signature_t,
757 string_to_sign_t,
758 signature_factory_t,
759 completer_factory_t>
760 get_auth_data_v4(const req_state* s, bool using_qs) const;
761
762 public:
763 AWSGeneralAbstractor(CephContext* const cct)
764 : cct(cct) {
765 }
766
767 std::tuple<access_key_id_t,
768 client_signature_t,
769 string_to_sign_t,
770 signature_factory_t,
771 completer_factory_t>
772 get_auth_data(const req_state* s) const override;
773 };
774
775 class AWSGeneralBoto2Abstractor : public AWSGeneralAbstractor {
776 boost::optional<std::string>
777 get_v4_canonical_headers(const req_info& info,
778 const boost::string_view& signedheaders,
779 const bool using_qs) const override;
780
781 public:
782 using AWSGeneralAbstractor::AWSGeneralAbstractor;
783 };
784
785 class AWSBrowserUploadAbstractor : public AWSEngine::VersionAbstractor {
786 static std::string to_string(ceph::bufferlist bl) {
787 return std::string(bl.c_str(),
788 static_cast<std::string::size_type>(bl.length()));
789 }
790
791 using auth_data_t = std::tuple<access_key_id_t,
792 client_signature_t,
793 string_to_sign_t,
794 signature_factory_t,
795 completer_factory_t>;
796
797 auth_data_t get_auth_data_v2(const req_state* s) const;
798 auth_data_t get_auth_data_v4(const req_state* s) const;
799
800 public:
801 AWSBrowserUploadAbstractor(CephContext*) {
802 }
803
804 std::tuple<access_key_id_t,
805 client_signature_t,
806 string_to_sign_t,
807 signature_factory_t,
808 completer_factory_t>
809 get_auth_data(const req_state* s) const override;
810 };
811
812
813 class LDAPEngine : public AWSEngine {
814 static rgw::LDAPHelper* ldh;
815 static std::mutex mtx;
816
817 static void init(CephContext* const cct);
818
819 using acl_strategy_t = rgw::auth::RemoteApplier::acl_strategy_t;
820 using auth_info_t = rgw::auth::RemoteApplier::AuthInfo;
821 using result_t = rgw::auth::Engine::result_t;
822
823 protected:
824 RGWRados* const store;
825 const rgw::auth::RemoteApplier::Factory* const apl_factory;
826
827 acl_strategy_t get_acl_strategy() const;
828 auth_info_t get_creds_info(const rgw::RGWToken& token) const noexcept;
829
830 result_t authenticate(const boost::string_view& access_key_id,
831 const boost::string_view& signature,
832 const string_to_sign_t& string_to_sign,
833 const signature_factory_t&,
834 const completer_factory_t& completer_factory,
835 const req_state* s) const override;
836 public:
837 LDAPEngine(CephContext* const cct,
838 RGWRados* const store,
839 const VersionAbstractor& ver_abstractor,
840 const rgw::auth::RemoteApplier::Factory* const apl_factory)
841 : AWSEngine(cct, ver_abstractor),
842 store(store),
843 apl_factory(apl_factory) {
844 init(cct);
845 }
846
847 using AWSEngine::authenticate;
848
849 const char* get_name() const noexcept override {
850 return "rgw::auth::s3::LDAPEngine";
851 }
852 };
853
854
855 class LocalEngine : public AWSEngine {
856 RGWRados* const store;
857 const rgw::auth::LocalApplier::Factory* const apl_factory;
858
859 result_t authenticate(const boost::string_view& access_key_id,
860 const boost::string_view& signature,
861 const string_to_sign_t& string_to_sign,
862 const signature_factory_t& signature_factory,
863 const completer_factory_t& completer_factory,
864 const req_state* s) const override;
865 public:
866 LocalEngine(CephContext* const cct,
867 RGWRados* const store,
868 const VersionAbstractor& ver_abstractor,
869 const rgw::auth::LocalApplier::Factory* const apl_factory)
870 : AWSEngine(cct, ver_abstractor),
871 store(store),
872 apl_factory(apl_factory) {
873 }
874
875 using AWSEngine::authenticate;
876
877 const char* get_name() const noexcept override {
878 return "rgw::auth::s3::LocalEngine";
879 }
880 };
881
882
883 class S3AuthFactory : public rgw::auth::RemoteApplier::Factory,
884 public rgw::auth::LocalApplier::Factory {
885 typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t;
886 RGWRados* const store;
887
888 public:
889 S3AuthFactory(RGWRados* const store)
890 : store(store) {
891 }
892
893 aplptr_t create_apl_remote(CephContext* const cct,
894 const req_state* const s,
895 rgw::auth::RemoteApplier::acl_strategy_t&& acl_alg,
896 const rgw::auth::RemoteApplier::AuthInfo info
897 ) const override {
898 return aplptr_t(
899 new rgw::auth::RemoteApplier(cct, store, std::move(acl_alg), info,
900 false /* no implicit tenants */));
901 }
902
903 aplptr_t create_apl_local(CephContext* const cct,
904 const req_state* const s,
905 const RGWUserInfo& user_info,
906 const std::string& subuser) const override {
907 return aplptr_t(
908 new rgw::auth::LocalApplier(cct, user_info, subuser));
909 }
910 };
911
912
913 } /* namespace s3 */
914 } /* namespace auth */
915 } /* namespace rgw */
916
917
918 #endif /* CEPH_RGW_REST_S3_H */