From 9f3d9c608403ddada5f682a971dac85825e7d770 Mon Sep 17 00:00:00 2001 From: Casey Bodley Date: Wed, 20 Dec 2023 11:03:24 -0500 Subject: [PATCH] rgw/user: expose functions to generate access/secret keys Signed-off-by: Casey Bodley (cherry picked from commit 21d0ccb69663518d56d7d1dd9b8f983dd2225871) --- src/rgw/driver/rados/rgw_user.cc | 54 ++++++++++++++++++++++++-------- src/rgw/driver/rados/rgw_user.h | 10 ++++++ 2 files changed, 51 insertions(+), 13 deletions(-) diff --git a/src/rgw/driver/rados/rgw_user.cc b/src/rgw/driver/rados/rgw_user.cc index 348d876bfe2..01fa37fdf7c 100644 --- a/src/rgw/driver/rados/rgw_user.cc +++ b/src/rgw/driver/rados/rgw_user.cc @@ -491,6 +491,41 @@ int RGWAccessKeyPool::check_op(RGWUserAdminOpState& op_state, return 0; } +void rgw_generate_secret_key(CephContext* cct, + std::string& secret_key) +{ + char secret_key_buf[SECRET_KEY_LEN + 1]; + gen_rand_alphanumeric_plain(cct, secret_key_buf, sizeof(secret_key_buf)); + secret_key = secret_key_buf; +} + +int rgw_generate_access_key(const DoutPrefixProvider* dpp, + optional_yield y, + rgw::sal::Driver* driver, + std::string& access_key_id) +{ + std::string id; + int r = 0; + + do { + id.resize(PUBLIC_ID_LEN + 1); + gen_rand_alphanumeric_upper(dpp->get_cct(), id.data(), id.size()); + id.pop_back(); // remove trailing null + + if (!validate_access_key(id)) + continue; + + std::unique_ptr duplicate_check; + r = driver->get_user_by_access_key(dpp, id, y, &duplicate_check); + } while (r == 0); + + if (r == -ENOENT) { + access_key_id = std::move(id); + return 0; + } + return r; +} + // Generate a new random key int RGWAccessKeyPool::generate_key(const DoutPrefixProvider *dpp, RGWUserAdminOpState& op_state, optional_yield y, std::string *err_msg) @@ -553,23 +588,16 @@ int RGWAccessKeyPool::generate_key(const DoutPrefixProvider *dpp, RGWUserAdminOp key = op_state.get_secret_key(); } else { - char secret_key_buf[SECRET_KEY_LEN + 1]; - gen_rand_alphanumeric_plain(g_ceph_context, secret_key_buf, sizeof(secret_key_buf)); - key = secret_key_buf; + rgw_generate_secret_key(dpp->get_cct(), key); } // Generate the access key if (key_type == KEY_TYPE_S3 && gen_access) { - char public_id_buf[PUBLIC_ID_LEN + 1]; - - do { - int id_buf_size = sizeof(public_id_buf); - gen_rand_alphanumeric_upper(g_ceph_context, public_id_buf, id_buf_size); - id = public_id_buf; - if (!validate_access_key(id)) - continue; - - } while (!driver->get_user_by_access_key(dpp, id, y, &duplicate_check)); + int r = rgw_generate_access_key(dpp, y, driver, id); + if (r < 0) { + set_err_msg(err_msg, "failed to generate s3 access key"); + return -ERR_INVALID_ACCESS_KEY; + } } if (key_type == KEY_TYPE_SWIFT) { diff --git a/src/rgw/driver/rados/rgw_user.h b/src/rgw/driver/rados/rgw_user.h index c8c3c6dade5..ec177bfdcbd 100644 --- a/src/rgw/driver/rados/rgw_user.h +++ b/src/rgw/driver/rados/rgw_user.h @@ -30,6 +30,16 @@ class RGWUserCtl; class RGWBucketCtl; class RGWUserBuckets; +// generate a random secret access key of SECRET_KEY_LEN=40 +void rgw_generate_secret_key(CephContext* cct, + std::string& secret_key); + +// generate a unique random access key id of PUBLIC_ID_LEN=20 +int rgw_generate_access_key(const DoutPrefixProvider* dpp, + optional_yield y, + rgw::sal::Driver* driver, + std::string& access_key_id); + /** * A string wrapper that includes encode/decode functions for easily accessing * a UID in all forms. In some objects, this may refer to an account id instead -- 2.39.5