]> git.apps.os.sepia.ceph.com Git - ceph-ci.git/commitdiff
auth/cephx: session key type is set to client key type
authorYehuda Sadeh <ysadehwe@ibm.com>
Thu, 6 Mar 2025 14:23:34 +0000 (09:23 -0500)
committerPatrick Donnelly <pdonnell@ibm.com>
Wed, 1 Oct 2025 18:46:44 +0000 (14:46 -0400)
This ensures that the client supports the specific key type.

Signed-off-by: Yehuda Sadeh <ysadehwe@ibm.com>
src/auth/cephx/CephxKeyServer.cc
src/auth/cephx/CephxKeyServer.h
src/auth/cephx/CephxServiceHandler.cc
src/mon/Monitor.cc

index 9a51de94a457fac25e594c731f9538e6aac0c62e..c0e22824d2bec58059b39e37724c3b65c8527d18 100644 (file)
@@ -270,17 +270,18 @@ std::list<KeyServer> KeyServer::generate_test_instances()
   return ls;
 }
 
-bool KeyServer::generate_secret(CryptoKey& secret)
+bool KeyServer::generate_secret(CryptoKey& secret, std::optional<int> 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<int> 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<int> 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<int> 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);
 }
 
index b4ebffec137cf3936baefe0828c42f1af17c45aa..b21b815f7d58642a7be2d49edbe11bf43212ef0a 100644 (file)
@@ -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<int> 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<int> 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<int> 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<int> key_type,
                              CephXSessionAuthInfo& info);
 
   /* get current secret for specific service type */
index 4921728ae52a10aced0f55515cf1c291b861de3c..ee1b39ab9f537ff834856d83632d26a773f677fb 100644 (file)
@@ -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) {
index 5e1dd1d4a6990b7967bc39d6eaad3eb4491272a3..a81f4fcf6caf4c8451329f902080408d8ad84f3c 100644 (file)
@@ -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;