]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/auth/cephx/CephxProtocol.h
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / auth / cephx / CephxProtocol.h
index b5ec897f35b9ab447e3d29f2ba1435adb5aad4c3..0aedc9d12d9597bd1bdf970e50b0282c121a4cc8 100644 (file)
 /*
   Ceph X protocol
 
-  First, the principal has to authenticate with the authenticator. A
-  shared-secret mechanism is being used, and the negotitaion goes like this:
+  See doc/dev/cephx.rst
 
-  A = Authenticator
-  P = Principle
-  S = Service
-
-  1. Obtaining principal/auth session key
-
-  (Authenticate Request)
-  p->a : principal, principal_addr.  authenticate me!
-
- ...authenticator does lookup in database...
-
-  a->p : A= {principal/auth session key, validity}^principal_secret (*)
-         B= {principal ticket, validity, principal/auth session key}^authsecret
-
-  
-  [principal/auth session key, validity] = service ticket
-  [principal ticket, validity, principal/auth session key] = service ticket info
-
-  (*) annotation: ^ signifies 'encrypted by'
-
-  At this point, if is genuine, the principal should have the principal/auth
-  session key at hand. The next step would be to request an authorization to
-  use some other service:
-
-  2. Obtaining principal/service session key
-
-  p->a : B, {principal_addr, timestamp}^principal/auth session key.  authorize
-         me!
-  a->p : E= {service ticket}^svcsecret
-         F= {principal/service session key, validity}^principal/auth session key
-
-  principal_addr, timestamp = authenticator
-
-  service ticket = principal name, client network address, validity, principal/service session key
-
-  Note that steps 1 and 2 are pretty much the same thing; contacting the
-  authenticator and requesting for a key.
-
-  Following this the principal should have a principal/service session key that
-  could be used later on for creating a session:
-
-  3. Opening a session to a service
-
-  p->s : E + {principal_addr, timestamp}^principal/service session key
-  s->p : {timestamp+1}^principal/service/session key
-
-  timestamp+1 = reply authenticator
-
-  Now, the principal is fully authenticated with the service. So, logically we
-  have 2 main actions here. The first one would be to obtain a session key to
-  the service (steps 1 and 2), and the second one would be to authenticate with
-  the service, using that ticket.
 */
 
 /* authenticate requests */
