From d5b79beddb3bfa63b7f05bce342aaad1375e470c Mon Sep 17 00:00:00 2001
From: Yehuda Sadeh <yehuda@hq.newdream.net>
Date: Wed, 23 Sep 2009 14:58:42 -0700
Subject: [PATCH] auth: move keys_server to the monitor

---
 src/auth/Auth.cc               |  3 ++-
 src/auth/Auth.h                |  3 ++-
 src/auth/AuthProtocol.h        |  7 ++-----
 src/auth/AuthServiceManager.cc |  5 +++--
 src/auth/KeysServer.cc         |  5 +++++
 src/auth/KeysServer.h          |  4 ++++
 src/mon/AuthMonitor.cc         | 27 ++++++++++++++-------------
 src/mon/AuthMonitor.h          |  1 -
 src/mon/Monitor.h              |  4 ++++
 9 files changed, 36 insertions(+), 23 deletions(-)

diff --git a/src/auth/Auth.cc b/src/auth/Auth.cc
index 57914b4f960..848a08ecc85 100644
--- a/src/auth/Auth.cc
+++ b/src/auth/Auth.cc
@@ -97,7 +97,8 @@ bool build_service_ticket_reply(
   return true;
 }
 
-bool verify_service_ticket_request(CryptoKey& service_secret,
+bool verify_service_ticket_request(EntityName& name,
+                                   CryptoKey& service_secret,
                                    CryptoKey& session_key,
 				   AuthServiceTicketRequest& ticket_req,
 				   AuthServiceTicketInfo& ticket_info,
diff --git a/src/auth/Auth.h b/src/auth/Auth.h
index 55ae950a1da..dabae1222de 100644
--- a/src/auth/Auth.h
+++ b/src/auth/Auth.h
@@ -394,7 +394,8 @@ int encode_encrypt(const T& t, CryptoKey& key, bufferlist& out) {
 /*
  * Verify authorizer and generate reply authorizer
  */
-extern bool verify_service_ticket_request(CryptoKey& service_secret,
+extern bool verify_service_ticket_request(EntityName& name,
+                                          CryptoKey& service_secret,
 					  CryptoKey& session_key,
 					  AuthServiceTicketRequest& ticket_req,
 					  AuthServiceTicketInfo& ticket_info,
diff --git a/src/auth/AuthProtocol.h b/src/auth/AuthProtocol.h
index 2067d87dc05..efebb7e52b2 100644
--- a/src/auth/AuthProtocol.h
+++ b/src/auth/AuthProtocol.h
@@ -38,7 +38,7 @@ struct CephXPremable {
 };
 WRITE_CLASS_ENCODER(CephXPremable)
 
-/*
+/* 
   Ceph X-Envelope protocol
 */
 struct CephXEnvRequest1 {
@@ -58,15 +58,12 @@ struct CephXEnvRequest1 {
   void decode(bufferlist::iterator& bl) {
     uint32_t num_auth;
     ::decode(num_auth, bl);
-
-    dout(0) << "num_auth=" << num_auth << dendl;
-
+ 
     auth_types.clear();
 
     for (uint32_t i=0; i<num_auth; i++) {
       uint32_t auth_type;
       ::decode(auth_type, bl);
-    dout(0) << "auth_type[" << i << "] = " << auth_type << dendl;
       auth_types[auth_type] = true;
     }
   }
diff --git a/src/auth/AuthServiceManager.cc b/src/auth/AuthServiceManager.cc
index 3ac3ef05f0a..2895f8f9a00 100644
--- a/src/auth/AuthServiceManager.cc
+++ b/src/auth/AuthServiceManager.cc
@@ -45,7 +45,6 @@ static inline void hexdump(string msg, const char *s, int len)
   dout(0) << msg << ":\n" << buf << dendl;
 }
 
-
 class CephAuthServer {
   /* FIXME: this is all temporary */
   AuthTicket ticket;
@@ -233,10 +232,12 @@ int CephAuthService_X::handle_cephx_protocol(bufferlist::iterator& indata, buffe
     {
       CryptoKey auth_secret;
       auth_server.get_service_secret(auth_secret, CEPHX_PRINCIPAL_AUTH);
+      // ... FIXME .. get entity name, session_key from Monitor::Session
 
       AuthServiceTicketRequest ticket_req;
       AuthServiceTicketInfo ticket_info;
-      if (!verify_service_ticket_request(auth_secret, session_key, ticket_req, ticket_info, indata)) {
+      EntityName name;
+      if (!verify_service_ticket_request(name, auth_secret, session_key, ticket_req, ticket_info, indata)) {
         ret = -EPERM;
         break;
       }
diff --git a/src/auth/KeysServer.cc b/src/auth/KeysServer.cc
index b7562dcced5..35353e3e858 100644
--- a/src/auth/KeysServer.cc
+++ b/src/auth/KeysServer.cc
@@ -54,6 +54,9 @@ bool KeysServerData::get_service_secret(uint32_t service_id, RotatingSecrets& se
   if (iter == rotating_secrets.end())
     return false;
 
+  if (rotating_secrets.size() > 1)
+    ++iter; /* avoid giving the oldest rotating secret, as it'll expire soon */
+
   secret = iter->second;
   return true;
 }
@@ -189,6 +192,8 @@ bool KeysServer::contains(EntityName& name)
 
 void KeysServer::list_secrets(stringstream& ss)
 {
+  Mutex::Locker l(lock);
+
   map<EntityName, CryptoKey>::iterator mapiter = data.secrets_begin();
   if (mapiter != data.secrets_end()) {
     ss << "installed auth entries: " << std::endl;      
diff --git a/src/auth/KeysServer.h b/src/auth/KeysServer.h
index b233ea88faa..afe4f76ce2a 100644
--- a/src/auth/KeysServer.h
+++ b/src/auth/KeysServer.h
@@ -106,6 +106,7 @@ public:
   KeysServer();
 
   bool get_secret(EntityName& name, CryptoKey& secret);
+  bool get_active_rotating_secret(EntityName& name, CryptoKey& secret);
   int start_server(bool init);
   void rotate_timeout(double timeout);
 
@@ -118,6 +119,7 @@ public:
     ::encode(data, bl);
   }
   void decode(bufferlist::iterator& bl) {
+    Mutex::Locker l(lock);
     ::decode(data, bl);
   }
   bool contains(EntityName& name);
@@ -155,6 +157,8 @@ public:
   void decode_rotating(bufferlist& rotating_bl);
 
   bool get_rotating_encrypted(EntityName& name, bufferlist& enc_bl);
+
+  Mutex& get_lock() { return lock; }
 };
 WRITE_CLASS_ENCODER(KeysServer);
 
diff --git a/src/mon/AuthMonitor.cc b/src/mon/AuthMonitor.cc
index 06ef3cd0e33..c0295d479c6 100644
--- a/src/mon/AuthMonitor.cc
+++ b/src/mon/AuthMonitor.cc
@@ -53,7 +53,7 @@ ostream& operator<<(ostream& out, AuthMonitor& pm)
 void AuthMonitor::check_rotate()
 {
   AuthLibEntry entry;
-  if (!keys_server.updated_rotating(entry.rotating_bl, last_rotating_ver))
+  if (!mon->keys_server.updated_rotating(entry.rotating_bl, last_rotating_ver))
     return;
   dout(0) << "AuthMonitor::tick() updated rotating, now calling propose_pending" << dendl;
 
@@ -87,7 +87,7 @@ void AuthMonitor::on_active()
 
   if (!mon->is_leader())
     return;
-  keys_server.start_server(true);
+  mon->keys_server.start_server(true);
 
   check_rotate();
 }
@@ -121,7 +121,7 @@ bool AuthMonitor::update_from_paxos()
 {
   dout(0) << "AuthMonitor::update_from_paxos()" << dendl;
   version_t paxosv = paxos->get_version();
-  version_t keys_ver = keys_server.get_ver();
+  version_t keys_ver = mon->keys_server.get_ver();
   if (paxosv == keys_ver) return true;
   assert(paxosv >= keys_ver);
 
@@ -132,7 +132,7 @@ bool AuthMonitor::update_from_paxos()
     if (v) {
       dout(7) << "update_from_paxos startup: loading summary e" << v << dendl;
       bufferlist::iterator p = latest.begin();
-      ::decode(keys_server, p);
+      ::decode(mon->keys_server, p);
     }
   } 
 
@@ -150,18 +150,18 @@ bool AuthMonitor::update_from_paxos()
     switch (inc.op) {
     case AUTH_INC_ADD:
       if (!entry.rotating) {
-        keys_server.add_secret(entry.name, entry.secret);
+        mon->keys_server.add_secret(entry.name, entry.secret);
       } else {
         derr(0) << "got AUTH_INC_ADD with entry.rotating" << dendl;
       }
       break;
     case AUTH_INC_DEL:
-      keys_server.remove_secret(entry.name);
+      mon->keys_server.remove_secret(entry.name);
       break;
     case AUTH_INC_SET_ROTATING:
       {
         dout(0) << "AuthMonitor::update_from_paxos: decode_rotating" << dendl;
-        keys_server.decode_rotating(entry.rotating_bl);
+        mon->keys_server.decode_rotating(entry.rotating_bl);
       }
       break;
     case AUTH_INC_NOP:
@@ -171,11 +171,12 @@ bool AuthMonitor::update_from_paxos()
     }
 
     keys_ver++;
-    keys_server.set_ver(keys_ver);
+    mon->keys_server.set_ver(keys_ver);
   }
 
   bufferlist bl;
-  ::encode(keys_server, bl);
+  Mutex::Locker l(mon->keys_server.get_lock());
+  ::encode(mon->keys_server, bl);
   paxos->stash_latest(paxosv, bl);
 
   return true;
@@ -291,7 +292,7 @@ bool AuthMonitor::preprocess_auth_rotating(MAuthRotating *m)
   if (!reply)
     return true;
 
-  if (keys_server.get_rotating_encrypted(m->entity_name, reply->response_bl)) {
+  if (mon->keys_server.get_rotating_encrypted(m->entity_name, reply->response_bl)) {
     reply->status = 0;
   } else {
     reply->status = -EPERM;
@@ -313,7 +314,7 @@ bool AuthMonitor::preprocess_auth_mon(MAuthMon *m)
   for (deque<AuthLibEntry>::iterator p = m->info.begin();
        p != m->info.end();
        p++) {
-    if (!keys_server.contains((*p).name))
+    if (!mon->keys_server.contains((*p).name))
       num_new++;
   }
   if (!num_new) {
@@ -430,7 +431,7 @@ bool AuthMonitor::prepare_command(MMonCommand *m)
       string name = m->cmd[2];
       AuthLibEntry entry;
       entry.name.from_str(name);
-      if (!keys_server.contains(entry.name)) {
+      if (!mon->keys_server.contains(entry.name)) {
         ss << "couldn't find entry " << name;
         rs = -ENOENT;
         goto done;
@@ -445,7 +446,7 @@ bool AuthMonitor::prepare_command(MMonCommand *m)
       paxos->wait_for_commit(new Monitor::C_Command(mon, m, 0, rs, paxos->get_version()));
       return true;
     } else if (m->cmd[1] == "list") {
-      keys_server.list_secrets(ss);
+      mon->keys_server.list_secrets(ss);
       err = 0;
       goto done;
     } else {
diff --git a/src/mon/AuthMonitor.h b/src/mon/AuthMonitor.h
index f5d9ba6bac3..afd2705f0d0 100644
--- a/src/mon/AuthMonitor.h
+++ b/src/mon/AuthMonitor.h
@@ -38,7 +38,6 @@ class MAuthRotating;
 class AuthMonitor : public PaxosService {
   void auth_usage(stringstream& ss);
   vector<AuthLibIncremental> pending_auth;
-  KeysServer keys_server;
   version_t last_rotating_ver;
 
   AuthServiceManager auth_mgr;
diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h
index 94062f13dcc..31b2b983c3f 100644
--- a/src/mon/Monitor.h
+++ b/src/mon/Monitor.h
@@ -37,6 +37,8 @@
 
 #include "common/LogClient.h"
 
+#include "auth/KeysServer.h"
+
 
 class MonitorStore;
 
@@ -67,6 +69,8 @@ public:
   void reset_tick();
   friend class C_Mon_Tick;
 
+  KeysServer keys_server;
+
   // -- local storage --
 public:
   MonitorStore *store;