]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
radosgw: fix awsv4 header line sort order. 18046/head
authorMarcus Watts <mwatts@redhat.com>
Fri, 29 Sep 2017 21:04:08 +0000 (17:04 -0400)
committerMarcus Watts <mwatts@redhat.com>
Fri, 29 Sep 2017 21:04:08 +0000 (17:04 -0400)
The awsv4 signature calculation includes a list of header lines, which
are supposed to be sorted.  The existing code sorts by header name, but
it appears that in fact it is necessary to sort the whole header *line*,
not just the field name.  Sorting by just the field name usually works,
but not always.  The s3-tests teuthology suite includes
s3tests.functional.test_s3.test_object_header_acl_grants
s3tests.functional.test_s3.test_bucket_header_acl_grants
which include the following header lines,

x-amz-grant-read-acp:id=56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234
x-amz-grant-read:id=56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234
x-amz-grant-write-acp:id=56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234
x-amz-grant-write:id=56789abcdef0123456789abcdef0123456789abcdef0123456789abcdef01234

in this case, note that ':' needs to sort after '-'.

Fixes: http://tracker.ceph.com/issues/21607
Signed-off-by: Marcus Watts <mwatts@redhat.com>
src/rgw/rgw_auth_s3.cc

index ba137e3f59b509656f6d3318da4a85fc993d3ba0..c65e0d1fd631dd82ccb30046f0794b13c6b5d0c0 100644 (file)
@@ -3,6 +3,7 @@
 
 #include <algorithm>
 #include <map>
+#include <set>
 #include <iterator>
 #include <string>
 #include <vector>
@@ -15,6 +16,7 @@
 #include "rgw_rest.h"
 #include "rgw_crypt_sanitize.h"
 
+#include <boost/algorithm/string/join.hpp>
 #include <boost/container/small_vector.hpp>
 #include <boost/utility/string_view.hpp>
 
@@ -567,7 +569,7 @@ get_v4_canonical_headers(const req_info& info,
                          const bool using_qs,
                          const bool force_boto2_compat)
 {
-  std::map<boost::string_view, std::string> canonical_hdrs_map;
+  std::set<std::string> canonical_hdrs_set;
   for (const auto& token : get_str_vec<5>(signedheaders, ";")) {
     /* TODO(rzarzynski): we'd like to switch to sstring here but it should
      * get push_back() and reserve() first. */
@@ -614,17 +616,14 @@ get_v4_canonical_headers(const req_info& info,
       }
     }
 
-    canonical_hdrs_map[token] = rgw_trim_whitespace(token_value);
+    canonical_hdrs_set.insert(
+       boost::algorithm::join(std::vector<std::string>(
+           {std::string(token), rgw_trim_whitespace(token_value)} ), ":"));
   }
 
   std::string canonical_hdrs;
-  for (const auto& header : canonical_hdrs_map) {
-    const boost::string_view& name = header.first;
-    const std::string& value = header.second;
-
-    canonical_hdrs.append(name.data(), name.length())
-                  .append(":", std::strlen(":"))
-                  .append(value)
+  for (const auto& header : canonical_hdrs_set) {
+    canonical_hdrs.append(header.data(), header.length())
                   .append("\n", std::strlen("\n"));
   }