From: Radoslaw Zarzynski Date: Mon, 17 Apr 2017 16:52:03 +0000 (+0200) Subject: rgw: extend Version2ndEngine::Extractor to handle AWSv4 as well. X-Git-Tag: v12.1.0~155^2~46 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=d0b423118fe59e3e1f5fbde9faf0a74f589bd6ae;p=ceph.git rgw: extend Version2ndEngine::Extractor to handle AWSv4 as well. Signed-off-by: Radoslaw Zarzynski --- diff --git a/src/rgw/rgw_auth_s3.h b/src/rgw/rgw_auth_s3.h index 2902c1d97e02..262906f079ff 100644 --- a/src/rgw/rgw_auth_s3.h +++ b/src/rgw/rgw_auth_s3.h @@ -152,9 +152,9 @@ rgw_create_s3_canonical_header(const req_info& info, const bool qsr) { return std::make_tuple(ok, dest, header_time); } -int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, - string& dest); -int rgw_get_s3_header_digest(const string& auth_hdr, const string& key, string& dest); +int rgw_get_s3_header_digest(const std::string& auth_hdr, + const std::string& key, + std::string& dest); namespace rgw { namespace auth { @@ -215,6 +215,21 @@ get_v4_signing_key(CephContext* const cct, std::string get_v4_signature(CephContext* cct, const std::array& signing_key, const std::string& string_to_sign); + +static inline +std::string get_v2_signature(CephContext*, + const std::string& secret_key, + const std::string& string_to_sign) { + std::string signature_dest; + const int ret = rgw_get_s3_header_digest(string_to_sign, secret_key, + signature_dest); + if (ret < 0) { + throw ret; + } else { + return signature_dest; + } +} + } /* namespace s3 */ } /* namespace auth */ } /* namespace rgw */ diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index b905ebec0916..25fb01687a1e 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -4062,9 +4062,17 @@ bool rgw::auth::s3::RGWS3V2Extractor::is_time_skew_ok(const utime_t& header_time } } + +static rgw::auth::Completer::cmplptr_t null_completer_factory() +{ + return nullptr; +} + std::tuple + Version2ndEngine::Extractor::string_to_sign_t, + Version2ndEngine::Extractor::signature_factory_t, + Version2ndEngine::Extractor::completer_factory_t> rgw::auth::s3::RGWS3V2Extractor::get_auth_data(const req_state* const s) const { std::string access_key_id; @@ -4118,7 +4126,23 @@ rgw::auth::s3::RGWS3V2Extractor::get_auth_data(const req_state* const s) const return std::make_tuple(std::move(access_key_id), std::move(signature), - std::move(string_to_sign)); + std::move(string_to_sign), + rgw::auth::s3::get_v2_signature, + null_completer_factory); +} + +std::tuple +RGWGetPolicyV2Extractor::get_auth_data(const req_state* const s) const +{ + return std::make_tuple(s->auth.s3_postobj_creds.access_key, + s->auth.s3_postobj_creds.signature, + to_string(s->auth.s3_postobj_creds.encoded_policy), + rgw::auth::s3::get_v2_signature, + null_completer_factory); } } /* namespace s3 */ diff --git a/src/rgw/rgw_rest_s3.h b/src/rgw/rgw_rest_s3.h index d426b3d40caa..5c4b6777aecb 100644 --- a/src/rgw/rgw_rest_s3.h +++ b/src/rgw/rgw_rest_s3.h @@ -680,9 +680,24 @@ public: using signature_t = std::string; using string_to_sign_t = std::string; + /* Transformation for crafting the AWS signature at server side which is + * used later to compare with the user-provided one. The methodology for + * doing that depends on AWS auth version. */ + using signature_factory_t = \ + std::function; + + /* Return an instance of Completer for verifying the payload's fingerprint + * if necessary. Otherwise caller gets nullptr. */ + using completer_factory_t = \ + std::function; + virtual std::tuple + string_to_sign_t, + signature_factory_t, + completer_factory_t> get_auth_data(const req_state* s) const = 0; }; @@ -708,9 +723,15 @@ public: std::string signature; std::string string_to_sign; + Extractor::signature_factory_t signing_key_factory; + Extractor::completer_factory_t completer_factory; + /* Small reminder: an extractor is allowed to throw! */ - std::tie(access_key_id, signature, string_to_sign) = \ - extractor.get_auth_data(s); + std::tie(access_key_id, + signature, + string_to_sign, + signing_key_factory, + completer_factory) = extractor.get_auth_data(s); if (access_key_id.empty() || signature.empty()) { return result_t::deny(-EINVAL); @@ -733,7 +754,9 @@ public: std::tuple + string_to_sign_t, + signature_factory_t, + completer_factory_t> get_auth_data(const req_state* s) const override; }; @@ -750,12 +773,10 @@ public: std::tuple - get_auth_data(const req_state* s) const override { - return std::make_tuple(s->auth.s3_postobj_creds.access_key, - s->auth.s3_postobj_creds.signature, - to_string(s->auth.s3_postobj_creds.encoded_policy)); - } + string_to_sign_t, + signature_factory_t, + completer_factory_t> + get_auth_data(const req_state* s) const override; };