]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
auth: move cephx server side into cephx dir
authorSage Weil <sage@newdream.net>
Fri, 23 Oct 2009 18:39:12 +0000 (11:39 -0700)
committerSage Weil <sage@newdream.net>
Fri, 23 Oct 2009 19:01:24 +0000 (12:01 -0700)
src/Makefile.am
src/auth/AuthServiceHandler.cc
src/auth/AuthServiceHandler.h
src/auth/cephx/CephxServiceHandler.cc [new file with mode: 0644]
src/auth/cephx/CephxServiceHandler.h [new file with mode: 0644]
src/mon/AuthMonitor.cc

index fe4ff757482979f268f764d7b98de24a3e77a080..0cafae0584383cceac62c164e0f9d1d2ce295dd4 100644 (file)
@@ -333,6 +333,7 @@ libcrush_a_SOURCES = \
        crush/crush.c
 
 libmon_a_SOURCES = \
+       auth/cephx/CephxServiceHandler.cc \
        auth/AuthServiceHandler.cc \
        mon/Monitor.cc \
        mon/Paxos.cc \
@@ -401,6 +402,7 @@ libclient_a_SOURCES = \
 noinst_HEADERS = \
        auth/cephx/CephxProtocol.h\
        auth/cephx/CephxClientHandler.h\
+       auth/cephx/CephxServiceHandler.h\
        auth/Auth.h\
        auth/AuthServiceHandler.h\
        auth/KeyRing.h\
index 94d10171a697ecaf678b962e1cd1ea5ff3c4f11f..dbfb5897b355879da44d07126ce77b20e2aa316b 100644 (file)
  * 
  */
 
-
 #include "AuthServiceHandler.h"
