From 0c07d6c63a117e89f1677aabe3470078d578a211 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Tue, 26 Sep 2023 13:46:20 -0400 Subject: [PATCH] rgw/async: use optional_yield for keystone and kms requests Signed-off-by: Casey Bodley --- src/rgw/rgw_auth_keystone.cc | 57 +++++++----- src/rgw/rgw_auth_keystone.h | 25 +++-- src/rgw/rgw_crypt.cc | 30 +++--- src/rgw/rgw_crypt.h | 8 +- src/rgw/rgw_keystone.cc | 20 ++-- src/rgw/rgw_keystone.h | 8 +- src/rgw/rgw_kms.cc | 175 +++++++++++++++++++---------------- src/rgw/rgw_kms.h | 41 ++++---- src/rgw/rgw_op.cc | 2 +- src/rgw/rgw_rest_s3.cc | 16 ++-- src/test/rgw/test_rgw_kms.cc | 45 ++++----- 11 files changed, 237 insertions(+), 190 deletions(-) diff --git a/src/rgw/rgw_auth_keystone.cc b/src/rgw/rgw_auth_keystone.cc index 123d94e6e550..0e411f7ca4e5 100644 --- a/src/rgw/rgw_auth_keystone.cc +++ b/src/rgw/rgw_auth_keystone.cc @@ -38,7 +38,10 @@ TokenEngine::is_applicable(const std::string& token) const noexcept } boost::optional -TokenEngine::get_from_keystone(const DoutPrefixProvider* dpp, const std::string& token, bool allow_expired) const +TokenEngine::get_from_keystone(const DoutPrefixProvider* dpp, + const std::string& token, + bool allow_expired, + optional_yield y) const { /* Unfortunately, we can't use the short form of "using" here. It's because * we're aliasing a class' member, not namespace. */ @@ -69,8 +72,8 @@ TokenEngine::get_from_keystone(const DoutPrefixProvider* dpp, const std::string& } std::string admin_token; - if (rgw::keystone::Service::get_admin_token(dpp, cct, token_cache, config, - admin_token) < 0) { + if (rgw::keystone::Service::get_admin_token(dpp, token_cache, config, + y, admin_token) < 0) { throw -EINVAL; } @@ -79,7 +82,7 @@ TokenEngine::get_from_keystone(const DoutPrefixProvider* dpp, const std::string& validate.set_url(url); - int ret = validate.process(null_yield); + int ret = validate.process(y); if (ret < 0) { throw ret; } @@ -106,7 +109,7 @@ TokenEngine::get_from_keystone(const DoutPrefixProvider* dpp, const std::string& << ", body=" << token_body_bl.c_str() << dendl; TokenEngine::token_envelope_t token_body; - ret = token_body.parse(dpp, cct, token, token_body_bl, config.get_api_version()); + ret = token_body.parse(dpp, token, token_body_bl, config.get_api_version()); if (ret < 0) { throw ret; } @@ -205,7 +208,8 @@ TokenEngine::result_t TokenEngine::authenticate(const DoutPrefixProvider* dpp, const std::string& token, const std::string& service_token, - const req_state* const s) const + const req_state* const s, + optional_yield y) const { bool allow_expired = false; boost::optional t; @@ -282,7 +286,7 @@ TokenEngine::authenticate(const DoutPrefixProvider* dpp, /* Service token was not found in cache. Go to Keystone for validating * the token. The allow_expired here must always be false. */ ceph_assert(allow_expired == false); - st = get_from_keystone(dpp, service_token, allow_expired); + st = get_from_keystone(dpp, service_token, allow_expired, y); if (! st) { return result_t::deny(-EACCES); @@ -322,8 +326,7 @@ TokenEngine::authenticate(const DoutPrefixProvider* dpp, /* Token not in cache. Go to the Keystone for validation. This happens even * for the legacy PKI/PKIz token types. That's it, after the PKI/PKIz * RadosGW-side validation has been removed, we always ask Keystone. */ - t = get_from_keystone(dpp, token, allow_expired); - + t = get_from_keystone(dpp, token, allow_expired, y); if (! t) { return result_t::deny(-EACCES); } @@ -382,7 +385,8 @@ TokenEngine::authenticate(const DoutPrefixProvider* dpp, std::pair, int> EC2Engine::get_from_keystone(const DoutPrefixProvider* dpp, const std::string_view& access_key_id, const std::string& string_to_sign, - const std::string_view& signature) const + const std::string_view& signature, + optional_yield y) const { /* prepare keystone url */ std::string keystone_url = config.get_endpoint_url(); @@ -399,8 +403,8 @@ EC2Engine::get_from_keystone(const DoutPrefixProvider* dpp, const std::string_vi /* get authentication token for Keystone. */ std::string admin_token; - int ret = rgw::keystone::Service::get_admin_token(dpp, cct, token_cache, config, - admin_token); + int ret = rgw::keystone::Service::get_admin_token(dpp, token_cache, config, + y, admin_token); if (ret < 0) { ldpp_dout(dpp, 2) << "s3 keystone: cannot get token for keystone access" << dendl; @@ -438,7 +442,7 @@ EC2Engine::get_from_keystone(const DoutPrefixProvider* dpp, const std::string_vi validate.set_send_length(os.str().length()); /* send request */ - ret = validate.process(null_yield); + ret = validate.process(y); if (ret < 0) { ldpp_dout(dpp, 2) << "s3 keystone: token validation ERROR: " << token_body_bl.c_str() << dendl; @@ -456,7 +460,7 @@ EC2Engine::get_from_keystone(const DoutPrefixProvider* dpp, const std::string_vi /* now parse response */ rgw::keystone::TokenEnvelope token_envelope; - ret = token_envelope.parse(dpp, cct, std::string(), token_body_bl, api_version); + ret = token_envelope.parse(dpp, std::string(), token_body_bl, api_version); if (ret < 0) { ldpp_dout(dpp, 2) << "s3 keystone: token parsing failed, ret=0" << ret << dendl; @@ -466,9 +470,11 @@ EC2Engine::get_from_keystone(const DoutPrefixProvider* dpp, const std::string_vi return std::make_pair(std::move(token_envelope), 0); } -std::pair, int> EC2Engine::get_secret_from_keystone(const DoutPrefixProvider* dpp, - const std::string& user_id, - const std::string_view& access_key_id) const +auto EC2Engine::get_secret_from_keystone(const DoutPrefixProvider* dpp, + const std::string& user_id, + const std::string_view& access_key_id, + optional_yield y) const + -> std::pair, int> { /* Fetch from /users/{USER_ID}/credentials/OS-EC2/{ACCESS_KEY_ID} */ /* Should return json with response key "credential" which contains entry "secret"*/ @@ -492,8 +498,8 @@ std::pair, int> EC2Engine::get_secret_from_keystone /* get authentication token for Keystone. */ std::string admin_token; - int ret = rgw::keystone::Service::get_admin_token(dpp, cct, token_cache, config, - admin_token); + int ret = rgw::keystone::Service::get_admin_token(dpp, token_cache, config, + y, admin_token); if (ret < 0) { ldpp_dout(dpp, 2) << "s3 keystone: cannot get token for keystone access" << dendl; @@ -514,7 +520,7 @@ std::pair, int> EC2Engine::get_secret_from_keystone secret.set_verify_ssl(cct->_conf->rgw_keystone_verify_ssl); /* send request */ - ret = secret.process(null_yield); + ret = secret.process(y); if (ret < 0) { ldpp_dout(dpp, 2) << "s3 keystone: secret fetching error: " << token_body_bl.c_str() << dendl; @@ -560,7 +566,8 @@ auto EC2Engine::get_access_token(const DoutPrefixProvider* dpp, const std::string_view& access_key_id, const std::string& string_to_sign, const std::string_view& signature, - const signature_factory_t& signature_factory) const + const signature_factory_t& signature_factory, + optional_yield y) const -> access_token_result { using server_signature_t = VersionAbstractor::server_signature_t; @@ -586,12 +593,13 @@ auto EC2Engine::get_access_token(const DoutPrefixProvider* dpp, } /* No cached token, token expired, or secret invalid: fall back to keystone */ - std::tie(token, failure_reason) = get_from_keystone(dpp, access_key_id, string_to_sign, signature); + std::tie(token, failure_reason) = + get_from_keystone(dpp, access_key_id, string_to_sign, signature, y); if (token) { /* Fetch secret from keystone for the access_key_id */ std::tie(secret, failure_reason) = - get_secret_from_keystone(dpp, token->get_user_id(), access_key_id); + get_secret_from_keystone(dpp, token->get_user_id(), access_key_id, y); if (secret) { /* Add token, secret pair to cache, and set timeout */ @@ -671,7 +679,8 @@ rgw::auth::Engine::result_t EC2Engine::authenticate( } accepted_roles(cct); auto [t, secret_key, failure_reason] = - get_access_token(dpp, access_key_id, string_to_sign, signature, signature_factory); + get_access_token(dpp, access_key_id, string_to_sign, + signature, signature_factory, y); if (! t) { return result_t::deny(failure_reason); } diff --git a/src/rgw/rgw_auth_keystone.h b/src/rgw/rgw_auth_keystone.h index 0bae6cf453fa..c6852d639783 100644 --- a/src/rgw/rgw_auth_keystone.h +++ b/src/rgw/rgw_auth_keystone.h @@ -38,14 +38,18 @@ class TokenEngine : public rgw::auth::Engine { bool is_applicable(const std::string& token) const noexcept; boost::optional - get_from_keystone(const DoutPrefixProvider* dpp, const std::string& token, bool allow_expired) const; + get_from_keystone(const DoutPrefixProvider* dpp, + const std::string& token, + bool allow_expired, + optional_yield y) const; acl_strategy_t get_acl_strategy(const token_envelope_t& token) const; auth_info_t get_creds_info(const token_envelope_t& token) const noexcept; result_t authenticate(const DoutPrefixProvider* dpp, const std::string& token, const std::string& service_token, - const req_state* s) const; + const req_state* s, + optional_yield y) const; public: TokenEngine(CephContext* const cct, @@ -68,7 +72,8 @@ public: result_t authenticate(const DoutPrefixProvider* dpp, const req_state* const s, optional_yield y) const override { - return authenticate(dpp, auth_token_extractor->get_token(s), service_token_extractor->get_token(s), s); + return authenticate(dpp, auth_token_extractor->get_token(s), + service_token_extractor->get_token(s), s, y); } }; /* class TokenEngine */ @@ -145,7 +150,8 @@ class EC2Engine : public rgw::auth::s3::AWSEngine { get_from_keystone(const DoutPrefixProvider* dpp, const std::string_view& access_key_id, const std::string& string_to_sign, - const std::string_view& signature) const; + const std::string_view& signature, + optional_yield y) const; struct access_token_result { boost::optional token; @@ -157,7 +163,8 @@ class EC2Engine : public rgw::auth::s3::AWSEngine { const std::string_view& access_key_id, const std::string& string_to_sign, const std::string_view& signature, - const signature_factory_t& signature_factory) const; + const signature_factory_t& signature_factory, + optional_yield y) const; result_t authenticate(const DoutPrefixProvider* dpp, const std::string_view& access_key_id, const std::string_view& signature, @@ -167,9 +174,11 @@ class EC2Engine : public rgw::auth::s3::AWSEngine { const completer_factory_t& completer_factory, const req_state* s, optional_yield y) const override; - std::pair, int> get_secret_from_keystone(const DoutPrefixProvider* dpp, - const std::string& user_id, - const std::string_view& access_key_id) const; + auto get_secret_from_keystone(const DoutPrefixProvider* dpp, + const std::string& user_id, + const std::string_view& access_key_id, + optional_yield y) const + -> std::pair, int>; public: EC2Engine(CephContext* const cct, const rgw::auth::s3::AWSEngine::VersionAbstractor* const ver_abstractor, diff --git a/src/rgw/rgw_crypt.cc b/src/rgw/rgw_crypt.cc index 7adc72b1e846..6bc4bb9c1675 100644 --- a/src/rgw/rgw_crypt.cc +++ b/src/rgw/rgw_crypt.cc @@ -973,8 +973,8 @@ std::string expand_key_name(req_state *s, const std::string_view&t) return r; } -static int get_sse_s3_bucket_key(req_state *s, - std::string &key_id) +static int get_sse_s3_bucket_key(req_state *s, optional_yield y, + std::string &key_id) { int res; std::string saved_key; @@ -993,7 +993,7 @@ static int get_sse_s3_bucket_key(req_state *s, ldpp_dout(s, 5) << "Found KEK ID: " << key_id << dendl; } if (saved_key != key_id) { - res = create_sse_s3_bucket_key(s, s->cct, key_id); + res = create_sse_s3_bucket_key(s, key_id, y); if (res != 0) { return res; } @@ -1020,7 +1020,7 @@ static int get_sse_s3_bucket_key(req_state *s, return 0; } -int rgw_s3_prepare_encrypt(req_state* s, +int rgw_s3_prepare_encrypt(req_state* s, optional_yield y, std::map& attrs, std::unique_ptr* block_crypt, std::map& crypt_http_responses) @@ -1169,7 +1169,7 @@ int rgw_s3_prepare_encrypt(req_state* s, set_attr(attrs, RGW_ATTR_CRYPT_KEYSEL, key_selector); set_attr(attrs, RGW_ATTR_CRYPT_CONTEXT, cooked_context); std::string actual_key; - res = make_actual_key_from_kms(s, s->cct, attrs, actual_key); + res = make_actual_key_from_kms(s, attrs, y, actual_key); if (res != 0) { ldpp_dout(s, 5) << "ERROR: failed to retrieve actual key from key_id: " << key_id << dendl; s->err.message = "Failed to retrieve the actual key, kms-keyid: " + std::string(key_id); @@ -1215,7 +1215,7 @@ int rgw_s3_prepare_encrypt(req_state* s, return res; std::string key_id; - res = get_sse_s3_bucket_key(s, key_id); + res = get_sse_s3_bucket_key(s, y, key_id); if (res != 0) { return res; } @@ -1226,7 +1226,7 @@ int rgw_s3_prepare_encrypt(req_state* s, set_attr(attrs, RGW_ATTR_CRYPT_MODE, "AES256"); set_attr(attrs, RGW_ATTR_CRYPT_KEYID, key_id); std::string actual_key; - res = make_actual_key_from_sse_s3(s, s->cct, attrs, actual_key); + res = make_actual_key_from_sse_s3(s, attrs, y, actual_key); if (res != 0) { ldpp_dout(s, 5) << "ERROR: failed to retrieve actual key from key_id: " << key_id << dendl; s->err.message = "Failed to retrieve the actual key"; @@ -1293,10 +1293,10 @@ int rgw_s3_prepare_encrypt(req_state* s, } -int rgw_s3_prepare_decrypt(req_state* s, - map& attrs, - std::unique_ptr* block_crypt, - std::map& crypt_http_responses) +int rgw_s3_prepare_decrypt(req_state* s, optional_yield y, + map& attrs, + std::unique_ptr* block_crypt, + std::map& crypt_http_responses) { int res = 0; std::string stored_mode = get_str_attribute(attrs, RGW_ATTR_CRYPT_MODE); @@ -1400,7 +1400,7 @@ int rgw_s3_prepare_decrypt(req_state* s, /* try to retrieve actual key */ std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); std::string actual_key; - res = reconstitute_actual_key_from_kms(s, s->cct, attrs, actual_key); + res = reconstitute_actual_key_from_kms(s, attrs, y, actual_key); if (res != 0) { ldpp_dout(s, 10) << "ERROR: failed to retrieve actual key from key_id: " << key_id << dendl; s->err.message = "Failed to retrieve the actual key, kms-keyid: " + key_id; @@ -1470,7 +1470,7 @@ int rgw_s3_prepare_decrypt(req_state* s, /* try to retrieve actual key */ std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); std::string actual_key; - res = reconstitute_actual_key_from_sse_s3(s, s->cct, attrs, actual_key); + res = reconstitute_actual_key_from_sse_s3(s, attrs, y, actual_key); if (res != 0) { ldpp_dout(s, 10) << "ERROR: failed to retrieve actual key" << dendl; s->err.message = "Failed to retrieve the actual key"; @@ -1497,7 +1497,7 @@ int rgw_s3_prepare_decrypt(req_state* s, return 0; } -int rgw_remove_sse_s3_bucket_key(req_state *s) +int rgw_remove_sse_s3_bucket_key(req_state *s, optional_yield y) { int res; auto key_id { expand_key_name(s, s->cct->_conf->rgw_crypt_sse_s3_key_template) }; @@ -1523,7 +1523,7 @@ int rgw_remove_sse_s3_bucket_key(req_state *s) return 0; } ldpp_dout(s, 5) << "Removing valid KEK ID: " << saved_key << dendl; - res = remove_sse_s3_bucket_key(s, s->cct, saved_key); + res = remove_sse_s3_bucket_key(s, saved_key, y); if (res != 0) { ldpp_dout(s, 0) << "ERROR: Unable to remove KEK ID: " << saved_key << " got " << res << dendl; } diff --git a/src/rgw/rgw_crypt.h b/src/rgw/rgw_crypt.h index 48e4530da8d2..51208388f4c8 100644 --- a/src/rgw/rgw_crypt.h +++ b/src/rgw/rgw_crypt.h @@ -147,13 +147,13 @@ public: }; /* RGWPutObj_BlockEncrypt */ -int rgw_s3_prepare_encrypt(req_state* s, +int rgw_s3_prepare_encrypt(req_state* s, optional_yield y, std::map& attrs, std::unique_ptr* block_crypt, std::map& crypt_http_responses); -int rgw_s3_prepare_decrypt(req_state* s, +int rgw_s3_prepare_decrypt(req_state* s, optional_yield y, std::map& attrs, std::unique_ptr* block_crypt, std::map& attrs, attrs[key] = std::move(bl); } -static inline std::string get_str_attribute(std::map& attrs, +static inline std::string get_str_attribute(const std::map& attrs, const char *name) { auto iter = attrs.find(name); @@ -178,4 +178,4 @@ static inline std::string get_str_attribute(std::map& a return iter->second.to_str(); } -int rgw_remove_sse_s3_bucket_key(req_state *s); +int rgw_remove_sse_s3_bucket_key(req_state *s, optional_yield y); diff --git a/src/rgw/rgw_keystone.cc b/src/rgw/rgw_keystone.cc index c225474482a9..d0aba2f7832c 100644 --- a/src/rgw/rgw_keystone.cc +++ b/src/rgw/rgw_keystone.cc @@ -137,9 +137,9 @@ std::string CephCtxConfig::get_admin_password() const noexcept { } int Service::get_admin_token(const DoutPrefixProvider *dpp, - CephContext* const cct, TokenCache& token_cache, const Config& config, + optional_yield y, std::string& token) { /* Let's check whether someone uses the deprecated "admin token" feauture @@ -160,7 +160,7 @@ int Service::get_admin_token(const DoutPrefixProvider *dpp, } /* Call Keystone now. */ - const auto ret = issue_admin_token_request(dpp, cct, config, t); + const auto ret = issue_admin_token_request(dpp, config, y, t); if (! ret) { token_cache.add_admin(t); token = t.token.id; @@ -170,8 +170,8 @@ int Service::get_admin_token(const DoutPrefixProvider *dpp, } int Service::issue_admin_token_request(const DoutPrefixProvider *dpp, - CephContext* const cct, const Config& config, + optional_yield y, TokenEnvelope& t) { std::string token_url = config.get_endpoint_url(); @@ -180,7 +180,7 @@ int Service::issue_admin_token_request(const DoutPrefixProvider *dpp, } bufferlist token_bl; - RGWGetKeystoneAdminToken token_req(cct, "POST", "", &token_bl); + RGWGetKeystoneAdminToken token_req(dpp->get_cct(), "POST", "", &token_bl); token_req.append_header("Content-Type", "application/json"); JSONFormatter jf; @@ -210,7 +210,7 @@ int Service::issue_admin_token_request(const DoutPrefixProvider *dpp, token_req.set_url(token_url); - const int ret = token_req.process(null_yield); + const int ret = token_req.process(y); if (ret < 0) { return ret; } @@ -221,7 +221,7 @@ int Service::issue_admin_token_request(const DoutPrefixProvider *dpp, return -EACCES; } - if (t.parse(dpp, cct, token_req.get_subject_token(), token_bl, + if (t.parse(dpp, token_req.get_subject_token(), token_bl, keystone_version) != 0) { return -EINVAL; } @@ -230,12 +230,13 @@ int Service::issue_admin_token_request(const DoutPrefixProvider *dpp, } int Service::get_keystone_barbican_token(const DoutPrefixProvider *dpp, - CephContext * const cct, + optional_yield y, std::string& token) { using keystone_config_t = rgw::keystone::CephCtxConfig; using keystone_cache_t = rgw::keystone::TokenCache; + CephContext* cct = dpp->get_cct(); auto& config = keystone_config_t::get_instance(); auto& token_cache = keystone_cache_t::get_instance(); @@ -285,7 +286,7 @@ int Service::get_keystone_barbican_token(const DoutPrefixProvider *dpp, token_req.set_url(token_url); ldpp_dout(dpp, 20) << "Requesting secret from barbican url=" << token_url << dendl; - const int ret = token_req.process(null_yield); + const int ret = token_req.process(y); if (ret < 0) { ldpp_dout(dpp, 20) << "Barbican process error:" << token_bl.c_str() << dendl; return ret; @@ -297,7 +298,7 @@ int Service::get_keystone_barbican_token(const DoutPrefixProvider *dpp, return -EACCES; } - if (t.parse(dpp, cct, token_req.get_subject_token(), token_bl, + if (t.parse(dpp, token_req.get_subject_token(), token_bl, keystone_version) != 0) { return -EINVAL; } @@ -320,7 +321,6 @@ bool TokenEnvelope::has_role(const std::string& r) const } int TokenEnvelope::parse(const DoutPrefixProvider *dpp, - CephContext* const cct, const std::string& token_str, ceph::bufferlist& bl, const ApiVersion version) diff --git a/src/rgw/rgw_keystone.h b/src/rgw/rgw_keystone.h index a1728b25a048..f800830767d3 100644 --- a/src/rgw/rgw_keystone.h +++ b/src/rgw/rgw_keystone.h @@ -120,16 +120,16 @@ public: typedef RGWKeystoneHTTPTransceiver RGWGetKeystoneAdminToken; static int get_admin_token(const DoutPrefixProvider *dpp, - CephContext* const cct, TokenCache& token_cache, const Config& config, + optional_yield y, std::string& token); static int issue_admin_token_request(const DoutPrefixProvider *dpp, - CephContext* const cct, const Config& config, + optional_yield y, TokenEnvelope& token); static int get_keystone_barbican_token(const DoutPrefixProvider *dpp, - CephContext * const cct, + optional_yield y, std::string& token); }; @@ -209,7 +209,7 @@ public: const uint64_t now = ceph_clock_now().sec(); return std::cmp_greater_equal(now, get_expires()); } - int parse(const DoutPrefixProvider *dpp, CephContext* cct, + int parse(const DoutPrefixProvider *dpp, const std::string& token_str, ceph::buffer::list& bl /* in */, ApiVersion version); diff --git a/src/rgw/rgw_kms.cc b/src/rgw/rgw_kms.cc index eec5d80daab1..0249c8aebb04 100644 --- a/src/rgw/rgw_kms.cc +++ b/src/rgw/rgw_kms.cc @@ -251,6 +251,7 @@ protected: int send_request(const DoutPrefixProvider *dpp, const char *method, std::string_view infix, std::string_view key_id, const std::string& postdata, + optional_yield y, bufferlist &secret_bl) { int res; @@ -305,7 +306,7 @@ protected: secret_req.set_client_key(kctx.ssl_clientkey()); } - res = secret_req.process(null_yield); + res = secret_req.process(y); if (res < 0) { ldpp_dout(dpp, 0) << "ERROR: Request to Vault failed with error " << res << dendl; return res; @@ -323,9 +324,10 @@ protected: return res; } - int send_request(const DoutPrefixProvider *dpp, std::string_view key_id, bufferlist &secret_bl) + int send_request(const DoutPrefixProvider *dpp, std::string_view key_id, + optional_yield y, bufferlist &secret_bl) { - return send_request(dpp, "GET", "", key_id, string{}, secret_bl); + return send_request(dpp, "GET", "", key_id, string{}, y, secret_bl); } int decode_secret(const DoutPrefixProvider *dpp, std::string encoded, std::string& actual_key){ @@ -402,7 +404,8 @@ public: } } - int get_key(const DoutPrefixProvider *dpp, std::string_view key_id, std::string& actual_key) + int get_key(const DoutPrefixProvider *dpp, std::string_view key_id, + optional_yield y, std::string& actual_key) override { ZeroPoolDocument d; ZeroPoolValue *v; @@ -415,7 +418,7 @@ public: } int res = send_request(dpp, "GET", compat == COMPAT_ONLY_OLD ? "" : "/export/encryption-key", - key_id, string{}, secret_bl); + key_id, string{}, y, secret_bl); if (res < 0) { return res; } @@ -455,10 +458,13 @@ public: return decode_secret(dpp, v->GetString(), actual_key); } - int make_actual_key(const DoutPrefixProvider *dpp, map& attrs, std::string& actual_key) + int make_actual_key(const DoutPrefixProvider *dpp, map& attrs, + optional_yield y, std::string& actual_key) { std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); - if (compat == COMPAT_ONLY_OLD) return get_key(dpp, key_id, actual_key); + if (compat == COMPAT_ONLY_OLD) { + return get_key(dpp, key_id, y, actual_key); + } if (key_id.find("/") != std::string::npos) { ldpp_dout(dpp, 0) << "sorry, can't allow / in keyid" << dendl; return -EINVAL; @@ -485,7 +491,7 @@ public: std::string post_data { buf.GetString() }; int res = send_request(dpp, "POST", "/datakey/plaintext/", key_id, - post_data, secret_bl); + post_data, y, secret_bl); if (res < 0) { return res; } @@ -539,12 +545,13 @@ public: } } - int reconstitute_actual_key(const DoutPrefixProvider *dpp, map& attrs, std::string& actual_key) + int reconstitute_actual_key(const DoutPrefixProvider *dpp, const map& attrs, + optional_yield y, std::string& actual_key) { std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); std::string wrapped_key = get_str_attribute(attrs, RGW_ATTR_CRYPT_DATAKEY); if (compat == COMPAT_ONLY_OLD || key_id.rfind("/") != std::string::npos) { - return get_key(dpp, key_id, actual_key); + return get_key(dpp, key_id, y, actual_key); } /* .data.ciphertext <- (to-be) named attribute @@ -569,7 +576,7 @@ public: std::string post_data { buf.GetString() }; int res = send_request(dpp, "POST", "/decrypt/", key_id, - post_data, secret_bl); + post_data, y, secret_bl); if (res < 0) { return res; } @@ -612,7 +619,8 @@ public: } } - int create_bucket_key(const DoutPrefixProvider *dpp, const std::string& key_name) + int create_bucket_key(const DoutPrefixProvider *dpp, + const std::string& key_name, optional_yield y) { /* .data.ciphertext <- (to-be) named attribute @@ -636,7 +644,7 @@ public: std::string post_data { buf.GetString() }; int res = send_request(dpp, "POST", "/keys/", key_name, - post_data, dummy_bl); + post_data, y, dummy_bl); if (res < 0) { return res; } @@ -648,7 +656,8 @@ public: return 0; } - int delete_bucket_key(const DoutPrefixProvider *dpp, const std::string& key_name) + int delete_bucket_key(const DoutPrefixProvider *dpp, + const std::string& key_name, optional_yield y) { /* /keys//config @@ -676,7 +685,7 @@ public: std::string post_data { buf.GetString() }; int res = send_request(dpp, "POST", "", config_path, - post_data, dummy_bl); + post_data, y, dummy_bl); if (res < 0) { return res; } @@ -688,7 +697,7 @@ public: } res = send_request(dpp, "DELETE", "", delete_path, - string{}, dummy_bl); + string{}, y, dummy_bl); if (res < 0) { return res; } @@ -714,12 +723,13 @@ public: virtual ~KvSecretEngine(){} - int get_key(const DoutPrefixProvider *dpp, std::string_view key_id, std::string& actual_key){ + int get_key(const DoutPrefixProvider *dpp, std::string_view key_id, + optional_yield y, std::string& actual_key) override { ZeroPoolDocument d; ZeroPoolValue *v; bufferlist secret_bl; - int res = send_request(dpp, key_id, secret_bl); + int res = send_request(dpp, key_id, y, secret_bl); if (res < 0) { return res; } @@ -771,8 +781,8 @@ private: protected: KmipGetTheKey(CephContext *cct) : cct(cct) {} KmipGetTheKey& keyid_to_keyname(std::string_view key_id); - KmipGetTheKey& get_uniqueid_for_keyname(); - int get_key_for_uniqueid(std::string &); + KmipGetTheKey& get_uniqueid_for_keyname(optional_yield y); + int get_key_for_uniqueid(optional_yield y, std::string &); friend KmipSecretEngine; }; @@ -797,12 +807,12 @@ KmipGetTheKey::keyid_to_keyname(std::string_view key_id) } KmipGetTheKey& -KmipGetTheKey::get_uniqueid_for_keyname() +KmipGetTheKey::get_uniqueid_for_keyname(optional_yield y) { RGWKMIPTransceiver secret_req(cct, RGWKMIPTransceiver::LOCATE); secret_req.name = work.data(); - ret = secret_req.process(null_yield); + ret = secret_req.process(y); if (ret < 0) { failed = true; } else if (!secret_req.outlist->string_count) { @@ -823,12 +833,12 @@ KmipGetTheKey::get_uniqueid_for_keyname() } int -KmipGetTheKey::get_key_for_uniqueid(std::string& actual_key) +KmipGetTheKey::get_key_for_uniqueid(optional_yield y, std::string& actual_key) { if (failed) return ret; RGWKMIPTransceiver secret_req(cct, RGWKMIPTransceiver::GET); secret_req.unique_id = work.data(); - ret = secret_req.process(null_yield); + ret = secret_req.process(y); if (ret < 0) { failed = true; } else { @@ -849,25 +859,26 @@ public: this->cct = cct; } - int get_key(const DoutPrefixProvider *dpp, std::string_view key_id, std::string& actual_key) + int get_key(const DoutPrefixProvider *dpp, std::string_view key_id, + optional_yield y, std::string& actual_key) override { int r; r = KmipGetTheKey{cct} .keyid_to_keyname(key_id) - .get_uniqueid_for_keyname() - .get_key_for_uniqueid(actual_key); + .get_uniqueid_for_keyname(y) + .get_key_for_uniqueid(y, actual_key); return r; } }; static int get_actual_key_from_conf(const DoutPrefixProvider* dpp, - CephContext *cct, std::string_view key_id, std::string_view key_selector, std::string& actual_key) { int res = 0; + CephContext* cct = dpp->get_cct(); static map str_map = get_str_map( cct->_conf->rgw_crypt_s3_kms_encryption_keys); @@ -905,12 +916,13 @@ static int get_actual_key_from_conf(const DoutPrefixProvider* dpp, } static int request_key_from_barbican(const DoutPrefixProvider *dpp, - CephContext *cct, std::string_view key_id, const std::string& barbican_token, + optional_yield y, std::string& actual_key) { int res; + CephContext* cct = dpp->get_cct(); std::string secret_url = cct->_conf->rgw_barbican_url; if (secret_url.empty()) { ldpp_dout(dpp, 0) << "ERROR: conf rgw_barbican_url is not set" << dendl; @@ -924,7 +936,7 @@ static int request_key_from_barbican(const DoutPrefixProvider *dpp, secret_req.append_header("Accept", "application/octet-stream"); secret_req.append_header("X-Auth-Token", barbican_token); - res = secret_req.process(null_yield); + res = secret_req.process(y); if (res < 0) { return res; } @@ -945,19 +957,19 @@ static int request_key_from_barbican(const DoutPrefixProvider *dpp, } static int get_actual_key_from_barbican(const DoutPrefixProvider *dpp, - CephContext *cct, std::string_view key_id, + optional_yield y, std::string& actual_key) { int res = 0; std::string token; - if (rgw::keystone::Service::get_keystone_barbican_token(dpp, cct, token) < 0) { + if (rgw::keystone::Service::get_keystone_barbican_token(dpp, y, token) < 0) { ldpp_dout(dpp, 5) << "Failed to retrieve token for Barbican" << dendl; return -EINVAL; } - res = request_key_from_barbican(dpp, cct, key_id, token, actual_key); + res = request_key_from_barbican(dpp, key_id, token, y, actual_key); if (res != 0) { ldpp_dout(dpp, 5) << "Failed to retrieve secret from Barbican:" << key_id << dendl; } @@ -1002,11 +1014,12 @@ std::string config_to_engine_and_parms(CephContext *cct, static int get_actual_key_from_vault(const DoutPrefixProvider *dpp, - CephContext *cct, SSEContext & kctx, map& attrs, + optional_yield y, std::string& actual_key, bool make_it) { + CephContext* cct = dpp->get_cct(); std::string secret_engine_str = kctx.secret_engine(); EngineParmMap secret_engine_parms; auto secret_engine { config_to_engine_and_parms( @@ -1018,14 +1031,14 @@ static int get_actual_key_from_vault(const DoutPrefixProvider *dpp, if (RGW_SSE_KMS_VAULT_SE_KV == secret_engine){ std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); KvSecretEngine engine(cct, kctx, std::move(secret_engine_parms)); - return engine.get_key(dpp, key_id, actual_key); + return engine.get_key(dpp, key_id, y, actual_key); } else if (RGW_SSE_KMS_VAULT_SE_TRANSIT == secret_engine){ TransitSecretEngine engine(cct, kctx, std::move(secret_engine_parms)); std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); return make_it - ? engine.make_actual_key(dpp, attrs, actual_key) - : engine.reconstitute_actual_key(dpp, attrs, actual_key); + ? engine.make_actual_key(dpp, attrs, y, actual_key) + : engine.reconstitute_actual_key(dpp, attrs, y, actual_key); } else { ldpp_dout(dpp, 0) << "Missing or invalid secret engine" << dendl; @@ -1035,35 +1048,35 @@ static int get_actual_key_from_vault(const DoutPrefixProvider *dpp, static int make_actual_key_from_vault(const DoutPrefixProvider *dpp, - CephContext *cct, SSEContext & kctx, map& attrs, + optional_yield y, std::string& actual_key) { - return get_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key, true); + return get_actual_key_from_vault(dpp, kctx, attrs, y, actual_key, true); } static int reconstitute_actual_key_from_vault(const DoutPrefixProvider *dpp, - CephContext *cct, - SSEContext & kctx, - map& attrs, - std::string& actual_key) + SSEContext & kctx, + map& attrs, + optional_yield y, + std::string& actual_key) { - return get_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key, false); + return get_actual_key_from_vault(dpp, kctx, attrs, y, actual_key, false); } static int get_actual_key_from_kmip(const DoutPrefixProvider *dpp, - CephContext *cct, - std::string_view key_id, - std::string& actual_key) + std::string_view key_id, + optional_yield y, + std::string& actual_key) { std::string secret_engine = RGW_SSE_KMS_KMIP_SE_KV; if (RGW_SSE_KMS_KMIP_SE_KV == secret_engine){ - KmipSecretEngine engine(cct); - return engine.get_key(dpp, key_id, actual_key); + KmipSecretEngine engine(dpp->get_cct()); + return engine.get_key(dpp, key_id, y, actual_key); } else{ ldpp_dout(dpp, 0) << "Missing or invalid secret engine" << dendl; @@ -1151,63 +1164,65 @@ public: }; }; -int reconstitute_actual_key_from_kms(const DoutPrefixProvider *dpp, CephContext *cct, - map& attrs, - std::string& actual_key) +int reconstitute_actual_key_from_kms(const DoutPrefixProvider *dpp, + map& attrs, + optional_yield y, + std::string& actual_key) { std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); - KMSContext kctx { cct }; + KMSContext kctx { dpp->get_cct() }; const std::string &kms_backend { kctx.backend() }; ldpp_dout(dpp, 20) << "Getting KMS encryption key for key " << key_id << dendl; ldpp_dout(dpp, 20) << "SSE-KMS backend is " << kms_backend << dendl; if (RGW_SSE_KMS_BACKEND_BARBICAN == kms_backend) { - return get_actual_key_from_barbican(dpp, cct, key_id, actual_key); + return get_actual_key_from_barbican(dpp, key_id, y, actual_key); } if (RGW_SSE_KMS_BACKEND_VAULT == kms_backend) { - return reconstitute_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key); + return reconstitute_actual_key_from_vault(dpp, kctx, attrs, y, actual_key); } if (RGW_SSE_KMS_BACKEND_KMIP == kms_backend) { - return get_actual_key_from_kmip(dpp, cct, key_id, actual_key); + return get_actual_key_from_kmip(dpp, key_id, y, actual_key); } if (RGW_SSE_KMS_BACKEND_TESTING == kms_backend) { std::string key_selector = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYSEL); - return get_actual_key_from_conf(dpp, cct, key_id, key_selector, actual_key); + return get_actual_key_from_conf(dpp, key_id, key_selector, actual_key); } ldpp_dout(dpp, 0) << "ERROR: Invalid rgw_crypt_s3_kms_backend: " << kms_backend << dendl; return -EINVAL; } -int make_actual_key_from_kms(const DoutPrefixProvider *dpp, CephContext *cct, - map& attrs, - std::string& actual_key) +int make_actual_key_from_kms(const DoutPrefixProvider *dpp, + map& attrs, + optional_yield y, + std::string& actual_key) { - KMSContext kctx { cct }; + KMSContext kctx { dpp->get_cct() }; const std::string &kms_backend { kctx.backend() }; if (RGW_SSE_KMS_BACKEND_VAULT == kms_backend) - return make_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key); - return reconstitute_actual_key_from_kms(dpp, cct, attrs, actual_key); + return make_actual_key_from_vault(dpp, kctx, attrs, y, actual_key); + return reconstitute_actual_key_from_kms(dpp, attrs, y, actual_key); } int reconstitute_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, - CephContext *cct, - map& attrs, - std::string& actual_key) + map& attrs, + optional_yield y, + std::string& actual_key) { std::string key_id = get_str_attribute(attrs, RGW_ATTR_CRYPT_KEYID); - SseS3Context kctx { cct }; + SseS3Context kctx { dpp->get_cct() }; const std::string &kms_backend { kctx.backend() }; ldpp_dout(dpp, 20) << "Getting SSE-S3 encryption key for key " << key_id << dendl; ldpp_dout(dpp, 20) << "SSE-KMS backend is " << kms_backend << dendl; if (RGW_SSE_KMS_BACKEND_VAULT == kms_backend) { - return reconstitute_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key); + return reconstitute_actual_key_from_vault(dpp, kctx, attrs, y, actual_key); } ldpp_dout(dpp, 0) << "ERROR: Invalid rgw_crypt_sse_s3_backend: " << kms_backend << dendl; @@ -1215,24 +1230,25 @@ int reconstitute_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, } int make_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, - CephContext *cct, - map& attrs, - std::string& actual_key) + map& attrs, + optional_yield y, + std::string& actual_key) { - SseS3Context kctx { cct }; + SseS3Context kctx { dpp->get_cct() }; const std::string kms_backend { kctx.backend() }; if (RGW_SSE_KMS_BACKEND_VAULT != kms_backend) { ldpp_dout(dpp, 0) << "ERROR: Unsupported rgw_crypt_sse_s3_backend: " << kms_backend << dendl; return -EINVAL; } - return make_actual_key_from_vault(dpp, cct, kctx, attrs, actual_key); + return make_actual_key_from_vault(dpp, kctx, attrs, y, actual_key); } int create_sse_s3_bucket_key(const DoutPrefixProvider *dpp, - CephContext *cct, - const std::string& bucket_key) + const std::string& bucket_key, + optional_yield y) { + CephContext* cct = dpp->get_cct(); SseS3Context kctx { cct }; const std::string kms_backend { kctx.backend() }; @@ -1248,7 +1264,7 @@ int create_sse_s3_bucket_key(const DoutPrefixProvider *dpp, secret_engine_str, secret_engine_parms) }; if (RGW_SSE_KMS_VAULT_SE_TRANSIT == secret_engine){ TransitSecretEngine engine(cct, kctx, std::move(secret_engine_parms)); - return engine.create_bucket_key(dpp, bucket_key); + return engine.create_bucket_key(dpp, bucket_key, y); } else { ldpp_dout(dpp, 0) << "Missing or invalid secret engine" << dendl; @@ -1257,9 +1273,10 @@ int create_sse_s3_bucket_key(const DoutPrefixProvider *dpp, } int remove_sse_s3_bucket_key(const DoutPrefixProvider *dpp, - CephContext *cct, - const std::string& bucket_key) + const std::string& bucket_key, + optional_yield y) { + CephContext* cct = dpp->get_cct(); SseS3Context kctx { cct }; std::string secret_engine_str = kctx.secret_engine(); EngineParmMap secret_engine_parms; @@ -1268,7 +1285,7 @@ int remove_sse_s3_bucket_key(const DoutPrefixProvider *dpp, secret_engine_str, secret_engine_parms) }; if (RGW_SSE_KMS_VAULT_SE_TRANSIT == secret_engine){ TransitSecretEngine engine(cct, kctx, std::move(secret_engine_parms)); - return engine.delete_bucket_key(dpp, bucket_key); + return engine.delete_bucket_key(dpp, bucket_key, y); } else { ldpp_dout(dpp, 0) << "Missing or invalid secret engine" << dendl; diff --git a/src/rgw/rgw_kms.h b/src/rgw/rgw_kms.h index f8e8655f261c..ceece721dca0 100644 --- a/src/rgw/rgw_kms.h +++ b/src/rgw/rgw_kms.h @@ -32,24 +32,30 @@ static const std::string RGW_SSE_KMS_KMIP_SE_KV = "kv"; * TODO * \return */ -int make_actual_key_from_kms(const DoutPrefixProvider *dpp, CephContext *cct, - std::map& attrs, - std::string& actual_key); -int reconstitute_actual_key_from_kms(const DoutPrefixProvider *dpp, CephContext *cct, - std::map& attrs, - std::string& actual_key); -int make_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, CephContext *cct, - std::map& attrs, - std::string& actual_key); -int reconstitute_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, CephContext *cct, - std::map& attrs, - std::string& actual_key); +int make_actual_key_from_kms(const DoutPrefixProvider *dpp, + std::map& attrs, + optional_yield y, + std::string& actual_key); +int reconstitute_actual_key_from_kms(const DoutPrefixProvider *dpp, + std::map& attrs, + optional_yield y, + std::string& actual_key); +int make_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, + std::map& attrs, + optional_yield y, + std::string& actual_key); +int reconstitute_actual_key_from_sse_s3(const DoutPrefixProvider *dpp, + std::map& attrs, + optional_yield y, + std::string& actual_key); -int create_sse_s3_bucket_key(const DoutPrefixProvider *dpp, CephContext *cct, - const std::string& actual_key); +int create_sse_s3_bucket_key(const DoutPrefixProvider *dpp, + const std::string& actual_key, + optional_yield y); -int remove_sse_s3_bucket_key(const DoutPrefixProvider *dpp, CephContext *cct, - const std::string& actual_key); +int remove_sse_s3_bucket_key(const DoutPrefixProvider *dpp, + const std::string& actual_key, + optional_yield y); /** * SecretEngine Interface @@ -59,6 +65,7 @@ int remove_sse_s3_bucket_key(const DoutPrefixProvider *dpp, CephContext *cct, class SecretEngine { public: - virtual int get_key(const DoutPrefixProvider *dpp, std::string_view key_id, std::string& actual_key) = 0; + virtual int get_key(const DoutPrefixProvider *dpp, std::string_view key_id, + optional_yield y, std::string& actual_key) = 0; virtual ~SecretEngine(){}; }; diff --git a/src/rgw/rgw_op.cc b/src/rgw/rgw_op.cc index 374975f5d4c9..8c15e5bd2e3f 100644 --- a/src/rgw/rgw_op.cc +++ b/src/rgw/rgw_op.cc @@ -3570,7 +3570,7 @@ void RGWDeleteBucket::execute(optional_yield y) return; } - op_ret = rgw_remove_sse_s3_bucket_key(s); + op_ret = rgw_remove_sse_s3_bucket_key(s, y); if (op_ret != 0) { // do nothing; it will already have been logged } diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 821f2b38b068..0723141708df 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -594,7 +594,8 @@ int RGWGetObj_ObjStore_S3::get_decrypt_filter(std::unique_ptr } std::unique_ptr block_crypt; - int res = rgw_s3_prepare_decrypt(s, attrs, &block_crypt, crypt_http_responses); + int res = rgw_s3_prepare_decrypt(s, s->yield, attrs, &block_crypt, + crypt_http_responses); if (res < 0) { return res; } @@ -2766,7 +2767,8 @@ int RGWPutObj_ObjStore_S3::get_decrypt_filter( std::map crypt_http_responses_unused; std::unique_ptr block_crypt; - int res = rgw_s3_prepare_decrypt(s, attrs, &block_crypt, crypt_http_responses_unused); + int res = rgw_s3_prepare_decrypt(s, s->yield, attrs, &block_crypt, + crypt_http_responses_unused); if (res < 0) { return res; } @@ -2819,7 +2821,8 @@ int RGWPutObj_ObjStore_S3::get_encrypt_filter( std::unique_ptr block_crypt; /* We are adding to existing object. * We use crypto mode that configured as if we were decrypting. */ - res = rgw_s3_prepare_decrypt(s, obj->get_attrs(), &block_crypt, crypt_http_responses); + res = rgw_s3_prepare_decrypt(s, s->yield, obj->get_attrs(), + &block_crypt, crypt_http_responses); if (res == 0 && block_crypt != nullptr) filter->reset(new RGWPutObj_BlockEncrypt(s, s->cct, cb, std::move(block_crypt), s->yield)); } @@ -2828,7 +2831,8 @@ int RGWPutObj_ObjStore_S3::get_encrypt_filter( else { std::unique_ptr block_crypt; - res = rgw_s3_prepare_encrypt(s, attrs, &block_crypt, crypt_http_responses); + res = rgw_s3_prepare_encrypt(s, s->yield, attrs, &block_crypt, + crypt_http_responses); if (res == 0 && block_crypt != nullptr) { filter->reset(new RGWPutObj_BlockEncrypt(s, s->cct, cb, std::move(block_crypt), s->yield)); } @@ -3375,7 +3379,7 @@ int RGWPostObj_ObjStore_S3::get_encrypt_filter( rgw::sal::DataProcessor *cb) { std::unique_ptr block_crypt; - int res = rgw_s3_prepare_encrypt(s, attrs, &block_crypt, + int res = rgw_s3_prepare_encrypt(s, s->yield, attrs, &block_crypt, crypt_http_responses); if (res == 0 && block_crypt != nullptr) { filter->reset(new RGWPutObj_BlockEncrypt(s, s->cct, cb, std::move(block_crypt), s->yield)); @@ -3993,7 +3997,7 @@ void RGWInitMultipart_ObjStore_S3::send_response() int RGWInitMultipart_ObjStore_S3::prepare_encryption(map& attrs) { int res = 0; - res = rgw_s3_prepare_encrypt(s, attrs, nullptr, crypt_http_responses); + res = rgw_s3_prepare_encrypt(s, s->yield, attrs, nullptr, crypt_http_responses); return res; } diff --git a/src/test/rgw/test_rgw_kms.cc b/src/test/rgw/test_rgw_kms.cc index 49ee747f7335..aaa4e4174f78 100644 --- a/src/test/rgw/test_rgw_kms.cc +++ b/src/test/rgw/test_rgw_kms.cc @@ -20,7 +20,7 @@ class MockTransitSecretEngine : public TransitSecretEngine { public: MockTransitSecretEngine(CephContext *cct, SSEContext & kctx, EngineParmMap parms) : TransitSecretEngine(cct, kctx, parms){} - MOCK_METHOD(int, send_request, (const DoutPrefixProvider *dpp, const char *method, std::string_view infix, std::string_view key_id, const std::string& postdata, bufferlist &bl), (override)); + MOCK_METHOD(int, send_request, (const DoutPrefixProvider *dpp, const char *method, std::string_view infix, std::string_view key_id, const std::string& postdata, optional_yield y, bufferlist &bl), (override)); }; @@ -29,7 +29,7 @@ class MockKvSecretEngine : public KvSecretEngine { public: MockKvSecretEngine(CephContext *cct, SSEContext & kctx, EngineParmMap parms) : KvSecretEngine(cct, kctx, parms){} - MOCK_METHOD(int, send_request, (const DoutPrefixProvider *dpp, const char *method, std::string_view infix, std::string_view key_id, const std::string& postdata, bufferlist &bl), (override)); + MOCK_METHOD(int, send_request, (const DoutPrefixProvider *dpp, const char *method, std::string_view infix, std::string_view key_id, const std::string& postdata, optional_yield y, bufferlist &bl), (override)); }; @@ -73,8 +73,8 @@ TEST_F(TestSSEKMS, vault_token_file_unset) std::string_view key_id("my_key"); std::string actual_key; - ASSERT_EQ(te.get_key(&no_dpp, key_id, actual_key), -EINVAL); - ASSERT_EQ(kv.get_key(&no_dpp, key_id, actual_key), -EINVAL); + ASSERT_EQ(te.get_key(&no_dpp, key_id, null_yield, actual_key), -EINVAL); + ASSERT_EQ(kv.get_key(&no_dpp, key_id, null_yield, actual_key), -EINVAL); } @@ -91,14 +91,14 @@ TEST_F(TestSSEKMS, non_existent_vault_token_file) std::string_view key_id("my_key/1"); std::string actual_key; - ASSERT_EQ(te.get_key(&no_dpp, key_id, actual_key), -ENOENT); - ASSERT_EQ(kv.get_key(&no_dpp, key_id, actual_key), -ENOENT); + ASSERT_EQ(te.get_key(&no_dpp, key_id, null_yield, actual_key), -ENOENT); + ASSERT_EQ(kv.get_key(&no_dpp, key_id, null_yield, actual_key), -ENOENT); } typedef int SendRequestMethod(const DoutPrefixProvider *dpp, const char *, std::string_view, std::string_view, - const std::string &, bufferlist &); + const std::string &, optional_yield, bufferlist &); class SetPointedValueAction : public ActionInterface { public: @@ -108,13 +108,14 @@ class SetPointedValueAction : public ActionInterface { this->json = json; } - int Perform(const ::std::tuple& args) override { + int Perform(const ::std::tuple& args) override { // const DoutPrefixProvider *dpp = ::std::get<0>(args); // const char *method = ::std::get<1>(args); // std::string_view infix = ::std::get<2>(args); // std::string_view key_id = ::std::get<3>(args); // const std::string& postdata = ::std::get<4>(args); - bufferlist& bl = ::std::get<5>(args); +// optional_yield y = ::std::get<5>(args); + bufferlist& bl = ::std::get<6>(args); // std::cout << "method = " << method << " infix = " << infix << " key_id = " << key_id // << " postdata = " << postdata @@ -137,7 +138,7 @@ Action SetPointedValue(std::string json) { TEST_F(TestSSEKMS, test_transit_key_version_extraction){ const NoDoutPrefix no_dpp(cct, 1); string json = R"({"data": {"keys": {"6": "8qgPWvdtf6zrriS5+nkOzDJ14IGVR6Bgkub5dJn6qeg="}}})"; - EXPECT_CALL(*old_engine, send_request(&no_dpp, StrEq("GET"), StrEq(""), StrEq("1/2/3/4/5/6"), StrEq(""), _)).WillOnce(SetPointedValue(json)); + EXPECT_CALL(*old_engine, send_request(&no_dpp, StrEq("GET"), StrEq(""), StrEq("1/2/3/4/5/6"), StrEq(""), _, _)).WillOnce(SetPointedValue(json)); std::string actual_key; std::string tests[11] {"/", "my_key/", "my_key", "", "my_key/a", "my_key/1a", @@ -146,11 +147,11 @@ TEST_F(TestSSEKMS, test_transit_key_version_extraction){ int res; for (const auto &test: tests) { - res = old_engine->get_key(&no_dpp, std::string_view(test), actual_key); + res = old_engine->get_key(&no_dpp, std::string_view(test), null_yield, actual_key); ASSERT_EQ(res, -EINVAL); } - res = old_engine->get_key(&no_dpp, std::string_view("1/2/3/4/5/6"), actual_key); + res = old_engine->get_key(&no_dpp, std::string_view("1/2/3/4/5/6"), null_yield, actual_key); ASSERT_EQ(res, 0); ASSERT_EQ(actual_key, from_base64("8qgPWvdtf6zrriS5+nkOzDJ14IGVR6Bgkub5dJn6qeg=")); } @@ -164,9 +165,9 @@ TEST_F(TestSSEKMS, test_transit_backend){ // Mocks the expected return Value from Vault Server using custom Argument Action string json = R"({"data": {"keys": {"1": "8qgPWvdtf6zrriS5+nkOzDJ14IGVR6Bgkub5dJn6qeg="}}})"; const NoDoutPrefix no_dpp(cct, 1); - EXPECT_CALL(*old_engine, send_request(&no_dpp, StrEq("GET"), StrEq(""), StrEq("my_key/1"), StrEq(""), _)).WillOnce(SetPointedValue(json)); + EXPECT_CALL(*old_engine, send_request(&no_dpp, StrEq("GET"), StrEq(""), StrEq("my_key/1"), StrEq(""), _, _)).WillOnce(SetPointedValue(json)); - int res = old_engine->get_key(&no_dpp, my_key, actual_key); + int res = old_engine->get_key(&no_dpp, my_key, null_yield, actual_key); ASSERT_EQ(res, 0); ASSERT_EQ(actual_key, from_base64("8qgPWvdtf6zrriS5+nkOzDJ14IGVR6Bgkub5dJn6qeg=")); @@ -182,13 +183,13 @@ TEST_F(TestSSEKMS, test_transit_makekey){ // Mocks the expected return Value from Vault Server using custom Argument Action string post_json = R"({"data": {"ciphertext": "vault:v2:HbdxLnUztGVo+RseCIaYVn/4wEUiJNT6GQfw57KXQmhXVe7i1/kgLWegEPg1I6lexhIuXAM6Q2YvY0aZ","key_version": 1,"plaintext": "3xfTra/dsIf3TMa3mAT2IxPpM7YWm/NvUb4gDfSDX4g="}})"; - EXPECT_CALL(*transit_engine, send_request(&no_dpp, StrEq("POST"), StrEq("/datakey/plaintext/"), StrEq("my_key"), _, _)) + EXPECT_CALL(*transit_engine, send_request(&no_dpp, StrEq("POST"), StrEq("/datakey/plaintext/"), StrEq("my_key"), _, _, _)) .WillOnce(SetPointedValue(post_json)); set_attr(attrs, RGW_ATTR_CRYPT_CONTEXT, R"({"aws:s3:arn": "fred"})"); set_attr(attrs, RGW_ATTR_CRYPT_KEYID, my_key); - int res = transit_engine->make_actual_key(&no_dpp, attrs, actual_key); + int res = transit_engine->make_actual_key(&no_dpp, attrs, null_yield, actual_key); std::string cipher_text { get_str_attribute(attrs,RGW_ATTR_CRYPT_DATAKEY) }; ASSERT_EQ(res, 0); @@ -206,13 +207,13 @@ TEST_F(TestSSEKMS, test_transit_reconstitutekey){ // Mocks the expected return Value from Vault Server using custom Argument Action set_attr(attrs, RGW_ATTR_CRYPT_DATAKEY, "vault:v2:HbdxLnUztGVo+RseCIaYVn/4wEUiJNT6GQfw57KXQmhXVe7i1/kgLWegEPg1I6lexhIuXAM6Q2YvY0aZ"); string post_json = R"({"data": {"key_version": 1,"plaintext": "3xfTra/dsIf3TMa3mAT2IxPpM7YWm/NvUb4gDfSDX4g="}})"; - EXPECT_CALL(*transit_engine, send_request(&no_dpp, StrEq("POST"), StrEq("/decrypt/"), StrEq("my_key"), _, _)) + EXPECT_CALL(*transit_engine, send_request(&no_dpp, StrEq("POST"), StrEq("/decrypt/"), StrEq("my_key"), _, _, _)) .WillOnce(SetPointedValue(post_json)); set_attr(attrs, RGW_ATTR_CRYPT_CONTEXT, R"({"aws:s3:arn": "fred"})"); set_attr(attrs, RGW_ATTR_CRYPT_KEYID, my_key); - int res = transit_engine->reconstitute_actual_key(&no_dpp, attrs, actual_key); + int res = transit_engine->reconstitute_actual_key(&no_dpp, attrs, null_yield, actual_key); ASSERT_EQ(res, 0); ASSERT_EQ(actual_key, from_base64("3xfTra/dsIf3TMa3mAT2IxPpM7YWm/NvUb4gDfSDX4g=")); @@ -226,10 +227,10 @@ TEST_F(TestSSEKMS, test_kv_backend){ // Mocks the expected return value from Vault Server using custom Argument Action string json = R"({"data": {"data": {"key": "8qgPWvdtf6zrriS5+nkOzDJ14IGVR6Bgkub5dJn6qeg="}}})"; - EXPECT_CALL(*kv_engine, send_request(&no_dpp, StrEq("GET"), StrEq(""), StrEq("my_key"), StrEq(""), _)) + EXPECT_CALL(*kv_engine, send_request(&no_dpp, StrEq("GET"), StrEq(""), StrEq("my_key"), StrEq(""), _, _)) .WillOnce(SetPointedValue(json)); - int res = kv_engine->get_key(&no_dpp, my_key, actual_key); + int res = kv_engine->get_key(&no_dpp, my_key, null_yield, actual_key); ASSERT_EQ(res, 0); ASSERT_EQ(actual_key, from_base64("8qgPWvdtf6zrriS5+nkOzDJ14IGVR6Bgkub5dJn6qeg=")); @@ -285,9 +286,9 @@ TEST_F(TestSSEKMS, test_transit_backend_empty_response) // Mocks the expected return Value from Vault Server using custom Argument Action string json = R"({"errors": ["version does not exist or cannot be found"]})"; - EXPECT_CALL(*old_engine, send_request(&no_dpp, StrEq("GET"), StrEq(""), StrEq("/key/nonexistent/1"), StrEq(""), _)).WillOnce(SetPointedValue(json)); + EXPECT_CALL(*old_engine, send_request(&no_dpp, StrEq("GET"), StrEq(""), StrEq("/key/nonexistent/1"), StrEq(""), _, _)).WillOnce(SetPointedValue(json)); - int res = old_engine->get_key(&no_dpp, my_key, actual_key); + int res = old_engine->get_key(&no_dpp, my_key, null_yield, actual_key); ASSERT_EQ(res, -EINVAL); ASSERT_EQ(actual_key, from_base64("")); -- 2.47.3