]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
auth: client requests tickets when needed
authorYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 27 Oct 2009 21:40:30 +0000 (14:40 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 27 Oct 2009 21:43:46 +0000 (14:43 -0700)
src/auth/Auth.h
src/auth/cephx/CephxClientHandler.cc
src/auth/cephx/CephxKeyServer.cc
src/auth/cephx/CephxProtocol.cc
src/auth/cephx/CephxProtocol.h
src/auth/cephx/CephxServiceHandler.cc
src/config.cc
src/mon/MonClient.cc
src/testradospp.cc

index 9b4dff852e0c486eafe4415d8a98d710a118089c..56a5359d04a7c7255268ab67f65e3fea70037261 100644 (file)
@@ -192,7 +192,6 @@ struct AuthAuthorizer {
 /*
  * Key management
  */ 
-#define KEY_ROTATE_TIME 20
 #define KEY_ROTATE_NUM 3
 
 struct ExpiringCryptoKey {
index 1c98fc0dd3ded70ed01ba6888b14bcf9e3d045e1..96270a93b647fb9676283273d063bbd9052d2a20 100644 (file)
@@ -31,6 +31,7 @@ int CephxClientHandler::build_request(bufferlist& bl)
 {
   dout(10) << "build_request" << dendl;
 
+  dout(10) << "validate_tickets: want=" << want << " need=" << need << " have=" << have << dendl;
   validate_tickets();
 
   dout(10) << "want=" << want << " need=" << need << " have=" << have << dendl;
@@ -65,7 +66,7 @@ int CephxClientHandler::build_request(bufferlist& bl)
 
   if (need) {
     /* get service tickets */
-    dout(10) << "get service keys: want=" << hex << want << " need=" << need << " have=" << have << dec << dendl;
+    dout(10) << "get service keys: want=" << want << " need=" << need << " have=" << have << dendl;
 
     CephXRequestHeader header;
     header.request_type = CEPHX_GET_PRINCIPAL_SESSION_KEY;
@@ -133,8 +134,10 @@ int CephxClientHandler::handle_response(int ret, bufferlist::iterator& indata)
         dout(0) << "could not verify service_ticket reply" << dendl;
         return -EPERM;
       }
-      if (want == have)
+      validate_tickets();
+      if (!need) {
        ret = 0;
+      }
     }
     break;
 
@@ -178,12 +181,15 @@ void CephxClientHandler::build_rotating_request(bufferlist& bl)
 
 void CephxClientHandler::validate_tickets()
 {
-  tickets.validate_tickets(want, need);
+  tickets.validate_tickets(want, have, need);
 }
 
 bool CephxClientHandler::need_tickets()
 {
   validate_tickets();
+
+  dout(20) << "need_tickets: want=" << want << " need=" << need << " have=" << have << dendl;
+
   return (need != 0);
 }
 
index 1772837b32756645eddb373f2ef5097f8fcbdf28..a20f2af8734142cf8950eab63d917e8678e892e2 100644 (file)
@@ -122,7 +122,7 @@ void KeyServer::_generate_all_rotating_secrets(bool init)
 {
   data.rotating_ver++;
   data.next_rotating_time = g_clock.now();
-  data.next_rotating_time += KEY_ROTATE_TIME;
+  data.next_rotating_time += g_conf.auth_mon_ticket_ttl;
   dout(0) << "generate_all_rotating_secrets()" << dendl;
 
   int i = KEY_ROTATE_NUM;
@@ -160,7 +160,7 @@ void KeyServer::_rotate_secret(uint32_t service_id, int factor)
   ExpiringCryptoKey ek;
   generate_secret(ek.key);
   ek.expiration = g_clock.now();
-  ek.expiration += (KEY_ROTATE_TIME * factor);
+  ek.expiration += (g_conf.auth_mon_ticket_ttl * factor);
   
   data.add_rotating_secret(service_id, ek);
 }
index d31ecfdf3a3d3a347b5bf79a454a8c8fa4487f65..f1df2f85a3eb2ca0c633a8493c96154cdc82a75a 100644 (file)
@@ -55,6 +55,7 @@ bool cephx_build_service_ticket_reply(
 
     CephXServiceTicket msg_a;
     msg_a.session_key = info.session_key;
+    msg_a.validity = info.validity;
     if (encode_encrypt(msg_a, principal_secret, reply) < 0)
       return false;
 
@@ -83,42 +84,74 @@ bool CephXTicketHandler::verify_service_ticket_reply(CryptoKey& secret,
           << " session_key " << msg_a.session_key
            << " validity=" << msg_a.validity << dendl;
   session_key = msg_a.session_key;
-  has_key_flag = true;
+  if (!msg_a.validity.is_zero()) {
+    expires = g_clock.now();
+    expires += msg_a.validity;
+    renew_after = expires;
+    renew_after -= ((double)msg_a.validity.sec() / 4);
+    dout(10) << "ticket expires=" << expires << " renew_after=" << renew_after << dendl;
+  }
+  
+  have_key_flag = true;
   return true;
 }
 
-bool CephXTicketHandler::has_key()
+bool CephXTicketHandler::have_key()
 {
-  if (has_key_flag) {
-    has_key_flag = g_clock.now() < expires;
+  if (have_key_flag) {
+    dout(20) << "have_key: g_clock.now()=" << g_clock.now() << " renew_after=" << renew_after << " expires=" << expires << dendl;
+    have_key_flag = g_clock.now() < expires;
   }
 
-  return has_key_flag;
+  return have_key_flag;
 }
 
-bool CephXTicketHandler::needs_key()
+bool CephXTicketHandler::need_key()
 {
-  if (has_key_flag) {
+  if (have_key_flag) {
+    dout(20) << "need_key: g_clock.now()=" << g_clock.now() << " renew_after=" << renew_after << " expires=" << expires << dendl;
     return (!expires.is_zero()) && (g_clock.now() >= renew_after);
   }
 
   return true;
 }
 
-bool CephXTicketManager::has_key(uint32_t service_id)
+bool CephXTicketManager::have_key(uint32_t service_id)
 {
   map<uint32_t, CephXTicketHandler>::iterator iter = tickets_map.find(service_id);
   if (iter == tickets_map.end())
     return false;
-  return iter->second.has_key();
+  return iter->second.have_key();
 }
 
-bool CephXTicketManager::needs_key(uint32_t service_id)
+bool CephXTicketManager::need_key(uint32_t service_id)
 {
   map<uint32_t, CephXTicketHandler>::iterator iter = tickets_map.find(service_id);
   if (iter == tickets_map.end())
     return true;
-  return iter->second.needs_key();
+  return iter->second.need_key();
+}
+
+void CephXTicketManager::set_have_need_key(uint32_t service_id, uint32_t& have, uint32_t& need)
+{
+  map<uint32_t, CephXTicketHandler>::iterator iter = tickets_map.find(service_id);
+  if (iter == tickets_map.end()) {
+    have &= ~service_id;
+    need |= service_id;
+    dout(0) << "couldn't find entry for service_id " << service_id << dendl;
+    return;
+  }
+
+  dout(10) << "service_id=" << service_id << " need=" << iter->second.need_key() << " have=" << iter->second.have_key() << dendl;
+  if (iter->second.need_key())
+    need |= service_id;
+  else
+    need &= ~service_id;
+
+  if (iter->second.have_key())
+    have |= service_id;
+  else
+    have &= ~service_id;
 }
 
 /*
@@ -188,13 +221,13 @@ CephXAuthorizer *CephXTicketManager::build_authorizer(uint32_t service_id)
   return handler.build_authorizer();
 }
 
-void CephXTicketManager::validate_tickets(uint32_t mask, uint32_t& need)
+void CephXTicketManager::validate_tickets(uint32_t mask, uint32_t& have, uint32_t& need)
 {
   uint32_t i;
   need = 0;
   for (i = 1; i<=mask; i<<=1) {
-    if ((mask & i) && needs_key(i)) {
-      need |= i;
+    if (mask & i) {
+      set_have_need_key(i, have, need);
     }
   }
 }
index 2f8089687f77ee40dd29d120e747e6fea15b68e4..4f645bfeff2bf8dfa81ab41f969f6b914294c95b 100644 (file)
@@ -161,6 +161,7 @@ struct CephXSessionAuthInfo {
   AuthTicket ticket;
   CryptoKey session_key;
   CryptoKey service_secret;
+  utime_t validity;
 };
 
 
@@ -220,9 +221,9 @@ struct CephXTicketHandler {
   CryptoKey session_key;
   AuthBlob ticket;        // opaque to us
   utime_t renew_after, expires;
-  bool has_key_flag;
+  bool have_key_flag;
 
-  CephXTicketHandler() : service_id(0), has_key_flag(false) {}
+  CephXTicketHandler() : service_id(0), have_key_flag(false) {}
 
   // to build our ServiceTicket
   bool verify_service_ticket_reply(CryptoKey& principal_secret,
@@ -230,8 +231,8 @@ struct CephXTicketHandler {
   // to access the service
   CephXAuthorizer *build_authorizer();
 
-  bool has_key();
-  bool needs_key();
+  bool have_key();
+  bool need_key();
 };
 
 struct CephXTicketManager {
@@ -246,9 +247,10 @@ struct CephXTicketManager {
     return handler;
   }
   CephXAuthorizer *build_authorizer(uint32_t service_id);
-  bool has_key(uint32_t service_id);
-  bool needs_key(uint32_t service_id);
-  void validate_tickets(uint32_t mask, uint32_t& need);
+  bool have_key(uint32_t service_id);
+  bool need_key(uint32_t service_id);
+  void set_have_need_key(uint32_t service_id, uint32_t& have, uint32_t& need);
+  void validate_tickets(uint32_t mask, uint32_t& have, uint32_t& need);
 };
 
 
index 9671a9d31b07280999f983770178bc42cf04347b..37f1dfc4c36120fd10a0de3d7cf04207711f76cd 100644 (file)
@@ -80,7 +80,7 @@ int CephxServiceHandler::handle_request(bufferlist::iterator& indata, bufferlist
       for (int pos = 0; pos + sizeof(req.key) <= key_enc.length(); pos+=sizeof(req.key), p++) {
         expected_key ^= *p;
       }
-      dout(0) << " checking key: req.key=" << hex << req.key << " expected_key=" << expected_key << dec << dendl;
+      dout(20) << " checking key: req.key=" << hex << req.key << " expected_key=" << expected_key << dec << dendl;
       if (req.key != expected_key) {
         dout(0) << " unexpected key: req.key=" << req.key << " expected_key=" << expected_key << dendl;
         ret = -EPERM;
@@ -96,8 +96,9 @@ int CephxServiceHandler::handle_request(bufferlist::iterator& indata, bufferlist
        break;
       }
 
-      info.ticket.name = req.name;
       info.ticket.init_timestamps(g_clock.now(), g_conf.auth_mon_ticket_ttl);
+      info.ticket.name = req.name;
+      info.validity += g_conf.auth_mon_ticket_ttl;
 
       key_server->generate_secret(session_key);
 
@@ -149,6 +150,7 @@ int CephxServiceHandler::handle_request(bufferlist::iterator& indata, bufferlist
             ret = r;
             break;
           }
+          info.validity += g_conf.auth_service_ticket_ttl;
           info_vec.push_back(info);
         }
       }
index e600156d1e83c4eb34eca605f4ab8cb700a39b65..cfcc04b37a53fc10793b8ab3ca26d3868c190fbf 100644 (file)
@@ -365,7 +365,7 @@ static struct config_option config_optionsp[] = {
        OPTION(mon_clientid_prealloc, 0, OPT_INT, 100),   // how many clientids to prealloc
        OPTION(paxos_propose_interval, 0, OPT_DOUBLE, 1.0),  // gather updates for this long before proposing a map update
        OPTION(paxos_observer_timeout, 0, OPT_DOUBLE, 5*60), // gather updates for this long before proposing a map update
-       OPTION(auth_mon_ticket_ttl, 0, OPT_DOUBLE, 60*60*24),
+       OPTION(auth_mon_ticket_ttl, 0, OPT_DOUBLE, 60*60*12),
        OPTION(auth_service_ticket_ttl, 0, OPT_DOUBLE, 60*60),
        OPTION(auth_nonce_len, 0, OPT_INT, 16),
        OPTION(client_cache_size, 0, OPT_INT, 1000),
index 2a6df410a1db972607a887cac03307fc67869936..a0fade70a68ff716e5dc6ed5b82f7fcf06f63d34 100644 (file)
@@ -538,6 +538,7 @@ int MonClient::wait_authenticate(double timeout)
 int MonClient::_check_auth_rotating()
 {
   if (state == MC_STATE_HAVE_SESSION && auth && auth->need_tickets()) {
+    dout(10) << "need new tickets!" << dendl;
     MAuth *m = new MAuth;
     m->protocol = auth->get_protocol();
     auth->build_request(m->auth_payload);
index 2449999ea9ee5bdc94e140456bab110ece79a46a..f07fdd724e537d747bcd496d3e07849170aa7bd6 100644 (file)
@@ -59,6 +59,8 @@ int main(int argc, const char **argv)
   r = rados.write(pool, oid, 0, bl, bl.length() - 2);
   cout << "rados.write returned " << r << std::endl;
   r = rados.write(pool, oid, 0, bl, bl.length() - 3);
+  cout << "*** press enter to continue ***" << std::endl;
+  getchar();
   cout << "rados.write returned " << r << std::endl;
   r = rados.write(pool, oid, 0, bl, bl.length() - 4);
   cout << "rados.write returned " << r << std::endl;