-#include "cephx/CephxProtocol.h"
-#include "Auth.h"
-
-#include "mon/Monitor.h"
-
-#include <errno.h>
-#include <sstream>
-
-#include "config.h"
-
-/*
-   the first X request is empty, we then send a response and get another request which
-   is not empty and contains the client challenge and the key
-*/
-class CephAuthService_X  : public AuthServiceHandler {
-  int state;
-  uint64_t server_challenge;
-  EntityName entity_name;
-
-public:
-  CephAuthService_X(Monitor *m) : AuthServiceHandler(m), state(0) {}
-  ~CephAuthService_X() {}
-
-  int start_session(bufferlist& result_bl);
-  int handle_request(bufferlist::iterator& indata, bufferlist& result_bl);
-  int handle_cephx_protocol(bufferlist::iterator& indata, bufferlist& result_bl);
-  void build_cephx_response_header(int request_type, int status, bufferlist& bl);
-};
-
-
-int CephAuthService_X::start_session(bufferlist& result_bl)
-{
-  CephXEnvResponse1 response;
-  get_random_bytes((char *)&server_challenge, sizeof(server_challenge));
-  response.server_challenge = server_challenge;
-  ::encode(response, result_bl);
-  state = 1;
-  return CEPH_AUTH_CEPHX;
-}
-
-int CephAuthService_X::handle_request(bufferlist::iterator& indata, bufferlist& result_bl)
-{
-  int ret = 0;
-
-  dout(0) << "CephAuthService_X: handle request" << dendl;
-  dout(0) << "state=" << state << dendl;
-
-  switch (state) {
-  case 0:
-    assert(0);
-    break;
-  case 1:
-    {
-      CephXGetMonKey req;
-      ::decode(req, indata);
-
-      entity_name = req.name;
-
-      CryptoKey secret;
-      dout(0) << "entity_name=" << entity_name.to_str() << dendl;
-      if (!mon->key_server.get_secret(entity_name, secret)) {
-        dout(0) << "couldn't find entity name: " << entity_name.to_str() << dendl;
-       ret = -EPERM;
-       break;
-      }
-
-      bufferlist key, key_enc;
-      ::encode(server_challenge, key);
-      ::encode(req.client_challenge, key);
-      ret = encode_encrypt(key, secret, key_enc);
-      if (ret < 0)
-        break;
-      uint64_t expected_key = 0;
-      const uint64_t *p = (const uint64_t *)key_enc.c_str();
-      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;
-      if (req.key != expected_key) {
-        dout(0) << "unexpected key: req.key=" << req.key << " expected_key=" << expected_key << dendl;
-        ret = -EPERM;
-       break;
-      }
-
-      dout(0) << "CEPHX_GET_AUTH_SESSION_KEY" << dendl;
-      struct CephXRequestHeader cephx_header;
-      ::decode(cephx_header, indata);
-
-      AuthAuthenticateRequest areq;
-      ::decode(areq, indata);
-
-      CryptoKey session_key;
-      SessionAuthInfo info;
-
-      CryptoKey principal_secret;
-      if (mon->key_server.get_secret(areq.name, principal_secret) < 0) {
-       ret = -EPERM;
-       break;
-      }
-
-      info.ticket.name = areq.name;
-      info.ticket.init_timestamps(g_clock.now(), g_conf.auth_mon_ticket_ttl);
-
-      mon->key_server.generate_secret(session_key);
-
-      info.session_key = session_key;
-      info.service_id = CEPH_ENTITY_TYPE_AUTH;
-      if (!mon->key_server.get_service_secret(CEPH_ENTITY_TYPE_AUTH, info.service_secret, info.secret_id)) {
-        dout(0) << "could not get service secret for auth subsystem" << dendl;
-        ret = -EIO;
-        break;
-      }
-
-      vector<SessionAuthInfo> info_vec;
-      info_vec.push_back(info);
-
-      build_cephx_response_header(cephx_header.request_type, 0, result_bl);
-      if (!build_service_ticket_reply(principal_secret, info_vec, result_bl)) {
-        ret = -EIO;
-        break;
-      }
-    }
-    break;
-
-  case 2:
-    {
-      struct CephXRequestHeader cephx_header;
-      ::decode(cephx_header, indata);
-      dout(0) << "CEPHX_GET_PRINCIPAL_SESSION_KEY " << cephx_header.request_type << dendl;
-
-      bufferlist tmp_bl;
-      AuthServiceTicketInfo auth_ticket_info;
-      if (!verify_authorizer(mon->key_server, indata, auth_ticket_info, tmp_bl)) {
-        ret = -EPERM;
-      }
-
-      AuthServiceTicketRequest ticket_req;
-      if (!verify_service_ticket_request(ticket_req, indata)) {
-        ret = -EPERM;
-        break;
-      }
-      dout(0) << " ticket_req.keys = " << ticket_req.keys << dendl;
-
-      ret = 0;
-      vector<SessionAuthInfo> info_vec;
-      for (uint32_t service_id = 1; service_id <= ticket_req.keys; service_id <<= 1) {
-        if (ticket_req.keys & service_id) {
-         dout(0) << " adding key for service " << service_id << dendl;
-          SessionAuthInfo info;
-          int r = mon->key_server.build_session_auth_info(service_id, auth_ticket_info, info);
-          if (r < 0) {
-            ret = r;
-            break;
-          }
-          info_vec.push_back(info);
-        }
-      }
-      build_cephx_response_header(cephx_header.request_type, ret, result_bl);
-      build_service_ticket_reply(auth_ticket_info.session_key, info_vec, result_bl);
-    }
-    break;
-
-  default:
-    return -EINVAL;
-  }
-
-  if (!ret || (ret == -EAGAIN)) {
-    state++;
-  }
-  dout(0) << "returning with state=" << state << dendl;
-  return ret;
-}
-
-void CephAuthService_X::build_cephx_response_header(int request_type, int status, bufferlist& bl)
-{
-  struct CephXResponseHeader header;
-  header.request_type = request_type;
-  header.status = status;
-  ::encode(header, bl);
-}
-
-
-// --------------
+#include "cephx/CephxServiceHandler.h"
 
-AuthServiceHandler *get_auth_handler(Monitor *mon, set<__u32>& supported)
+AuthServiceHandler *get_auth_service_handler(KeyServer *ks, set<__u32>& supported)
 {
   if (supported.count(CEPH_AUTH_CEPHX))
-    return new CephAuthService_X(mon);
+    return new CephxServiceHandler(ks);
   return NULL;
 }
 
index 1430234acae1ff67f693d6e9ec5cebebc0806132..1cc0f3d117ad6435723bdf16cef610031a5cd313 100644 (file)
 #include "include/types.h"
 #include "config.h"
 
