From 2049689178dfe952763a0cb3f3c44f93c620136b Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Thu, 27 Feb 2025 11:55:37 -0500 Subject: [PATCH] ceph-authtool: support --key-type param Also move the encryption handlers out of the ceph_context. Handlers are now returned as a shared_ptr, to support the creation of new handlers with different params (such as the usage param). Signed-off-by: Yehuda Sadeh --- src/auth/Crypto.cc | 44 ++++++++++++++++++++++++++++++++ src/auth/Crypto.h | 21 +++++++++++++++ src/auth/cephx/CephxKeyServer.cc | 2 +- src/common/ceph_context.cc | 25 ++---------------- src/common/ceph_context.h | 9 ++++--- src/rgw/rgw_rest_s3.cc | 2 +- src/rgw/rgw_sts.cc | 2 +- src/tools/ceph_authtool.cc | 17 ++++++++++-- 8 files changed, 90 insertions(+), 32 deletions(-) diff --git a/src/auth/Crypto.cc b/src/auth/Crypto.cc index 20dfe06b0b6..aed7a2e3a50 100644 --- a/src/auth/Crypto.cc +++ b/src/auth/Crypto.cc @@ -1051,5 +1051,49 @@ CryptoHandler *CryptoHandler::create(int type) } } +CryptoManager::CryptoManager(CephContext *_cct) : cct(_cct) { + crypto_none.reset(CryptoHandler::create(CEPH_CRYPTO_NONE)); + crypto_aes.reset(CryptoHandler::create(CEPH_CRYPTO_AES)); + crypto_aes256krb5.reset(CryptoHandler::create(CEPH_CRYPTO_AES256KRB5)); + + supported_crypto_types = { CEPH_CRYPTO_NONE, CEPH_CRYPTO_AES, CEPH_CRYPTO_AES256KRB5 }; +} + +std::shared_ptr CryptoManager::get_handler(int type) +{ + switch (type) { + case CEPH_CRYPTO_NONE: + return crypto_none; + case CEPH_CRYPTO_AES: + return crypto_aes; + case CEPH_CRYPTO_AES256KRB5: + return crypto_aes256krb5; + default: + break; + }; + return nullptr; +} + +int CryptoManager::get_key_type(const std::string& s) +{ + auto l = s; + std::transform(l.begin(), l.end(), l.begin(), ::tolower); + if (l == "aes") { + return CEPH_CRYPTO_AES; + } + if (l == "aes256k") { + return CEPH_CRYPTO_AES256KRB5; + } + if (l == "none") { + return CEPH_CRYPTO_NONE; + } + return -ENOENT; +} + +bool CryptoManager::crypto_type_supported(int type) const +{ + return supported_crypto_types.find(type) != supported_crypto_types.end(); +} + #pragma clang diagnostic pop #pragma GCC diagnostic pop diff --git a/src/auth/Crypto.h b/src/auth/Crypto.h index 7153a84d845..ddb8df067fb 100644 --- a/src/auth/Crypto.h +++ b/src/auth/Crypto.h @@ -226,4 +226,25 @@ public: }; +class CryptoManager { + CephContext *cct; + std::shared_ptr crypto_none; + std::shared_ptr crypto_aes; + std::shared_ptr crypto_aes256krb5; + + std::set supported_crypto_types; +public: + CryptoManager(CephContext *_cct); + + const std::set& get_supported_crypto_types() const { + return supported_crypto_types; + } + + static int get_key_type(const std::string& s); + bool crypto_type_supported(int type) const; + + std::shared_ptr get_handler(int type); +}; + + #endif diff --git a/src/auth/cephx/CephxKeyServer.cc b/src/auth/cephx/CephxKeyServer.cc index e49cea16a54..4bb8b638a1e 100644 --- a/src/auth/cephx/CephxKeyServer.cc +++ b/src/auth/cephx/CephxKeyServer.cc @@ -273,7 +273,7 @@ std::list KeyServer::generate_test_instances() bool KeyServer::generate_secret(CryptoKey& secret) { bufferptr bp; - CryptoHandler *crypto = cct->get_crypto_handler(CEPH_CRYPTO_AES); + auto crypto = cct->get_crypto_manager()->get_handler(CEPH_CRYPTO_AES); if (!crypto) return false; diff --git a/src/common/ceph_context.cc b/src/common/ceph_context.cc index 064adecc51d..2b757ccefef 100644 --- a/src/common/ceph_context.cc +++ b/src/common/ceph_context.cc @@ -719,9 +719,6 @@ CephContext::CephContext(uint32_t module_type_, _perf_counters_collection(NULL), _perf_counters_conf_obs(NULL), _heartbeat_map(NULL), - _crypto_none(NULL), - _crypto_aes(NULL), - _crypto_aes256krb5(NULL), _plugin_registry(NULL), #ifdef CEPH_DEBUG_MUTEX _lockdep_obs(NULL), @@ -782,10 +779,8 @@ CephContext::CephContext(uint32_t module_type_, _admin_socket->register_command("log dump", _admin_hook, "dump recent log entries to log file"); _admin_socket->register_command("log reopen", _admin_hook, "reopen log file"); - _crypto_none = CryptoHandler::create(CEPH_CRYPTO_NONE); - _crypto_aes = CryptoHandler::create(CEPH_CRYPTO_AES); - _crypto_aes256krb5 = CryptoHandler::create(CEPH_CRYPTO_AES256KRB5); _crypto_random.reset(new CryptoRandom()); + _crypto_mgr.reset(new CryptoManager(this)); lookup_or_create_singleton_object("mempool_obs", false, this); } @@ -845,9 +840,7 @@ CephContext::~CephContext() delete _log; _log = NULL; - delete _crypto_none; - delete _crypto_aes; - delete _crypto_aes256krb5; + _crypto_mgr.reset(); if (_crypto_inited > 0) { ceph_assert(_crypto_inited == 1); // or else someone explicitly did // init but not shutdown @@ -1046,20 +1039,6 @@ AdminSocket *CephContext::get_admin_socket() return _admin_socket; } -CryptoHandler *CephContext::get_crypto_handler(int type) -{ - switch (type) { - case CEPH_CRYPTO_NONE: - return _crypto_none; - case CEPH_CRYPTO_AES: - return _crypto_aes; - case CEPH_CRYPTO_AES256KRB5: - return _crypto_aes256krb5; - default: - return NULL; - } -} - void CephContext::notify_pre_fork() { { diff --git a/src/common/ceph_context.h b/src/common/ceph_context.h index 60af31a2c35..5f236fe3b00 100644 --- a/src/common/ceph_context.h +++ b/src/common/ceph_context.h @@ -53,6 +53,7 @@ namespace google_breakpad { class AdminSocket; class AdminSocketHook; class CryptoHandler; +class CryptoManager; class CryptoRandom; class MonMap; @@ -236,7 +237,9 @@ public: /** * get a crypto handler */ - CryptoHandler *get_crypto_handler(int type); + CryptoManager *get_crypto_manager() { + return _crypto_mgr.get(); + } CryptoRandom* random() const { return _crypto_random.get(); } @@ -377,10 +380,8 @@ private: std::vector _fork_watchers; // crypto - CryptoHandler *_crypto_none; - CryptoHandler *_crypto_aes; - CryptoHandler *_crypto_aes256krb5; std::unique_ptr _crypto_random; + std::unique_ptr _crypto_mgr; // experimental CephContextObs *_cct_obs; diff --git a/src/rgw/rgw_rest_s3.cc b/src/rgw/rgw_rest_s3.cc index 728eef2ecc6..5ed40373ee5 100644 --- a/src/rgw/rgw_rest_s3.cc +++ b/src/rgw/rgw_rest_s3.cc @@ -7167,7 +7167,7 @@ rgw::auth::s3::STSEngine::get_session_token(const DoutPrefixProvider* dpp, const return -EINVAL; } - auto* cryptohandler = cct->get_crypto_handler(CEPH_CRYPTO_AES); + auto cryptohandler = cct->get_crypto_manager()->get_handler(CEPH_CRYPTO_AES); if (! cryptohandler) { return -EINVAL; } diff --git a/src/rgw/rgw_sts.cc b/src/rgw/rgw_sts.cc index 867cfc544a2..ab311025cba 100644 --- a/src/rgw/rgw_sts.cc +++ b/src/rgw/rgw_sts.cc @@ -71,7 +71,7 @@ int Credentials::generateCredentials(const DoutPrefixProvider *dpp, expiration = ceph::to_iso_8601(exp); //Session Token - Encrypt using AES - auto* cryptohandler = cct->get_crypto_handler(CEPH_CRYPTO_AES); + auto cryptohandler = cct->get_crypto_manager()->get_handler(CEPH_CRYPTO_AES); if (! cryptohandler) { ldpp_dout(dpp, 0) << "ERROR: No AES crypto handler found !" << dendl; return -EINVAL; diff --git a/src/tools/ceph_authtool.cc b/src/tools/ceph_authtool.cc index da7957c9d2c..9671ba33eb3 100644 --- a/src/tools/ceph_authtool.cc +++ b/src/tools/ceph_authtool.cc @@ -66,6 +66,8 @@ int main(int argc, const char **argv) map caps; std::string fn; + int key_type = CEPH_CRYPTO_AES; + if (args.empty()) { cerr << argv[0] << ": -h or --help for usage" << std::endl; exit(1); @@ -123,6 +125,17 @@ int main(int argc, const char **argv) create_keyring = true; } else if (ceph_argparse_witharg(args, i, &val, "--import-keyring", (char*)NULL)) { import_keyring = val; + } else if (ceph_argparse_witharg(args, i, &val, "--key-type", (char*)NULL)) { + auto cm = cct->get_crypto_manager(); + key_type = cm->get_key_type(val); + if (key_type < 0) { + cerr << "invalid key type: " << val << std::endl; + exit(1); + } + if (!cm->crypto_type_supported(key_type)) { + cerr << "unsupported key type: " << val << std::endl; + exit(1); + } } else if (ceph_argparse_witharg(args, i, &val, "--mode", (char*)NULL)) { std::string err; mode = strict_strtoll(val.c_str(), 8, &err); @@ -171,7 +184,7 @@ int main(int argc, const char **argv) if (gen_print_key) { CryptoKey key; - key.create(g_ceph_context, CEPH_CRYPTO_AES); + key.create(g_ceph_context, key_type); cout << key << std::endl; return 0; } @@ -240,7 +253,7 @@ int main(int argc, const char **argv) } if (gen_key) { EntityAuth eauth; - eauth.key.create(g_ceph_context, CEPH_CRYPTO_AES); + eauth.key.create(g_ceph_context, key_type); keyring.add(ename, eauth); modified = true; } -- 2.39.5