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 <jmunhoz@igalia.com>
This commit is contained in:
Javier M. Mellid 2015-07-02 09:28:09 +02:00
parent 49856eb7c1
commit 483ad81592
3 changed files with 18 additions and 11 deletions

View File

@ -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);
}
}
}

View File

@ -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,

View File

@ -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;
}
}