From: Yehuda Sadeh Date: Thu, 6 Mar 2025 14:23:34 +0000 (-0500) Subject: auth/cephx: session key type is set to client key type X-Git-Url: http://git.apps.os.sepia.ceph.com/?a=commitdiff_plain;h=96bca8e93d7b8f45dfcdd499d31632a20c7a0829;p=ceph-ci.git auth/cephx: session key type is set to client key type This ensures that the client supports the specific key type. Signed-off-by: Yehuda Sadeh --- diff --git a/src/auth/cephx/CephxKeyServer.cc b/src/auth/cephx/CephxKeyServer.cc index 9a51de94a45..c0e22824d2b 100644 --- a/src/auth/cephx/CephxKeyServer.cc +++ b/src/auth/cephx/CephxKeyServer.cc @@ -270,17 +270,18 @@ std::list KeyServer::generate_test_instances() return ls; } -bool KeyServer::generate_secret(CryptoKey& secret) +bool KeyServer::generate_secret(CryptoKey& secret, std::optional key_type) { + int type = key_type.value_or(CEPH_CRYPTO_AES256KRB5); bufferptr bp; - auto crypto = cct->get_crypto_manager()->get_handler(CEPH_CRYPTO_AES256KRB5); + auto crypto = cct->get_crypto_manager()->get_handler(type); if (!crypto) return false; if (crypto->create(cct->random(), bp) < 0) return false; - secret.set_secret(CEPH_CRYPTO_AES256KRB5, bp, ceph_clock_now()); + secret.set_secret(type, bp, ceph_clock_now()); return true; } @@ -442,6 +443,7 @@ bool KeyServer::get_service_caps(const EntityName& name, uint32_t service_id, int KeyServer::_build_session_auth_info(uint32_t service_id, const AuthTicket& parent_ticket, + std::optional key_type, CephXSessionAuthInfo& info, double ttl) { @@ -450,7 +452,7 @@ int KeyServer::_build_session_auth_info(uint32_t service_id, info.ticket.init_timestamps(ceph_clock_now(), ttl); info.validity.set_from_double(ttl); - generate_secret(info.session_key); + generate_secret(info.session_key, key_type); // mon keys are stored externally. and the caps are blank anyway. if (service_id != CEPH_ENTITY_TYPE_MON) { @@ -464,6 +466,7 @@ int KeyServer::_build_session_auth_info(uint32_t service_id, int KeyServer::build_session_auth_info(uint32_t service_id, const AuthTicket& parent_ticket, + std::optional key_type, CephXSessionAuthInfo& info) { double ttl; @@ -472,21 +475,35 @@ int KeyServer::build_session_auth_info(uint32_t service_id, return -EACCES; } + /* either use the provided key type, or the one that the service + * is using. As things are, there are two different cases: + * one that this is being called as a result of a client call + * and in which case we'll be provided with the client's key type. + * The second case is when the monitor generates tickets to + * connects to the manager, in which case we want to use + * the manager's key type. In any case, we assume that services + * are upgraded first before clients, so we prioritize client's + * key type over the service key type. + */ + int ktype = key_type.value_or(info.service_secret.get_type()); + std::scoped_lock l{lock}; - return _build_session_auth_info(service_id, parent_ticket, info, ttl); + return _build_session_auth_info(service_id, parent_ticket, + ktype, info, ttl); } int KeyServer::build_session_auth_info(uint32_t service_id, const AuthTicket& parent_ticket, const CryptoKey& service_secret, uint64_t secret_id, + std::optional key_type, CephXSessionAuthInfo& info) { info.service_secret = service_secret; info.secret_id = secret_id; std::scoped_lock l{lock}; - return _build_session_auth_info(service_id, parent_ticket, info, + return _build_session_auth_info(service_id, parent_ticket, key_type, info, cct->_conf->auth_service_ticket_ttl); } diff --git a/src/auth/cephx/CephxKeyServer.h b/src/auth/cephx/CephxKeyServer.h index b4ebffec137..b21b815f7d5 100644 --- a/src/auth/cephx/CephxKeyServer.h +++ b/src/auth/cephx/CephxKeyServer.h @@ -235,6 +235,7 @@ class KeyServer : public KeyStore { void _dump_rotating_secrets(); int _build_session_auth_info(uint32_t service_id, const AuthTicket& parent_ticket, + std::optional key_type, CephXSessionAuthInfo& info, double ttl); bool _get_service_caps(const EntityName& name, uint32_t service_id, @@ -243,7 +244,7 @@ public: KeyServer() : lock{ceph::make_mutex("KeyServer::lock")} {} KeyServer(CephContext *cct_, KeyRing *extra_secrets); KeyServer& operator=(const KeyServer&) = delete; - bool generate_secret(CryptoKey& secret); + bool generate_secret(CryptoKey& secret, std::optional type = std::nullopt); bool get_secret(const EntityName& name, CryptoKey& secret) const override; bool get_auth(const EntityName& name, EntityAuth& auth) const; @@ -261,11 +262,13 @@ public: int build_session_auth_info(uint32_t service_id, const AuthTicket& parent_ticket, + std::optional key_type, CephXSessionAuthInfo& info); int build_session_auth_info(uint32_t service_id, const AuthTicket& parent_ticket, const CryptoKey& service_secret, uint64_t secret_id, + std::optional key_type, CephXSessionAuthInfo& info); /* get current secret for specific service type */ diff --git a/src/auth/cephx/CephxServiceHandler.cc b/src/auth/cephx/CephxServiceHandler.cc index 4921728ae52..ee1b39ab9f5 100644 --- a/src/auth/cephx/CephxServiceHandler.cc +++ b/src/auth/cephx/CephxServiceHandler.cc @@ -243,7 +243,7 @@ int CephxServiceHandler::handle_request( info.ticket.init_timestamps(ceph_clock_now(), ttl); info.validity.set_from_double(ttl); - key_server->generate_secret(session_key); + key_server->generate_secret(session_key, eauth.key.get_type()); info.session_key = session_key; if (psession_key) { @@ -308,6 +308,7 @@ int CephxServiceHandler::handle_request( key_server->build_session_auth_info( service_id, info.ticket, + eauth.key.get_type(), svc_info); info_vec.push_back(svc_info); } @@ -370,6 +371,7 @@ int CephxServiceHandler::handle_request( int r = key_server->build_session_auth_info( service_id, auth_ticket_info.ticket, // parent ticket (client's auth ticket) + auth_ticket_info.session_key.get_type(), /* keep the same encryption type as in the session key */ info); // tolerate missing MGR rotating key for the purposes of upgrades. if (r < 0) { diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 5e1dd1d4a69..a81f4fcf6ca 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -6385,7 +6385,7 @@ bool Monitor::get_authorizer(int service_id, AuthAuthorizer **authorizer) } ret = key_server.build_session_auth_info( - service_id, auth_ticket_info.ticket, secret, (uint64_t)-1, info); + service_id, auth_ticket_info.ticket, secret, (uint64_t)-1, secret.get_type(), info); if (ret < 0) { dout(0) << __func__ << " failed to build mon session_auth_info " << cpp_strerror(ret) << dendl; @@ -6394,7 +6394,7 @@ bool Monitor::get_authorizer(int service_id, AuthAuthorizer **authorizer) } else if (service_id == CEPH_ENTITY_TYPE_MGR) { // mgr ret = key_server.build_session_auth_info( - service_id, auth_ticket_info.ticket, info); + service_id, auth_ticket_info.ticket, std::nullopt, info); if (ret < 0) { derr << __func__ << " failed to build mgr service session_auth_info " << cpp_strerror(ret) << dendl;