diff options
author | Radoslaw Zarzynski <rzarzynski@mirantis.com> | 2017-04-13 19:13:30 +0200 |
---|---|---|
committer | Radoslaw Zarzynski <rzarzynski@mirantis.com> | 2017-06-07 12:43:15 +0200 |
commit | 985c2bc5c8d8a931a2ab53a8ddbc47c86527311e (patch) | |
tree | 3fe50e13f6cfc2e80ec05ecf18e251e49845f22d | |
parent | rgw: dissect AWSv4's Canonical QS crafting into a separated function. (diff) | |
download | ceph-985c2bc5c8d8a931a2ab53a8ddbc47c86527311e.tar.xz ceph-985c2bc5c8d8a931a2ab53a8ddbc47c86527311e.zip |
rgw: dissect AWSv4's Canonical Headers crafting into a separated function.
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
-rw-r--r-- | src/rgw/rgw_auth_s3.cc | 57 | ||||
-rw-r--r-- | src/rgw/rgw_auth_s3.h | 5 | ||||
-rw-r--r-- | src/rgw/rgw_rest_s3.cc | 59 |
3 files changed, 73 insertions, 48 deletions
diff --git a/src/rgw/rgw_auth_s3.cc b/src/rgw/rgw_auth_s3.cc index c988555cf30..c4c1abbb3a5 100644 --- a/src/rgw/rgw_auth_s3.cc +++ b/src/rgw/rgw_auth_s3.cc @@ -330,6 +330,63 @@ std::string get_v4_canonical_qs(const req_info& info, const bool using_qs) return canonical_qs; } +boost::optional<std::string> +get_v4_canonical_headers(const req_info& info, + const std::string& signedheaders, + const bool using_qs, + const bool force_boto2_compat) +{ + map<string, string> canonical_hdrs_map; + istringstream sh(signedheaders); + string token; + string port = info.env->get("SERVER_PORT", ""); + string secure_port = info.env->get("SERVER_PORT_SECURE", ""); + + while (getline(sh, token, ';')) { + string token_env = "HTTP_" + token; + transform(token_env.begin(), token_env.end(), token_env.begin(), ::toupper); + replace(token_env.begin(), token_env.end(), '-', '_'); + if (token_env == "HTTP_CONTENT_LENGTH") { + token_env = "CONTENT_LENGTH"; + } + if (token_env == "HTTP_CONTENT_TYPE") { + token_env = "CONTENT_TYPE"; + } + const char *t = info.env->get(token_env.c_str()); + if (!t) { + dout(10) << "warning env var not available" << dendl; + continue; + } + if (token_env == "HTTP_CONTENT_MD5") { + for (const char *p = t; *p; p++) { + if (!is_base64_for_content_md5(*p)) { + dout(0) << "NOTICE: bad content-md5 provided (not base64), aborting request p=" << *p << " " << (int)*p << dendl; + return boost::none; + } + } + } + string token_value = string(t); + if (force_boto2_compat && using_qs && (token == "host")) { + if (!secure_port.empty()) { + if (secure_port != "443") + token_value = token_value + ":" + secure_port; + } else if (!port.empty()) { + if (port != "80") + token_value = token_value + ":" + port; + } + } + canonical_hdrs_map[token] = rgw_trim_whitespace(token_value); + } + + std::string canonical_hdrs; + for (map<string, string>::iterator it = canonical_hdrs_map.begin(); + it != canonical_hdrs_map.end(); ++it) { + canonical_hdrs.append(it->first + ":" + it->second + "\n"); + } + + return canonical_hdrs; +} + std::string hash_string_sha256(const char* const data, const int len) { std::string dest; diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index f6b455a5eee..4696dfd2e7e 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -178,6 +178,11 @@ static inline std::string get_v4_canonical_uri(const req_info& info) { std::string get_v4_canonical_qs(const req_info& info, bool using_qs); +boost::optional<std::string> get_v4_canonical_headers(const req_info& info, + const std::string& signedheaders, + bool using_qs, + bool force_boto2_compat); + std::string hash_string_sha256(const char* data, int len); std::string get_v4_canonical_request_hash(CephContext* cct, diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 4bf44051eb0..7485a9b67ad 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -3722,56 +3722,19 @@ int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s, bool force_b rgw::auth::s3::get_v4_canonical_qs(s->info, using_qs); /* craft canonical headers */ - - map<string, string> canonical_hdrs_map; - istringstream sh(s->aws4_auth->signedheaders); - string token; - string port = s->info.env->get("SERVER_PORT", ""); - string secure_port = s->info.env->get("SERVER_PORT_SECURE", ""); - - while (getline(sh, token, ';')) { - string token_env = "HTTP_" + token; - transform(token_env.begin(), token_env.end(), token_env.begin(), ::toupper); - replace(token_env.begin(), token_env.end(), '-', '_'); - if (token_env == "HTTP_CONTENT_LENGTH") { - token_env = "CONTENT_LENGTH"; - } - if (token_env == "HTTP_CONTENT_TYPE") { - token_env = "CONTENT_TYPE"; - } - const char *t = s->info.env->get(token_env.c_str()); - if (!t) { - dout(10) << "warning env var not available" << dendl; - continue; - } - if (token_env == "HTTP_CONTENT_MD5") { - for (const char *p = t; *p; p++) { - if (!is_base64_for_content_md5(*p)) { - dout(0) << "NOTICE: bad content-md5 provided (not base64), aborting request p=" << *p << " " << (int)*p << dendl; - return -EPERM; - } - } - } - string token_value = string(t); - if (force_boto2_compat && using_qs && (token == "host")) { - if (!secure_port.empty()) { - if (secure_port != "443") - token_value = token_value + ":" + secure_port; - } else if (!port.empty()) { - if (port != "80") - token_value = token_value + ":" + port; - } - } - canonical_hdrs_map[token] = rgw_trim_whitespace(token_value); - } - - for (map<string, string>::iterator it = canonical_hdrs_map.begin(); - it != canonical_hdrs_map.end(); ++it) { - s->aws4_auth->canonical_hdrs.append(it->first + ":" + it->second + "\n"); + boost::optional<std::string> canonical_headers = \ + rgw::auth::s3::get_v4_canonical_headers(s->info, + s->aws4_auth->signedheaders, + using_qs, + force_boto2_compat); + if (canonical_headers) { + ldout(s->cct, 10) << "canonical headers format = " << *canonical_headers + << dendl; + s->aws4_auth->canonical_hdrs = std::move(*canonical_headers); + } else { + return -EPERM; } - dout(10) << "canonical headers format = " << s->aws4_auth->canonical_hdrs << dendl; - /* craft signed headers */ s->aws4_auth->signed_hdrs = s->aws4_auth->signedheaders; |