]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
rgw: should recode canonical_uri when caculate s3v4 auth
authoryuliyang <yuliyang@cmss.chinamobile.com>
Sat, 7 Apr 2018 10:58:55 +0000 (06:58 -0400)
committerNathan Cutler <ncutler@suse.com>
Thu, 18 Apr 2019 05:49:23 +0000 (07:49 +0200)
fix: http://tracker.ceph.com/issues/23587

Signed-off-by: yuliyang <yuliyang@cmss.chinamobile.com>
(cherry picked from commit 919a8976cf40866e7212c5bb2ff38a9c5f8a1f75)

src/rgw/rgw_auth_s3.cc
src/rgw/rgw_auth_s3.h

index 089f290db1c1b50ef3c2ea153709a16bbc97f8b3..9a9c24e0735e13a6655151cc71581ef1a052b2e3 100644 (file)
@@ -309,7 +309,6 @@ static inline int parse_v4_query_string(const req_info& info,              /* in
   return 0;
 }
 
-namespace {
 static bool get_next_token(const boost::string_view& s,
                            size_t& pos,
                            const char* const delims,
@@ -358,7 +357,6 @@ get_str_vec(const boost::string_view& str)
   const char delims[] = ";,= \t";
   return get_str_vec<ExpectedStrNum>(str, delims);
 }
-};
 
 static inline int parse_v4_auth_header(const req_info& info,               /* in */
                                        boost::string_view& credential,     /* out */
@@ -477,45 +475,6 @@ int parse_v4_credentials(const req_info& info,                     /* in */
   return 0;
 }
 
-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 std::string aws4_uri_encode(const std::string& src)
-{
-  std::string result;
-
-  for (const std::string::value_type c : src) {
-    if (char_needs_aws4_escaping(c)) {
-      rgw_uri_escape_char(c, result);
-    } else {
-      result.push_back(c);
-    }
-  }
-
-  return result;
-}
-
-static inline std::string aws4_uri_recode(const boost::string_view& src)
-{
-  std::string decoded = url_decode(src);
-  return aws4_uri_encode(decoded);
-}
-
 std::string get_v4_canonical_qs(const req_info& info, const bool using_qs)
 {
   const std::string *params = &info.request_params;
@@ -556,7 +515,7 @@ std::string get_v4_canonical_qs(const req_info& info, const bool using_qs)
        * way. */
       canonical_qs_map[key.to_string()] = val.to_string();
     } else {
-      canonical_qs_map[aws4_uri_recode(key)] = aws4_uri_recode(val);
+      canonical_qs_map[aws4_uri_recode(key, true)] = aws4_uri_recode(val, true);
     }
   }
 
index ed5096e36dbcef03eefc30d815852017de8713e6..3d6ccf6babce874d77f4b4a422502268e7116066 100644 (file)
@@ -389,12 +389,55 @@ int parse_v4_credentials(const req_info& info,                     /* in */
                         boost::string_view& date,                 /* out */
                          bool& using_qs);                          /* out */
 
+static inline bool char_needs_aws4_escaping(const char c, bool encode_slash)
+{
+  if ((c >= 'a' && c <= 'z') ||
+      (c >= 'A' && c <= 'Z') ||
+      (c >= '0' && c <= '9')) {
+    return false;
+  }
+
+  switch (c) {
+    case '-':
+    case '_':
+    case '.':
+    case '~':
+      return false;
+  }
+
+  if (c == '/' && !encode_slash)
+    return false;
+
+  return true;
+}
+
+static inline std::string aws4_uri_encode(const std::string& src, bool encode_slash)
+{
+  std::string result;
+
+  for (const std::string::value_type c : src) {
+    if (char_needs_aws4_escaping(c, encode_slash)) {
+      rgw_uri_escape_char(c, result);
+    } else {
+      result.push_back(c);
+    }
+  }
+
+  return result;
+}
+
+static inline std::string aws4_uri_recode(const boost::string_view& src, bool encode_slash)
+{
+  std::string decoded = url_decode(src);
+  return aws4_uri_encode(decoded, encode_slash);
+}
+
 static inline std::string get_v4_canonical_uri(const req_info& info) {
   /* The code should normalize according to RFC 3986 but S3 does NOT do path
    * normalization that SigV4 typically does. This code follows the same
    * approach that boto library. See auth.py:canonical_uri(...). */
 
-  std::string canonical_uri = info.request_uri_aws4;
+  std::string canonical_uri = aws4_uri_recode(info.request_uri_aws4, false);
 
   if (canonical_uri.empty()) {
     canonical_uri = "/";
@@ -485,7 +528,6 @@ extern AWSEngine::VersionAbstractor::server_signature_t
 get_v2_signature(CephContext*,
                  const std::string& secret_key,
                  const AWSEngine::VersionAbstractor::string_to_sign_t& string_to_sign);
-
 } /* namespace s3 */
 } /* namespace auth */
 } /* namespace rgw */