@@ -98,14 +45,16 @@ struct CephXServerChallenge {
   uint64_t server_challenge;
 
   void encode(bufferlist& bl) const {
+    using ceph::encode;
     __u8 struct_v = 1;
-    ::encode(struct_v, bl);
-    ::encode(server_challenge, bl);
+    encode(struct_v, bl);
+    encode(server_challenge, bl);
   }
-  void decode(bufferlist::iterator& bl) {
+  void decode(bufferlist::const_iterator& bl) {
+    using ceph::decode;
     __u8 struct_v;
-    ::decode(struct_v, bl);
-    ::decode(server_challenge, bl);
+    decode(struct_v, bl);
+    decode(server_challenge, bl);
   }
 };
 WRITE_CLASS_ENCODER(CephXServerChallenge)
@@ -117,10 +66,12 @@ struct CephXRequestHeader {
   __u16 request_type;
 
   void encode(bufferlist& bl) const {
-    ::encode(request_type, bl);
+    using ceph::encode;
+    encode(request_type, bl);
   }
-  void decode(bufferlist::iterator& bl) {
-    ::decode(request_type, bl);
+  void decode(bufferlist::const_iterator& bl) {
+    using ceph::decode;
+    decode(request_type, bl);
   }
 };
 WRITE_CLASS_ENCODER(CephXRequestHeader)
@@ -130,12 +81,14 @@ struct CephXResponseHeader {
   int32_t status;
 
   void encode(bufferlist& bl) const {
-    ::encode(request_type, bl);
-    ::encode(status, bl);
+    using ceph::encode;
+    encode(request_type, bl);
+    encode(status, bl);
   }
-  void decode(bufferlist::iterator& bl) {
-    ::decode(request_type, bl);
-    ::decode(status, bl);
+  void decode(bufferlist::const_iterator& bl) {
+    using ceph::decode;
+    decode(request_type, bl);
+    decode(status, bl);
   }
 };
 WRITE_CLASS_ENCODER(CephXResponseHeader)
@@ -147,17 +100,19 @@ struct CephXTicketBlob {
   CephXTicketBlob() : secret_id(0) {}
 
   void encode(bufferlist& bl) const {
+     using ceph::encode;
      __u8 struct_v = 1;
-    ::encode(struct_v, bl);
-    ::encode(secret_id, bl);
-    ::encode(blob, bl);
+     encode(struct_v, bl);
+     encode(secret_id, bl);
+     encode(blob, bl);
   }
 
-  void decode(bufferlist::iterator& bl) {
-    __u8 struct_v;
-    ::decode(struct_v, bl);
-    ::decode(secret_id, bl);
-    ::decode(blob, bl);
+  void decode(bufferlist::const_iterator& bl) {
+     using ceph::decode;
+     __u8 struct_v;
+     decode(struct_v, bl);
+     decode(secret_id, bl);
+     decode(blob, bl);
   }
 };
 WRITE_CLASS_ENCODER(CephXTicketBlob)
@@ -167,21 +122,28 @@ struct CephXAuthenticate {
   uint64_t client_challenge;
   uint64_t key;
   CephXTicketBlob old_ticket;
+  uint32_t other_keys = 0;  // replaces CephXServiceTicketRequest
 
   void encode(bufferlist& bl) const {
-    __u8 struct_v = 1;
-    ::encode(struct_v, bl);
-    ::encode(client_challenge, bl);
-    ::encode(key, bl);
-    ::encode(old_ticket, bl);
+    using ceph::encode;
+    __u8 struct_v = 2;
+    encode(struct_v, bl);
+    encode(client_challenge, bl);
+    encode(key, bl);
+    encode(old_ticket, bl);
+    encode(other_keys, bl);
   }
-  void decode(bufferlist::iterator& bl) {
+  void decode(bufferlist::const_iterator& bl) {
+    using ceph::decode;
     __u8 struct_v;
-    ::decode(struct_v, bl);
-    ::decode(client_challenge, bl);
-    ::decode(key, bl);
-    ::decode(old_ticket, bl);
- }
+    decode(struct_v, bl);
+    decode(client_challenge, bl);
+    decode(key, bl);
+    decode(old_ticket, bl);
+    if (struct_v >= 2) {
+      decode(other_keys, bl);
+    }
+  }
 };
 WRITE_CLASS_ENCODER(CephXAuthenticate)
 
@@ -189,12 +151,14 @@ struct CephXChallengeBlob {
   uint64_t server_challenge, client_challenge;
   
   void encode(bufferlist& bl) const {
-    ::encode(server_challenge, bl);
-    ::encode(client_challenge, bl);
+     using ceph::encode;
+    encode(server_challenge, bl);
+    encode(client_challenge, bl);
   }
-  void decode(bufferlist::iterator& bl) {
-    ::decode(server_challenge, bl);
-    ::decode(client_challenge, bl);
+  void decode(bufferlist::const_iterator& bl) {
+    using ceph::decode;
+    decode(server_challenge, bl);
+    decode(client_challenge, bl);
   }
 };
 WRITE_CLASS_ENCODER(CephXChallengeBlob)
@@ -235,14 +199,16 @@ struct CephXServiceTicketRequest {
   uint32_t keys;
 
   void encode(bufferlist& bl) const {
+    using ceph::encode;
     __u8 struct_v = 1;
-    ::encode(struct_v, bl);
-    ::encode(keys, bl);
+    encode(struct_v, bl);
+    encode(keys, bl);
   }
-  void decode(bufferlist::iterator& bl) {
+  void decode(bufferlist::const_iterator& bl) {
+    using ceph::decode;
     __u8 struct_v;
-    ::decode(struct_v, bl);
-    ::decode(keys, bl);
+    decode(struct_v, bl);
+    decode(keys, bl);
   }
 };
 WRITE_CLASS_ENCODER(CephXServiceTicketRequest)
@@ -254,15 +220,28 @@ WRITE_CLASS_ENCODER(CephXServiceTicketRequest)
 
 struct CephXAuthorizeReply {
   uint64_t nonce_plus_one;
+  std::string connection_secret;
   void encode(bufferlist& bl) const {
+    using ceph::encode;
     __u8 struct_v = 1;
-    ::encode(struct_v, bl);
-    ::encode(nonce_plus_one, bl);
+    if (connection_secret.size()) {
+      struct_v = 2;
+    }
+    encode(struct_v, bl);
+    encode(nonce_plus_one, bl);
+    if (struct_v >= 2) {
+      struct_v = 2;
+      encode(connection_secret, bl);
+    }
   }
-  void decode(bufferlist::iterator& bl) {
+  void decode(bufferlist::const_iterator& bl) {
+    using ceph::decode;
     __u8 struct_v;
-    ::decode(struct_v, bl);
-    ::decode(nonce_plus_one, bl);
+    decode(struct_v, bl);
+    decode(nonce_plus_one, bl);
+    if (struct_v >= 2) {
+      decode(connection_secret, bl);
+    }
   }
 };
 WRITE_CLASS_ENCODER(CephXAuthorizeReply)
@@ -279,8 +258,9 @@ public:
     : AuthAuthorizer(CEPH_AUTH_CEPHX), cct(cct_), nonce(0) {}
 
   bool build_authorizer();
-  bool verify_reply(bufferlist::iterator& reply) override;
-  bool add_challenge(CephContext *cct, bufferlist& challenge) override;
+  bool verify_reply(bufferlist::const_iterator& reply,
+                   std::string *connection_secret) override;
+  bool add_challenge(CephContext *cct, const bufferlist& challenge) override;
 };
 
 
@@ -300,7 +280,7 @@ struct CephXTicketHandler {
 
   // to build our ServiceTicket
   bool verify_service_ticket_reply(CryptoKey& principal_secret,
-                                bufferlist::iterator& indata);
+                                bufferlist::const_iterator& indata);
   // to access the service
   CephXAuthorizer *build_authorizer(uint64_t global_id) const;
 
@@ -322,7 +302,7 @@ struct CephXTicketManager {
   explicit CephXTicketManager(CephContext *cct_) : global_id(0), cct(cct_) {}
 
   bool verify_service_ticket_reply(CryptoKey& principal_secret,
-                                bufferlist::iterator& indata);
+                                bufferlist::const_iterator& indata);
 
   CephXTicketHandler& get_handler(uint32_t type) {
     tickets_map_t::iterator i = tickets_map.find(type);
@@ -331,7 +311,7 @@ struct CephXTicketManager {
     CephXTicketHandler newTicketHandler(cct, type);
     std::pair < tickets_map_t::iterator, bool > res =
        tickets_map.insert(std::make_pair(type, newTicketHandler));
-    assert(res.second);
+    ceph_assert(res.second);
     return res.first->second;
   }
   CephXAuthorizer *build_authorizer(uint32_t service_id) const;
@@ -352,16 +332,18 @@ struct CephXServiceTicket {
   utime_t validity;
 
   void encode(bufferlist& bl) const {
+    using ceph::encode;
     __u8 struct_v = 1;
-    ::encode(struct_v, bl);
-    ::encode(session_key, bl);
-    ::encode(validity, bl);
+    encode(struct_v, bl);
+    encode(session_key, bl);
+    encode(validity, bl);
   }
-  void decode(bufferlist::iterator& bl) {
+  void decode(bufferlist::const_iterator& bl) {
+    using ceph::decode;
     __u8 struct_v;
-    ::decode(struct_v, bl);
-    ::decode(session_key, bl);
-    ::decode(validity, bl);
+    decode(struct_v, bl);
+    decode(session_key, bl);
+    decode(validity, bl);
   }
 };
 WRITE_CLASS_ENCODER(CephXServiceTicket)
@@ -372,16 +354,18 @@ struct CephXServiceTicketInfo {
   CryptoKey session_key;
 
   void encode(bufferlist& bl) const {
+    using ceph::encode;
     __u8 struct_v = 1;
-    ::encode(struct_v, bl);
-    ::encode(ticket, bl);
-    ::encode(session_key, bl);
+    encode(struct_v, bl);
+    encode(ticket, bl);
+    encode(session_key, bl);
   }
-  void decode(bufferlist::iterator& bl) {
+  void decode(bufferlist::const_iterator& bl) {
+    using ceph::decode;
     __u8 struct_v;
-    ::decode(struct_v, bl);
-    ::decode(ticket, bl);
-    ::decode(session_key, bl);
+    decode(struct_v, bl);
+    decode(ticket, bl);
+    decode(session_key, bl);
   }
 };
 WRITE_CLASS_ENCODER(CephXServiceTicketInfo)
@@ -389,14 +373,16 @@ WRITE_CLASS_ENCODER(CephXServiceTicketInfo)
 struct CephXAuthorizeChallenge : public AuthAuthorizerChallenge {
   uint64_t server_challenge;
   void encode(bufferlist& bl) const {
+    using ceph::encode;
     __u8 struct_v = 1;
-    ::encode(struct_v, bl);
-    ::encode(server_challenge, bl);
+    encode(struct_v, bl);
+    encode(server_challenge, bl);
   }
-  void decode(bufferlist::iterator& bl) {
+  void decode(bufferlist::const_iterator& bl) {
+    using ceph::decode;
     __u8 struct_v;
-    ::decode(struct_v, bl);
-    ::decode(server_challenge, bl);
+    decode(struct_v, bl);
+    decode(server_challenge, bl);
   }
 };
 WRITE_CLASS_ENCODER(CephXAuthorizeChallenge)
@@ -406,21 +392,22 @@ struct CephXAuthorize {
   bool have_challenge = false;
   uint64_t server_challenge_plus_one = 0;
   void encode(bufferlist& bl) const {
+    using ceph::encode;
     __u8 struct_v = 2;
-    ::encode(struct_v, bl);
-    ::encode(nonce, bl);
-    ::encode(have_challenge, bl);
-    ::encode(server_challenge_plus_one, bl);
+    encode(struct_v, bl);
+    encode(nonce, bl);
+    encode(have_challenge, bl);
+    encode(server_challenge_plus_one, bl);
   }
-  void decode(bufferlist::iterator& bl) {
+  void decode(bufferlist::const_iterator& bl) {
+    using ceph::decode;
     __u8 struct_v;
-    ::decode(struct_v, bl);
-    ::decode(nonce, bl);
+    decode(struct_v, bl);
+    decode(nonce, bl);
     if (struct_v >= 2) {
-      ::decode(have_challenge, bl);
-      ::decode(server_challenge_plus_one, bl);
+      decode(have_challenge, bl);
+      decode(server_challenge_plus_one, bl);
     }
-
   }
 };
 WRITE_CLASS_ENCODER(CephXAuthorize)
@@ -436,11 +423,14 @@ bool cephx_decode_ticket(CephContext *cct, KeyStore *keys,
  * Verify authorizer and generate reply authorizer
  */
 extern bool cephx_verify_authorizer(
-  CephContext *cct, KeyStore *keys,
-  bufferlist::iterator& indata,
+  CephContext *cct,
+  KeyStore *keys,
+  bufferlist::const_iterator& indata,
+  size_t connection_secret_required_len,
   CephXServiceTicketInfo& ticket_info,
   std::unique_ptr<AuthAuthorizerChallenge> *challenge,
-  bufferlist& reply_bl);
+  std::string *connection_secret,
+  bufferlist *reply_bl);
 
 
 
@@ -453,7 +443,8 @@ extern bool cephx_verify_authorizer(
 static constexpr uint64_t AUTH_ENC_MAGIC = 0xff009cad8826aa55ull;
 
 template <typename T>
-void decode_decrypt_enc_bl(CephContext *cct, T& t, CryptoKey key, bufferlist& bl_enc, 
+void decode_decrypt_enc_bl(CephContext *cct, T& t, CryptoKey key,
+                          const bufferlist& bl_enc,
                           std::string &error)
 {
   uint64_t magic;
@@ -462,10 +453,10 @@ void decode_decrypt_enc_bl(CephContext *cct, T& t, CryptoKey key, bufferlist& bl
   if (key.decrypt(cct, bl_enc, bl, &error) < 0)
     return;
 
-  bufferlist::iterator iter2 = bl.begin();
+  auto iter2 = bl.cbegin();
   __u8 struct_v;
-  ::decode(struct_v, iter2);
-  ::decode(magic, iter2);
+  decode(struct_v, iter2);
+  decode(magic, iter2);
   if (magic != AUTH_ENC_MAGIC) {
     ostringstream oss;
     oss << "bad magic in decode_decrypt, " << magic << " != " << AUTH_ENC_MAGIC;
@@ -473,7 +464,7 @@ void decode_decrypt_enc_bl(CephContext *cct, T& t, CryptoKey key, bufferlist& bl
     return;
   }
 
-  ::decode(t, iter2);
+  decode(t, iter2);
 }
 
 template <typename T>
@@ -482,21 +473,21 @@ void encode_encrypt_enc_bl(CephContext *cct, const T& t, const CryptoKey& key,
 {
   bufferlist bl;
   __u8 struct_v = 1;
-  ::encode(struct_v, bl);
+  encode(struct_v, bl);
   uint64_t magic = AUTH_ENC_MAGIC;
-  ::encode(magic, bl);
-  ::encode(t, bl);
+  encode(magic, bl);
+  encode(t, bl);
 
   key.encrypt(cct, bl, out, &error);
 }
 
 template <typename T>
 int decode_decrypt(CephContext *cct, T& t, const CryptoKey& key,
-                   bufferlist::iterator& iter, std::string &error)
+                   bufferlist::const_iterator& iter, std::string &error)
 {
   bufferlist bl_enc;
   try {
-    ::decode(bl_enc, iter);
+    decode(bl_enc, iter);
     decode_decrypt_enc_bl(cct, t, key, bl_enc, error);
   }
   catch (buffer::error &e) {
@@ -516,9 +507,8 @@ int encode_encrypt(CephContext *cct, const T& t, const CryptoKey& key,
   if (!error.empty()){
     return CEPHX_CRYPT_ERR;
   }
-  ::encode(bl_enc, out);
+  encode(bl_enc, out);
   return 0;
 }
 
-
 #endif