Skip to content

Commit 968f278

Browse files
authored
Merge pull request ceph#59977 from tobias-urdin/rgw-cors-v2-auth
rgw: handle http options CORS with v2 auth Reviewed-by: Casey Bodley <[email protected]>
2 parents f601351 + 51adf77 commit 968f278

File tree

4 files changed

+39
-37
lines changed

4 files changed

+39
-37
lines changed

src/rgw/rgw_auth_s3.cc

Lines changed: 31 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -191,6 +191,7 @@ static inline void get_v2_qs_map(const req_info& info,
191191
* compute a request's signature
192192
*/
193193
bool rgw_create_s3_canonical_header(const DoutPrefixProvider *dpp,
194+
RGWOpType op_type,
194195
const req_info& info,
195196
utime_t* const header_time,
196197
std::string& dest,
@@ -253,7 +254,8 @@ bool rgw_create_s3_canonical_header(const DoutPrefixProvider *dpp,
253254
request_uri = info.effective_uri;
254255
}
255256

256-
rgw_create_s3_canonical_header(dpp, info.method, content_md5, content_type,
257+
auto method = rgw::auth::s3::get_canonical_method(dpp, op_type, info);
258+
rgw_create_s3_canonical_header(dpp, method.c_str(), content_md5, content_type,
257259
date.c_str(), meta_map, qs_map,
258260
request_uri.c_str(), sub_resources, dest);
259261
return true;
@@ -704,35 +706,6 @@ std::string gen_v4_canonical_qs(const req_info& info, bool is_non_s3_op)
704706
return canonical_qs;
705707
}
706708

707-
std::string get_v4_canonical_method(const req_state* s)
708-
{
709-
/* If this is a OPTIONS request we need to compute the v4 signature for the
710-
* intended HTTP method and not the OPTIONS request itself. */
711-
if (s->op_type == RGW_OP_OPTIONS_CORS) {
712-
const char *cors_method = s->info.env->get("HTTP_ACCESS_CONTROL_REQUEST_METHOD");
713-
714-
if (cors_method) {
715-
/* Validate request method passed in access-control-request-method is valid. */
716-
auto cors_flags = get_cors_method_flags(cors_method);
717-
if (!cors_flags) {
718-
ldpp_dout(s, 1) << "invalid access-control-request-method header = "
719-
<< cors_method << dendl;
720-
throw -EINVAL;
721-
}
722-
723-
ldpp_dout(s, 10) << "canonical req method = " << cors_method
724-
<< ", due to access-control-request-method header" << dendl;
725-
return cors_method;
726-
} else {
727-
ldpp_dout(s, 1) << "invalid http options req missing "
728-
<< "access-control-request-method header" << dendl;
729-
throw -EINVAL;
730-
}
731-
}
732-
733-
return s->info.method;
734-
}
735-
736709
boost::optional<std::string>
737710
get_v4_canonical_headers(const req_info& info,
738711
const std::string_view& signedheaders,
@@ -1740,4 +1713,32 @@ AWSv4ComplSingle::create(const req_state* const s,
17401713
return std::make_shared<AWSv4ComplSingle>(s);
17411714
}
17421715

1716+
std::string get_canonical_method(const DoutPrefixProvider *dpp, RGWOpType op_type, const req_info& info)
1717+
{
1718+
/* If this is a OPTIONS request we need to compute the v4 signature for the
1719+
* intended HTTP method and not the OPTIONS request itself. */
1720+
if (op_type == RGW_OP_OPTIONS_CORS) {
1721+
const char *cors_method = info.env->get("HTTP_ACCESS_CONTROL_REQUEST_METHOD");
1722+
1723+
if (cors_method) {
1724+
/* Validate request method passed in access-control-request-method is valid. */
1725+
auto cors_flags = get_cors_method_flags(cors_method);
1726+
if (!cors_flags) {
1727+
ldpp_dout(dpp, 1) << "invalid access-control-request-method header = "
1728+
<< cors_method << dendl;
1729+
throw -EINVAL;
1730+
}
1731+
1732+
ldpp_dout(dpp, 10) << "canonical req method = " << cors_method
1733+
<< ", due to access-control-request-method header" << dendl;
1734+
return cors_method;
1735+
} else {
1736+
ldpp_dout(dpp, 1) << "invalid http options req missing "
1737+
<< "access-control-request-method header" << dendl;
1738+
throw -EINVAL;
1739+
}
1740+
}
1741+
1742+
return info.method;
1743+
}
17431744
} // namespace rgw::auth::s3

src/rgw/rgw_auth_s3.h

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -500,16 +500,17 @@ void rgw_create_s3_canonical_header(
500500
const std::map<std::string, std::string>& sub_resources,
501501
std::string& dest_str);
502502
bool rgw_create_s3_canonical_header(const DoutPrefixProvider *dpp,
503+
RGWOpType op_type,
503504
const req_info& info,
504505
utime_t *header_time, /* out */
505506
std::string& dest, /* out */
506507
bool qsr);
507508
static inline std::tuple<bool, std::string, utime_t>
508-
rgw_create_s3_canonical_header(const DoutPrefixProvider *dpp, const req_info& info, const bool qsr) {
509+
rgw_create_s3_canonical_header(const DoutPrefixProvider *dpp, RGWOpType op_type, const req_info& info, const bool qsr) {
509510
std::string dest;
510511
utime_t header_time;
511512

512-
const bool ok = rgw_create_s3_canonical_header(dpp, info, &header_time, dest, qsr);
513+
const bool ok = rgw_create_s3_canonical_header(dpp, op_type, info, &header_time, dest, qsr);
513514
return std::make_tuple(ok, dest, header_time);
514515
}
515516

@@ -704,8 +705,6 @@ std::string get_v4_canonical_qs(const req_info& info, bool using_qs);
704705

705706
std::string gen_v4_canonical_qs(const req_info& info, bool is_non_s3_op);
706707

707-
std::string get_v4_canonical_method(const req_state* s);
708-
709708
boost::optional<std::string>
710709
get_v4_canonical_headers(const req_info& info,
711710
const std::string_view& signedheaders,
@@ -745,6 +744,8 @@ extern AWSEngine::VersionAbstractor::server_signature_t
745744
get_v2_signature(CephContext*,
746745
const std::string& secret_key,
747746
const AWSEngine::VersionAbstractor::string_to_sign_t& string_to_sign);
747+
748+
std::string get_canonical_method(const DoutPrefixProvider *dpp, RGWOpType op_type, const req_info& info);
748749
} /* namespace s3 */
749750
} /* namespace auth */
750751
} /* namespace rgw */

src/rgw/rgw_rest_client.cc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -209,7 +209,7 @@ static int sign_request_v2(const DoutPrefixProvider *dpp, const RGWAccessKey& ke
209209
}
210210

211211
string canonical_header;
212-
if (!rgw_create_s3_canonical_header(dpp, info, NULL, canonical_header, false)) {
212+
if (!rgw_create_s3_canonical_header(dpp, RGW_OP_UNKNOWN, info, NULL, canonical_header, false)) {
213213
ldpp_dout(dpp, 0) << "failed to create canonical s3 header" << dendl;
214214
return -EINVAL;
215215
}

src/rgw/rgw_rest_s3.cc

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5964,7 +5964,7 @@ AWSGeneralAbstractor::get_auth_data_v4(const req_state* const s,
59645964
auto canonical_qs = rgw::auth::s3::get_v4_canonical_qs(s->info, using_qs);
59655965

59665966
/* Craft canonical method. */
5967-
auto canonical_method = rgw::auth::s3::get_v4_canonical_method(s);
5967+
auto canonical_method = rgw::auth::s3::get_canonical_method(s, s->op_type, s->info);
59685968

59695969
/* Craft canonical request. */
59705970
auto canonical_req_hash = \
@@ -6229,7 +6229,7 @@ AWSGeneralAbstractor::get_auth_data_v2(const req_state* const s) const
62296229
/* Let's canonize the HTTP headers that are covered by the AWS auth v2. */
62306230
std::string string_to_sign;
62316231
utime_t header_time;
6232-
if (! rgw_create_s3_canonical_header(s, s->info, &header_time, string_to_sign,
6232+
if (! rgw_create_s3_canonical_header(s, s->op_type, s->info, &header_time, string_to_sign,
62336233
qsr)) {
62346234
ldpp_dout(s, 10) << "failed to create the canonized auth header\n"
62356235
<< rgw::crypt_sanitize::auth{s,string_to_sign} << dendl;

0 commit comments

Comments
 (0)