From: Javier M. Mellid Date: Mon, 1 Aug 2016 19:00:28 +0000 (+0200) Subject: rgw: aws4: add rgw_s3_auth_aws4_force_boto2_compat conf option X-Git-Tag: v10.2.10~49^2 X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=3adbc35205f663c8c312476f3694d2c14294c5d0;p=ceph.git rgw: aws4: add rgw_s3_auth_aws4_force_boto2_compat conf option Runtime bugfix to handle presigned urls computed with canonical requests using the port number once. Boto2 computes canonical requests using the port number twice although it should be used once only. This behaviour is a bug supported by AWS S3. Boto2 is used in RGW S3 as reference implementation. The client-side tools not supporting this boto2 bug will fail although they should work too. In order to support both presigned url implementations this patch adds a config option to compute a second signature. With this option disabled, the code will compute two signatures when the first signature is not valid. The aws4 auth succeed if some of the two signatures is valid. The config option rgw_s3_auth_aws4_force_boto2_compat, is enabled by default so one signature, working with boto2, is computed only. Fixes: http://tracker.ceph.com/issues/16463 Signed-off-by: Javier M. Mellid (cherry picked from commit 078c513b6bc6b1d1da50db1d51fbbb65bddd44b9) --- diff --git a/src/common/config_opts.h b/src/common/config_opts.h index 60ff9772e5392..e3582f5f87fbb 100644 --- a/src/common/config_opts.h +++ b/src/common/config_opts.h @@ -1304,6 +1304,7 @@ OPTION(rgw_cross_domain_policy, OPT_STR, "ctx()->_conf->rgw_s3_auth_aws4_force_boto2_compat) { + /* compute second aws4 signature (no bugs supported) */ + ldout(s->cct, 10) << "computing second aws4 signature..." << dendl; + return authorize_v4(store, s, false); + } + return err; } /* AWS2 */ @@ -3534,7 +3541,7 @@ static std::array aws4_presigned_required_keys = { "Credential", "Sig /* * handle v4 signatures (rados auth only) */ -int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s) +int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s, bool force_boto2_compat /* = true */) { string::size_type pos; bool using_qs; @@ -3819,7 +3826,7 @@ int RGW_Auth_S3::authorize_v4(RGWRados *store, struct req_state *s) } } string token_value = string(t); - if (using_qs && (token == "host")) { + if (force_boto2_compat && using_qs && (token == "host")) { if (!secure_port.empty()) { if (secure_port != "443") token_value = token_value + ":" + secure_port; diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index 712998238fa5f..1ce609ef5ffbf 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -430,7 +430,7 @@ private: static rgw::LDAPHelper* ldh; static int authorize_v2(RGWRados *store, struct req_state *s); - static int authorize_v4(RGWRados *store, struct req_state *s); + static int authorize_v4(RGWRados *store, struct req_state *s, bool force_boto2_compat = true); static int authorize_v4_complete(RGWRados *store, struct req_state *s, const string& request_payload, bool unsigned_payload);