]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: dissect AWSv4's Canonical QS crafting into a separated function.
authorRadoslaw Zarzynski <rzarzynski@mirantis.com>
Thu, 13 Apr 2017 16:49:38 +0000 (18:49 +0200)
committerRadoslaw Zarzynski <rzarzynski@mirantis.com>
Wed, 7 Jun 2017 10:43:15 +0000 (12:43 +0200)
Signed-off-by: Radoslaw Zarzynski <rzarzynski@mirantis.com>
src/rgw/rgw_auth_s3.cc
src/rgw/rgw_auth_s3.h
src/rgw/rgw_rest_s3.cc

index 2b5c32741cdd64f0e1a3ecec35fcb0e71a7ac993..c988555cf301f77400cf7abdd62ec8c4985ac812 100644 (file)
@@ -239,6 +239,97 @@ namespace rgw {
 namespace auth {
 namespace s3 {
 
+static inline bool char_needs_aws4_escaping(const char c)
+{
+  if ((c >= 'a' && c <= 'z') ||
+      (c >= 'A' && c <= 'Z') ||
+      (c >= '0' && c <= '9')) {
+    return false;
+  }
+
+  switch (c) {
+    case '-':
+    case '_':
+    case '.':
+    case '~':
+      return false;
+  }
+  return true;
+}
+
+static inline void aws4_uri_encode(const string& src, string& dst)
+{
+  const char *p = src.c_str();
+  for (unsigned i = 0; i < src.size(); i++, p++) {
+    if (char_needs_aws4_escaping(*p)) {
+      rgw_uri_escape_char(*p, dst);
+      continue;
+    }
+
+    dst.append(p, 1);
+  }
+}
+
+std::string get_v4_canonical_qs(const req_info& info, const bool using_qs)
+{
+  std::string canonical_qs = info.request_params;
+
+  if (!canonical_qs.empty()) {
+
+    /* Handle case when query string exists. Step 3 in
+     * http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html */
+    map<string, string> canonical_qs_map;
+    istringstream cqs(canonical_qs);
+    string keyval;
+
+    while (getline(cqs, keyval, '&')) {
+      string key, val;
+      istringstream kv(keyval);
+      getline(kv, key, '=');
+      getline(kv, val, '=');
+      if (!using_qs || key != "X-Amz-Signature") {
+        string encoded_key;
+        string encoded_val;
+        if (key != "X-Amz-Credential") {
+          string key_decoded;
+          url_decode(key, key_decoded);
+          if (key.length() != key_decoded.length()) {
+            encoded_key = key;
+          } else {
+            aws4_uri_encode(key, encoded_key);
+          }
+          string val_decoded;
+          url_decode(val, val_decoded);
+          if (val.length() != val_decoded.length()) {
+            encoded_val = val;
+          } else {
+            aws4_uri_encode(val, encoded_val);
+          }
+        } else {
+          encoded_key = key;
+          encoded_val = val;
+        }
+        canonical_qs_map[encoded_key] = encoded_val;
+      }
+    }
+
+    canonical_qs = "";
+
+    map<string, string>::iterator last = canonical_qs_map.end();
+    --last;
+
+    for (map<string, string>::iterator it = canonical_qs_map.begin();
+        it != canonical_qs_map.end(); ++it) {
+      canonical_qs.append(it->first + "=" + it->second);
+      if (it != last) {
+        canonical_qs.append("&");
+      }
+    }
+  }
+
+  return canonical_qs;
+}
+
 std::string hash_string_sha256(const char* const data, const int len)
 {
   std::string dest;
index f81559097497e5b8ee5bb74e0daca34baab7e793..f6b455a5eee33223c02a8364fdb83c47a9fc9b24 100644 (file)
@@ -176,6 +176,8 @@ static inline std::string get_v4_canonical_uri(const req_info& info) {
   return canonical_uri;
 }
 
+std::string get_v4_canonical_qs(const req_info& info, bool using_qs);
+
 std::string hash_string_sha256(const char* data, int len);
 
 std::string get_v4_canonical_request_hash(CephContext* cct,
index 4541b9f9c23153034ed2cb9e5966a5004761469b..4bf44051eb0e010351f1336639b2f2acdc661852 100644 (file)
@@ -3531,37 +3531,6 @@ static inline bool is_base64_for_content_md5(unsigned char c) {
   return (isalnum(c) || isspace(c) || (c == '+') || (c == '/') || (c == '='));
 }
 
-static bool char_needs_aws4_escaping(char c)
-{
-  if ((c >= 'a' && c <= 'z') ||
-      (c >= 'A' && c <= 'Z') ||
-      (c >= '0' && c <= '9')) {
-    return false;
-  }
-
-  switch (c) {
-    case '-':
-    case '_':
-    case '.':
-    case '~':
-      return false;
-  }
-  return true;
-}
-
-static void aws4_uri_encode(const string& src, string& dst)
-{
-  const char *p = src.c_str();
-  for (unsigned i = 0; i < src.size(); i++, p++) {
-    if (char_needs_aws4_escaping(*p)) {
-      rgw_uri_escape_char(*p, dst);
-      continue;
-    }
-
-    dst.append(p, 1);
-  }
-}
-
 static std::array<string, 3> aws4_presigned_required_keys = { "Credential", "SignedHeaders", "Signature" };
 
 /*
@@ -3749,62 +3718,8 @@ int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s, bool force_b
   s->aws4_auth->canonical_uri = rgw::auth::s3::get_v4_canonical_uri(s->info);
 
   /* craft canonical query string */
-  s->aws4_auth->canonical_qs = s->info.request_params;
-
-  if (!s->aws4_auth->canonical_qs.empty()) {
-
-    /* handle case when query string exists. Step 3 in
-     * http://docs.aws.amazon.com/general/latest/gr/sigv4-create-canonical-request.html */
-
-    map<string, string> canonical_qs_map;
-    istringstream cqs(s->aws4_auth->canonical_qs);
-    string keyval;
-
-    while (getline(cqs, keyval, '&')) {
-      string key, val;
-      istringstream kv(keyval);
-      getline(kv, key, '=');
-      getline(kv, val, '=');
-      if (!using_qs || key != "X-Amz-Signature") {
-        string encoded_key;
-        string encoded_val;
-        if (key != "X-Amz-Credential") {
-          string key_decoded;
-          url_decode(key, key_decoded);
-          if (key.length() != key_decoded.length()) {
-            encoded_key = key;
-          } else {
-            aws4_uri_encode(key, encoded_key);
-          }
-          string val_decoded;
-          url_decode(val, val_decoded);
-          if (val.length() != val_decoded.length()) {
-            encoded_val = val;
-          } else {
-            aws4_uri_encode(val, encoded_val);
-          }
-        } else {
-          encoded_key = key;
-          encoded_val = val;
-        }
-        canonical_qs_map[encoded_key] = encoded_val;
-      }
-    }
-
-    s->aws4_auth->canonical_qs = "";
-
-    map<string, string>::iterator last = canonical_qs_map.end();
-    --last;
-
-    for (map<string, string>::iterator it = canonical_qs_map.begin();
-        it != canonical_qs_map.end(); ++it) {
-      s->aws4_auth->canonical_qs.append(it->first + "=" + it->second);
-      if (it != last) {
-        s->aws4_auth->canonical_qs.append("&");
-      }
-    }
-
-  }
+  s->aws4_auth->canonical_qs = \
+    rgw::auth::s3::get_v4_canonical_qs(s->info, using_qs);
 
   /* craft canonical headers */