From: Javier M. Mellid Date: Thu, 2 Jul 2015 07:28:09 +0000 (+0200) Subject: rgw: avoid re-encoding already encoded query strings in AWS4 auth X-Git-Tag: v10.1.0~351^2^2~23 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=483ad81592059e3b70fb1e144160b8b46bc3e5f7;p=ceph.git rgw: avoid re-encoding already encoded query strings in AWS4 auth When computing V4 signature, we need to encode the query string. But it could come already encoded, at least partially. So do not encode the entities that are already encoded. Fixes: #10333 Signed-off-by: Javier M. Mellid --- diff --git a/src/rgw/rgw_common.cc b/src/rgw/rgw_common.cc index 2de86c54117f..d30fd38ed5a2 100644 --- a/src/rgw/rgw_common.cc +++ b/src/rgw/rgw_common.cc @@ -939,16 +939,23 @@ static bool char_needs_url_encoding(char c) return false; } -void url_encode(const string& src, string& dst) +void url_encode(const string& src, string& dst, bool in_query) { const char *p = src.c_str(); for (unsigned i = 0; i < src.size(); i++, p++) { - if (char_needs_url_encoding(*p)) { - escape_char(*p, dst); - continue; - } + if (*p == '%' && in_query && (i + 2) < src.size()) { + /* keep %AB as it is */ + dst.append(p, 3); + i += 2; + p += 2; + } else { + if (char_needs_url_encoding(*p)) { + escape_char(*p, dst); + continue; + } - dst.append(p, 1); + dst.append(p, 1); + } } } diff --git a/src/rgw/rgw_common.h b/src/rgw/rgw_common.h index 948c2797af19..ed2e619a8718 100644 --- a/src/rgw/rgw_common.h +++ b/src/rgw/rgw_common.h @@ -1710,7 +1710,7 @@ extern bool verify_object_permission(struct req_state *s, int perm); /** Convert an input URL into a sane object name * by converting %-escaped strings into characters, etc*/ extern bool url_decode(const string& src_str, string& dest_str, bool in_query = false); -extern void url_encode(const string& src, string& dst); +extern void url_encode(const string& src, string& dst, bool in_query = false); /* destination should be CEPH_CRYPTO_HMACSHA1_DIGESTSIZE bytes long */ extern void calc_hmac_sha1(const char *key, int key_len, diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 640ecfdec761..9b4c26a225e3 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -2901,10 +2901,10 @@ int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s) getline(kv, key, '='); getline(kv, val, '='); if (!using_qs || key != "X-Amz-Signature") { - string key_enc, val_enc; - url_encode(key, key_enc, true); - url_encode(val, val_enc, true); - canonical_qs_map[key_enc] = val_enc; + string key_enc, val_enc; + url_encode(key, key_enc, true); + url_encode(val, val_enc, true); + canonical_qs_map[key_enc] = val_enc; } }