From 0d69ee9ca334538df69f9a7e051a78dd2276e007 Mon Sep 17 00:00:00 2001 From: Pritha Srivastava Date: Tue, 22 Jan 2019 10:01:10 +0530 Subject: [PATCH] rgw: Correcting logic for signature calculation for non s3 ops. Signed-off-by: Pritha Srivastava --- src/rgw/rgw_auth_s3.h | 8 ++++++++ src/rgw/rgw_rest_s3.cc | 23 ++++++++++++++++++----- src/rgw/rgw_rest_sts.cc | 4 +++- src/rgw/rgw_rest_sts.h | 2 +- 4 files changed, 30 insertions(+), 7 deletions(-) diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index 0beb023c6ebd6..e01876e218295 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -511,6 +511,14 @@ static inline std::string get_v4_canonical_uri(const req_info& info) { return canonical_uri; } +static inline const string calc_v4_payload_hash(const string& payload) +{ + ceph::crypto::SHA256* sha256_hash = calc_hash_sha256_open_stream(); + calc_hash_sha256_update_stream(sha256_hash, payload.c_str(), payload.length()); + const auto payload_hash = calc_hash_sha256_close_stream(&sha256_hash); + return payload_hash; +} + static inline const char* get_v4_exp_payload_hash(const req_info& info) { /* In AWSv4 the hash of real, transferred payload IS NOT necessary to form diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index c81de09a3e1ab..424f42f87f06b 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -3930,8 +3930,23 @@ AWSGeneralAbstractor::get_auth_data_v4(const req_state* const s, throw -EPERM; } - /* Get the expected hash. */ - auto exp_payload_hash = rgw::auth::s3::get_v4_exp_payload_hash(s->info); + bool is_non_s3_op = false; + if (s->op_type == RGW_STS_GET_SESSION_TOKEN || + s->op_type == RGW_STS_ASSUME_ROLE || + s->op_type == RGW_STS_ASSUME_ROLE_WEB_IDENTITY) { + is_non_s3_op = true; + } + + const char* exp_payload_hash = nullptr; + string payload_hash; + if (is_non_s3_op) { + //For non s3 ops, we need to calculate the payload hash + payload_hash = s->info.args.get("PayloadHash"); + exp_payload_hash = payload_hash.c_str(); + } else { + /* Get the expected hash. */ + exp_payload_hash = rgw::auth::s3::get_v4_exp_payload_hash(s->info); + } /* Craft canonical URI. Using std::move later so let it be non-const. */ auto canonical_uri = rgw::auth::s3::get_v4_canonical_uri(s->info); @@ -3974,7 +3989,7 @@ AWSGeneralAbstractor::get_auth_data_v4(const req_state* const s, * This means we have absolutely no business in spawning completer. Both * aws4_auth_needs_complete and aws4_auth_streaming_mode are set to false * by default. We don't need to change that. */ - if (is_v4_payload_unsigned(exp_payload_hash) || is_v4_payload_empty(s)) { + if (is_v4_payload_unsigned(exp_payload_hash) || is_v4_payload_empty(s) || is_non_s3_op) { return { access_key_id, client_signature, @@ -4010,8 +4025,6 @@ AWSGeneralAbstractor::get_auth_data_v4(const req_state* const s, case RGW_OP_PUT_OBJ_TAGGING: case RGW_OP_PUT_LC: case RGW_OP_SET_REQUEST_PAYMENT: - case RGW_STS_GET_SESSION_TOKEN: - case RGW_STS_ASSUME_ROLE: break; default: dout(10) << "ERROR: AWS4 completion for this operation NOT IMPLEMENTED" << dendl; diff --git a/src/rgw/rgw_rest_sts.cc b/src/rgw/rgw_rest_sts.cc index bcbd9008c6b79..fab82b1e1ff2d 100644 --- a/src/rgw/rgw_rest_sts.cc +++ b/src/rgw/rgw_rest_sts.cc @@ -341,8 +341,8 @@ void RGWHandler_REST_STS::rgw_sts_parse_input() int ret = 0; bufferlist data; std::tie(ret, data) = rgw_rest_read_all_input(s, max_size, false); + string post_body = data.to_str(); if (data.length() > 0) { - string post_body = data.to_str(); ldout(s->cct, 10) << "Content of POST: " << post_body << dendl; if (post_body.find("Action") != string::npos) { @@ -362,6 +362,8 @@ void RGWHandler_REST_STS::rgw_sts_parse_input() } } } + auto payload_hash = rgw::auth::s3::calc_v4_payload_hash(post_body); + s->info.args.append("PayloadHash", payload_hash); } RGWOp *RGWHandler_REST_STS::op_post() diff --git a/src/rgw/rgw_rest_sts.h b/src/rgw/rgw_rest_sts.h index a7ec7ba26430b..a89c381d66efc 100644 --- a/src/rgw/rgw_rest_sts.h +++ b/src/rgw/rgw_rest_sts.h @@ -148,7 +148,7 @@ public: void execute() override; int verify_permission() override; int get_params(); - const char* name() const override { return "get_keystone_session_token"; } + const char* name() const override { return "get_session_token"; } RGWOpType get_type() override { return RGW_STS_GET_SESSION_TOKEN; } }; -- 2.39.5