]>
Commit | Line | Data |
---|---|---|
7c673cae FG |
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_AUTH_S3_H | |
5 | #define CEPH_RGW_AUTH_S3_H | |
6 | ||
7 | #include <string> | |
8 | #include <tuple> | |
9 | ||
10 | #include "rgw_common.h" | |
11 | #include "rgw_rest_s3.h" | |
12 | ||
13 | #include "rgw_auth.h" | |
14 | #include "rgw_auth_filters.h" | |
15 | #include "rgw_auth_keystone.h" | |
16 | ||
17 | ||
18 | namespace rgw { | |
19 | namespace auth { | |
20 | namespace s3 { | |
21 | ||
22 | class ExternalAuthStrategy : public rgw::auth::Strategy, | |
23 | public rgw::auth::RemoteApplier::Factory { | |
24 | typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t; | |
25 | RGWRados* const store; | |
26 | ||
27 | using keystone_config_t = rgw::keystone::CephCtxConfig; | |
28 | using keystone_cache_t = rgw::keystone::TokenCache; | |
29 | using EC2Engine = rgw::auth::keystone::EC2Engine; | |
30 | ||
31 | EC2Engine keystone_engine; | |
32 | LDAPEngine ldap_engine; | |
33 | ||
34 | aplptr_t create_apl_remote(CephContext* const cct, | |
35 | const req_state* const s, | |
36 | rgw::auth::RemoteApplier::acl_strategy_t&& acl_alg, | |
37 | const rgw::auth::RemoteApplier::AuthInfo info | |
38 | ) const override { | |
39 | auto apl = rgw::auth::add_sysreq(cct, store, s, | |
40 | rgw::auth::RemoteApplier(cct, store, std::move(acl_alg), info, | |
41 | false /* no implicit tenants */)); | |
42 | /* TODO(rzarzynski): replace with static_ptr. */ | |
43 | return aplptr_t(new decltype(apl)(std::move(apl))); | |
44 | } | |
45 | ||
46 | public: | |
47 | ExternalAuthStrategy(CephContext* const cct, | |
48 | RGWRados* const store, | |
49 | Version2ndEngine::Extractor* const extractor) | |
50 | : store(store), | |
51 | keystone_engine(cct, extractor, | |
52 | static_cast<rgw::auth::RemoteApplier::Factory*>(this), | |
53 | keystone_config_t::get_instance(), | |
54 | keystone_cache_t::get_instance<keystone_config_t>()), | |
55 | ldap_engine(cct, store, *extractor, | |
56 | static_cast<rgw::auth::RemoteApplier::Factory*>(this)) { | |
57 | ||
58 | if (cct->_conf->rgw_s3_auth_use_keystone && | |
59 | ! cct->_conf->rgw_keystone_url.empty()) { | |
60 | add_engine(Control::SUFFICIENT, keystone_engine); | |
61 | } | |
62 | ||
63 | if (cct->_conf->rgw_s3_auth_use_ldap && | |
64 | ! cct->_conf->rgw_ldap_uri.empty()) { | |
65 | add_engine(Control::SUFFICIENT, ldap_engine); | |
66 | } | |
67 | } | |
68 | ||
69 | const char* get_name() const noexcept override { | |
70 | return "rgw::auth::s3::AWSv2ExternalAuthStrategy"; | |
71 | } | |
72 | }; | |
73 | ||
74 | ||
75 | template <class ExtractorT> | |
76 | class AWSv2AuthStrategy : public rgw::auth::Strategy, | |
77 | public rgw::auth::LocalApplier::Factory { | |
78 | typedef rgw::auth::IdentityApplier::aplptr_t aplptr_t; | |
79 | ||
80 | static_assert(std::is_base_of<rgw::auth::s3::Version2ndEngine::Extractor, | |
81 | ExtractorT>::value, | |
82 | "ExtractorT must be a subclass of rgw::auth::s3::ExtractorT"); | |
83 | ||
84 | RGWRados* const store; | |
85 | ExtractorT extractor; | |
86 | ||
87 | ExternalAuthStrategy external_engines; | |
88 | LocalVersion2ndEngine local_engine; | |
89 | ||
90 | aplptr_t create_apl_local(CephContext* const cct, | |
91 | const req_state* const s, | |
92 | const RGWUserInfo& user_info, | |
93 | const std::string& subuser) const override { | |
94 | auto apl = rgw::auth::add_sysreq(cct, store, s, | |
95 | rgw::auth::LocalApplier(cct, user_info, subuser)); | |
96 | /* TODO(rzarzynski): replace with static_ptr. */ | |
97 | return aplptr_t(new decltype(apl)(std::move(apl))); | |
98 | } | |
99 | ||
100 | public: | |
101 | AWSv2AuthStrategy(CephContext* const cct, | |
102 | RGWRados* const store) | |
103 | : store(store), | |
104 | extractor(cct), | |
105 | external_engines(cct, store, &extractor), | |
106 | local_engine(cct, store, extractor, | |
107 | static_cast<rgw::auth::LocalApplier::Factory*>(this)) { | |
108 | ||
109 | Control local_engine_mode; | |
110 | if (! external_engines.is_empty()) { | |
111 | add_engine(Control::SUFFICIENT, external_engines); | |
112 | ||
113 | local_engine_mode = Control::FALLBACK; | |
114 | } else { | |
115 | local_engine_mode = Control::SUFFICIENT; | |
116 | } | |
117 | ||
118 | if (cct->_conf->rgw_s3_auth_use_rados) { | |
119 | add_engine(local_engine_mode, local_engine); | |
120 | } | |
121 | } | |
122 | ||
123 | const char* get_name() const noexcept override { | |
124 | return "rgw::auth::s3::AWSv2AuthStrategy"; | |
125 | } | |
126 | }; | |
127 | ||
128 | } /* namespace s3 */ | |
129 | } /* namespace auth */ | |
130 | } /* namespace rgw */ | |
131 | ||
132 | void rgw_create_s3_canonical_header( | |
133 | const char *method, | |
134 | const char *content_md5, | |
135 | const char *content_type, | |
136 | const char *date, | |
137 | const std::map<std::string, std::string>& meta_map, | |
138 | const char *request_uri, | |
139 | const std::map<std::string, std::string>& sub_resources, | |
140 | std::string& dest_str); | |
141 | bool rgw_create_s3_canonical_header(const req_info& info, | |
142 | utime_t *header_time, /* out */ | |
143 | std::string& dest, /* out */ | |
144 | bool qsr); | |
145 | static inline std::tuple<bool, std::string, utime_t> | |
146 | rgw_create_s3_canonical_header(const req_info& info, const bool qsr) { | |
147 | std::string dest; | |
148 | utime_t header_time; | |
149 | ||
150 | const bool ok = rgw_create_s3_canonical_header(info, &header_time, dest, qsr); | |
151 | return std::make_tuple(ok, dest, header_time); | |
152 | } | |
153 | ||
154 | int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, | |
155 | string& dest); | |
156 | int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, string& dest); | |
157 | ||
158 | void rgw_hash_s3_string_sha256(const char *data, int len, string& dest); | |
159 | void rgw_create_s3_v4_canonical_request(struct req_state *s, const string& canonical_uri, | |
160 | const string& canonical_qs, const string& canonical_hdrs, | |
161 | const string& signed_hdrs, const string& request_payload, | |
162 | bool unsigned_payload, | |
163 | string& canonical_req, string& canonical_req_hash); | |
164 | void rgw_create_s3_v4_string_to_sign(CephContext *cct, const string& algorithm, | |
165 | const string& request_date, const string& credential_scope, | |
166 | const string& hashed_qr, string& string_to_sign); | |
167 | int rgw_calculate_s3_v4_aws_signature(struct req_state *s, const string& access_key_id, | |
168 | const string &date, const string& region, | |
169 | const string& service, const string& string_to_sign, | |
170 | string& signature); | |
171 | ||
172 | #endif |