]> git.proxmox.com Git - ceph.git/blobdiff - ceph/src/auth/cephx/CephxProtocol.cc
update sources to ceph Nautilus 14.2.1
[ceph.git] / ceph / src / auth / cephx / CephxProtocol.cc
index cc5f44964c2adeed0b7f357ae2fd9af5f573ab16..6254d8f3c1e6da096c9362e8e09ce150022ec3e0 100644 (file)
@@ -14,6 +14,7 @@
 
 #include "CephxProtocol.h"
 #include "common/Clock.h"
+#include "common/ceph_context.h"
 #include "common/config.h"
 #include "common/debug.h"
 #include "include/buffer.h"
@@ -55,9 +56,12 @@ bool cephx_build_service_ticket_blob(CephContext *cct, CephXSessionAuthInfo& inf
   ticket_info.ticket = info.ticket;
   ticket_info.ticket.caps = info.ticket.caps;
 
-  ldout(cct, 10) << "build_service_ticket service " << ceph_entity_type_name(info.service_id)
-          << " secret_id " << info.secret_id
-          << " ticket_info.ticket.name=" << ticket_info.ticket.name.to_str() << dendl;
+  ldout(cct, 10) << "build_service_ticket service "
+                << ceph_entity_type_name(info.service_id)
+                << " secret_id " << info.secret_id
+                << " ticket_info.ticket.name="
+                << ticket_info.ticket.name.to_str()
+                << " ticket.global_id " << info.ticket.global_id << dendl;
   blob.secret_id = info.secret_id;
   std::string error;
   if (!info.service_secret.get_secret().length())
@@ -88,10 +92,10 @@ bool cephx_build_service_ticket_reply(CephContext *cct,
                      bufferlist& reply)
 {
   __u8 service_ticket_reply_v = 1;
-  ::encode(service_ticket_reply_v, reply);
+  encode(service_ticket_reply_v, reply);
 
   uint32_t num = ticket_info_vec.size();
-  ::encode(num, reply);
+  encode(num, reply);
   ldout(cct, 10) << "build_service_ticket_reply encoding " << num
           << " tickets with secret " << principal_secret << dendl;
 
@@ -99,10 +103,10 @@ bool cephx_build_service_ticket_reply(CephContext *cct,
        ticket_iter != ticket_info_vec.end();
        ++ticket_iter) {
     CephXSessionAuthInfo& info = *ticket_iter;
-    ::encode(info.service_id, reply);
+    encode(info.service_id, reply);
 
     __u8 service_ticket_v = 1;
-    ::encode(service_ticket_v, reply);
+    encode(service_ticket_v, reply);
 
     CephXServiceTicket msg_a;
     msg_a.session_key = info.session_key;
@@ -118,20 +122,20 @@ bool cephx_build_service_ticket_reply(CephContext *cct,
     if (!cephx_build_service_ticket_blob(cct, info, blob)) {
       return false;
     }
-    ::encode(blob, service_ticket_bl);
+    encode(blob, service_ticket_bl);
 
     ldout(cct, 30) << "service_ticket_blob is ";
     service_ticket_bl.hexdump(*_dout);
     *_dout << dendl;
 
-    ::encode((__u8)should_encrypt_ticket, reply);
+    encode((__u8)should_encrypt_ticket, reply);
     if (should_encrypt_ticket) {
       if (encode_encrypt(cct, service_ticket_bl, ticket_enc_key, reply, error)) {
        ldout(cct, -1) << "error encoding encrypted ticket: " << error << dendl;
         return false;
       }
     } else {
-      ::encode(service_ticket_bl, reply);
+      encode(service_ticket_bl, reply);
     }
   }
   return true;
@@ -141,11 +145,12 @@ bool cephx_build_service_ticket_reply(CephContext *cct,
  * PRINCIPAL: verify our attempt to authenticate succeeded.  fill out
  * this ServiceTicket with the result.
  */
-bool CephXTicketHandler::verify_service_ticket_reply(CryptoKey& secret,
-                                                    bufferlist::iterator& indata)
+bool CephXTicketHandler::verify_service_ticket_reply(
+  CryptoKey& secret,
+  bufferlist::const_iterator& indata)
 {
   __u8 service_ticket_v;
-  ::decode(service_ticket_v, indata);
+  decode(service_ticket_v, indata);
 
   CephXServiceTicket msg_a;
   std::string error;
@@ -155,7 +160,7 @@ bool CephXTicketHandler::verify_service_ticket_reply(CryptoKey& secret,
   }
   
   __u8 ticket_enc;
-  ::decode(ticket_enc, indata);
+  decode(ticket_enc, indata);
 
   bufferlist service_ticket_bl;
   if (ticket_enc) {
@@ -167,10 +172,10 @@ bool CephXTicketHandler::verify_service_ticket_reply(CryptoKey& secret,
       return false;
     }
   } else {
-    ::decode(service_ticket_bl, indata);
+    decode(service_ticket_bl, indata);
   }
-  bufferlist::iterator iter = service_ticket_bl.begin();
-  ::decode(ticket, iter);
+  auto iter = service_ticket_bl.cbegin();
+  decode(ticket, iter);
   ldout(cct, 10) << " ticket.secret_id=" <<  ticket.secret_id << dendl;
 
   ldout(cct, 10) << "verify_service_ticket_reply service " << ceph_entity_type_name(service_id)
@@ -261,18 +266,18 @@ void CephXTicketManager::invalidate_ticket(uint32_t service_id)
  * this ServiceTicket with the result.
  */
 bool CephXTicketManager::verify_service_ticket_reply(CryptoKey& secret,
-                                                    bufferlist::iterator& indata)
+                                                    bufferlist::const_iterator& indata)
 {
   __u8 service_ticket_reply_v;
-  ::decode(service_ticket_reply_v, indata);
+  decode(service_ticket_reply_v, indata);
 
   uint32_t num;
-  ::decode(num, indata);
+  decode(num, indata);
   ldout(cct, 10) << "verify_service_ticket_reply got " << num << " keys" << dendl;
 
   for (int i=0; i<(int)num; i++) {
     uint32_t type;
-    ::decode(type, indata);
+    decode(type, indata);
     ldout(cct, 10) << "got key for service_id " << ceph_entity_type_name(type) << dendl;
     CephXTicketHandler& handler = get_handler(type);
     if (!handler.verify_service_ticket_reply(secret, indata)) {
@@ -281,9 +286,6 @@ bool CephXTicketManager::verify_service_ticket_reply(CryptoKey& secret,
     handler.service_id = type;
   }
 
-  if (!indata.end())
-    return false;
-
   return true;
 }
 
@@ -296,14 +298,14 @@ CephXAuthorizer *CephXTicketHandler::build_authorizer(uint64_t global_id) const
 {
   CephXAuthorizer *a = new CephXAuthorizer(cct);
   a->session_key = session_key;
-  get_random_bytes((char*)&a->nonce, sizeof(a->nonce));
+  cct->random()->get_bytes((char*)&a->nonce, sizeof(a->nonce));
 
-  __u8 authorizer_v = 1;
-  ::encode(authorizer_v, a->bl);
-  ::encode(global_id, a->bl);
-  ::encode(service_id, a->bl);
+  __u8 authorizer_v = 1; // see AUTH_MODE_* in Auth.h
+  encode(authorizer_v, a->bl);
+  encode(global_id, a->bl);
+  encode(service_id, a->bl);
 
-  ::encode(ticket, a->bl);
+  encode(ticket, a->bl);
   a->base_bl = a->bl;
 
   CephXAuthorize msg;
@@ -390,10 +392,12 @@ bool cephx_decode_ticket(CephContext *cct, KeyStore *keys, uint32_t service_id,
  * {timestamp + 1}^session_key
  */
 bool cephx_verify_authorizer(CephContext *cct, KeyStore *keys,
-                            bufferlist::iterator& indata,
+                            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)
 {
   __u8 authorizer_v;
   uint32_t service_id;
@@ -402,12 +406,11 @@ bool cephx_verify_authorizer(CephContext *cct, KeyStore *keys,
   // ticket blob
   CephXTicketBlob ticket;
 
-
   try {
-    ::decode(authorizer_v, indata);
-    ::decode(global_id, indata);
-    ::decode(service_id, indata);
-    ::decode(ticket, indata);
+    decode(authorizer_v, indata);
+    decode(global_id, indata);
+    decode(service_id, indata);
+    decode(ticket, indata);
   } catch (buffer::end_of_buffer &e) {
     // Unable to decode!
     return false;
@@ -429,7 +432,7 @@ bool cephx_verify_authorizer(CephContext *cct, KeyStore *keys,
       ldout(cct, 0) << "verify_authorizer could not get service secret for service "
              << ceph_entity_type_name(service_id) << " secret_id=" << ticket.secret_id << dendl;
       if (cct->_conf->auth_debug && ticket.secret_id == 0)
-       assert(0 == "got secret_id=0");
+       ceph_abort_msg("got secret_id=0");
       return false;
     }
   }
@@ -465,11 +468,11 @@ bool cephx_verify_authorizer(CephContext *cct, KeyStore *keys,
     if (!auth_msg.have_challenge || !c) {
       c = new CephXAuthorizeChallenge;
       challenge->reset(c);
-      get_random_bytes((char*)&c->server_challenge, sizeof(c->server_challenge));
+      cct->random()->get_bytes((char*)&c->server_challenge, sizeof(c->server_challenge));
       ldout(cct,10) << __func__ << " adding server_challenge " << c->server_challenge
                    << dendl;
 
-      encode_encrypt_enc_bl(cct, *c, ticket_info.session_key, reply_bl, error);
+      encode_encrypt_enc_bl(cct, *c, ticket_info.session_key, *reply_bl, error);
       if (!error.empty()) {
        ldout(cct, 10) << "verify_authorizer: encode_encrypt error: " << error << dendl;
        return false;
@@ -491,17 +494,29 @@ bool cephx_verify_authorizer(CephContext *cct, KeyStore *keys,
   CephXAuthorizeReply reply;
   // reply.trans_id = auth_msg.trans_id;
   reply.nonce_plus_one = auth_msg.nonce + 1;
-  if (encode_encrypt(cct, reply, ticket_info.session_key, reply_bl, error)) {
+#ifndef WITH_SEASTAR
+  if (connection_secret) {
+    // generate a connection secret
+    connection_secret->resize(connection_secret_required_len);
+    if (connection_secret_required_len) {
+      cct->random()->get_bytes(connection_secret->data(),
+                              connection_secret_required_len);
+    }
+    reply.connection_secret = *connection_secret;
+  }
+#endif
+  if (encode_encrypt(cct, reply, ticket_info.session_key, *reply_bl, error)) {
     ldout(cct, 10) << "verify_authorizer: encode_encrypt error: " << error << dendl;
     return false;
   }
 
   ldout(cct, 10) << "verify_authorizer ok nonce " << hex << auth_msg.nonce << dec
-          << " reply_bl.length()=" << reply_bl.length() <<  dendl;
+          << " reply_bl.length()=" << reply_bl->length() <<  dendl;
   return true;
 }
 
-bool CephXAuthorizer::verify_reply(bufferlist::iterator& indata)
+bool CephXAuthorizer::verify_reply(bufferlist::const_iterator& indata,
+                                  std::string *connection_secret)
 {
   CephXAuthorizeReply reply;
 
@@ -517,10 +532,16 @@ bool CephXAuthorizer::verify_reply(bufferlist::iterator& indata)
            << " sent " << nonce << dendl;
     return false;
   }
+
+  if (connection_secret &&
+      reply.connection_secret.size()) {
+    *connection_secret = reply.connection_secret;
+  }
   return true;
 }
 
-bool CephXAuthorizer::add_challenge(CephContext *cct, bufferlist& challenge)
+bool CephXAuthorizer::add_challenge(CephContext *cct,
+                                   const bufferlist& challenge)
 {
   bl = base_bl;