summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>2017-04-13 19:13:30 +0200
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>2017-06-07 12:43:15 +0200
commit985c2bc5c8d8a931a2ab53a8ddbc47c86527311e (patch)
tree3fe50e13f6cfc2e80ec05ecf18e251e49845f22d
parentrgw: dissect AWSv4's Canonical QS crafting into a separated function. (diff)
downloadceph-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.cc57
-rw-r--r--src/rgw/rgw_auth_s3.h5
-rw-r--r--src/rgw/rgw_rest_s3.cc59
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;