-class Monitor;
+class KeyServer;
 
-class AuthServiceHandler {
-protected:
-  Monitor *mon;
-
-public:
-  AuthServiceHandler(Monitor *m) : mon(m) { }
+struct AuthServiceHandler {
   virtual ~AuthServiceHandler() { }
 
   virtual int start_session(bufferlist& result) = 0;
   virtual int handle_request(bufferlist::iterator& indata, bufferlist& result) = 0;
 };
 
-extern AuthServiceHandler *get_auth_handler(Monitor *mon, set<__u32>& supported);
+extern AuthServiceHandler *get_auth_service_handler(KeyServer *ks, set<__u32>& supported);
 
 #endif
diff --git a/src/auth/cephx/CephxServiceHandler.cc b/src/auth/cephx/CephxServiceHandler.cc
new file mode 100644 (file)
index 0000000..474b584
--- /dev/null
@@ -0,0 +1,178 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software 
+ * Foundation.  See file COPYING.
+ * 
+ */
+
+
+#include "CephxServiceHandler.h"
+#include "CephxProtocol.h"
+
+#include "../Auth.h"
+
+#include "mon/Monitor.h"
+
+#include <errno.h>
+#include <sstream>
+
+#include "config.h"
+
+
+int CephxServiceHandler::start_session(bufferlist& result_bl)
+{
+  CephXEnvResponse1 response;
+  get_random_bytes((char *)&server_challenge, sizeof(server_challenge));
+  response.server_challenge = server_challenge;
+  ::encode(response, result_bl);
+  state = 1;
+  return CEPH_AUTH_CEPHX;
+}
+
+int CephxServiceHandler::handle_request(bufferlist::iterator& indata, bufferlist& result_bl)
+{
+  int ret = 0;
+
+  dout(0) << "CephxServiceHandler: handle request" << dendl;
+  dout(0) << "state=" << state << dendl;
+
+  switch (state) {
+  case 0:
+    assert(0);
+    break;
+  case 1:
+    {
+      CephXGetMonKey req;
+      ::decode(req, indata);
+
+      entity_name = req.name;
+
+      CryptoKey secret;
+      dout(0) << "entity_name=" << entity_name.to_str() << dendl;
+      if (!key_server->get_secret(entity_name, secret)) {
+        dout(0) << "couldn't find entity name: " << entity_name.to_str() << dendl;
+       ret = -EPERM;
+       break;
+      }
+
+      bufferlist key, key_enc;
+      ::encode(server_challenge, key);
+      ::encode(req.client_challenge, key);
+      ret = encode_encrypt(key, secret, key_enc);
+      if (ret < 0)
+        break;
+      uint64_t expected_key = 0;
+      const uint64_t *p = (const uint64_t *)key_enc.c_str();
+      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;
+      if (req.key != expected_key) {
+        dout(0) << "unexpected key: req.key=" << req.key << " expected_key=" << expected_key << dendl;
+        ret = -EPERM;
+       break;
+      }
+
+      dout(0) << "CEPHX_GET_AUTH_SESSION_KEY" << dendl;
+      struct CephXRequestHeader cephx_header;
+      ::decode(cephx_header, indata);
+
+      AuthAuthenticateRequest areq;
+      ::decode(areq, indata);
+
+      CryptoKey session_key;
+      SessionAuthInfo info;
+
+      CryptoKey principal_secret;
+      if (key_server->get_secret(areq.name, principal_secret) < 0) {
+       ret = -EPERM;
+       break;
+      }
+
+      info.ticket.name = areq.name;
+      info.ticket.init_timestamps(g_clock.now(), g_conf.auth_mon_ticket_ttl);
+
+      key_server->generate_secret(session_key);
+
+      info.session_key = session_key;
+      info.service_id = CEPH_ENTITY_TYPE_AUTH;
+      if (!key_server->get_service_secret(CEPH_ENTITY_TYPE_AUTH, info.service_secret, info.secret_id)) {
+        dout(0) << "could not get service secret for auth subsystem" << dendl;
+        ret = -EIO;
+        break;
+      }
+
+      vector<SessionAuthInfo> info_vec;
+      info_vec.push_back(info);
+
+      build_cephx_response_header(cephx_header.request_type, 0, result_bl);
+      if (!build_service_ticket_reply(principal_secret, info_vec, result_bl)) {
+        ret = -EIO;
+        break;
+      }
+    }
+    break;
+
+  case 2:
+    {
+      struct CephXRequestHeader cephx_header;
+      ::decode(cephx_header, indata);
+      dout(0) << "CEPHX_GET_PRINCIPAL_SESSION_KEY " << cephx_header.request_type << dendl;
+
+      bufferlist tmp_bl;
+      AuthServiceTicketInfo auth_ticket_info;
+      if (!verify_authorizer(*key_server, indata, auth_ticket_info, tmp_bl)) {
+        ret = -EPERM;
+      }
+
+      AuthServiceTicketRequest ticket_req;
+      if (!verify_service_ticket_request(ticket_req, indata)) {
+        ret = -EPERM;
+        break;
+      }
+      dout(0) << " ticket_req.keys = " << ticket_req.keys << dendl;
+
+      ret = 0;
+      vector<SessionAuthInfo> info_vec;
+      for (uint32_t service_id = 1; service_id <= ticket_req.keys; service_id <<= 1) {
+        if (ticket_req.keys & service_id) {
+         dout(0) << " adding key for service " << service_id << dendl;
+          SessionAuthInfo info;
+          int r = key_server->build_session_auth_info(service_id, auth_ticket_info, info);
+          if (r < 0) {
+            ret = r;
+            break;
+          }
+          info_vec.push_back(info);
+        }
+      }
+      build_cephx_response_header(cephx_header.request_type, ret, result_bl);
+      build_service_ticket_reply(auth_ticket_info.session_key, info_vec, result_bl);
+    }
+    break;
+
+  default:
+    return -EINVAL;
+  }
+
+  if (!ret || (ret == -EAGAIN)) {
+    state++;
+  }
+  dout(0) << "returning with state=" << state << dendl;
+  return ret;
+}
+
+void CephxServiceHandler::build_cephx_response_header(int request_type, int status, bufferlist& bl)
+{
+  struct CephXResponseHeader header;
+  header.request_type = request_type;
+  header.status = status;
+  ::encode(header, bl);
+}
diff --git a/src/auth/cephx/CephxServiceHandler.h b/src/auth/cephx/CephxServiceHandler.h
new file mode 100644 (file)
index 0000000..839d02a
--- /dev/null
@@ -0,0 +1,39 @@
+// -*- mode:C++; tab-width:8; c-basic-offset:2; indent-tabs-mode:t -*- 
+// vim: ts=8 sw=2 smarttab
+/*
+ * Ceph - scalable distributed file system
+ *
+ * Copyright (C) 2004-2009 Sage Weil <sage@newdream.net>
+ *
+ * This is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software 
+ * Foundation.  See file COPYING.
+ * 
+ */
+
+#ifndef __CEPHXSERVICEMANAGER_H
+#define __CEPHXSERVICEMANAGER_H
+
+#include "../AuthServiceHandler.h"
+#include "../Auth.h"
+
+class KeyServer;
+
+class CephxServiceHandler  : public AuthServiceHandler {
+  KeyServer *key_server;
+  int state;
+  uint64_t server_challenge;
+  EntityName entity_name;
+
+public:
+  CephxServiceHandler(KeyServer *ks) : key_server(ks), state(0) {}
+  ~CephxServiceHandler() {}
+  
+  int start_session(bufferlist& result_bl);
+  int handle_request(bufferlist::iterator& indata, bufferlist& result_bl);
+  int handle_cephx_protocol(bufferlist::iterator& indata, bufferlist& result_bl);
+  void build_cephx_response_header(int request_type, int status, bufferlist& bl);
+};
+
+#endif
index 7473976a0167389b307fc87787e504761c86fa8b..d6666005fdaab818d72d561a852816c9e647a34f 100644 (file)
@@ -280,7 +280,7 @@ bool AuthMonitor::preprocess_auth(MAuth *m)
       }
       
       if (!ret) {
-       s->auth_handler = get_auth_handler(mon, supported);
+       s->auth_handler = get_auth_service_handler(&mon->key_server, supported);
        if (!s->auth_handler)
          ret = -EPERM;
        else {