]> git.apps.os.sepia.ceph.com Git - ceph.git/commitdiff
auth: auth stub implementation
authorYehuda Sadeh <yehuda@hq.newdream.net>
Tue, 18 Aug 2009 00:05:04 +0000 (17:05 -0700)
committerYehuda Sadeh <yehuda@hq.newdream.net>
Wed, 19 Aug 2009 17:30:29 +0000 (10:30 -0700)
src/Makefile.am
src/auth/AuthManager.cc [new file with mode: 0644]
src/auth/AuthManager.h [new file with mode: 0644]
src/kernel/auth.c
src/kernel/super.c
src/mon/ClientMonitor.cc
src/mon/ClientMonitor.h

index 572ccf53bfa17242ca2091a5cd7061e58c326681..f479abaf17b85a6585d8f384d13f730ad2218d88 100644 (file)
@@ -268,6 +268,7 @@ libcommon_a_SOURCES = \
 # this list ommits the ceph_ver.c file
 libcommon_files = \
        auth/ExportControl.cc \
+       auth/AuthManager.cc \
        common/LogClient.cc \
        msg/Message.cc \
        common/Logger.cc \
diff --git a/src/auth/AuthManager.cc b/src/auth/AuthManager.cc
new file mode 100644 (file)
index 0000000..6d47d58
--- /dev/null
@@ -0,0 +1,143 @@
+// -*- 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-2006 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 "AuthManager.h"
+
+#include <errno.h>
+#include <sstream>
+
+#include "config.h"
+
+struct CephXResponse {
+  uint64_t server_challenge;
+
+  void encode(bufferlist& bl) const {
+    ::encode(server_challenge, bl);
+  }
+  void decode(bufferlist::iterator& bl) {
+    ::decode(server_challenge, bl);
+  }
+};
+WRITE_CLASS_ENCODER(CephXResponse);
+
+class CephAuth_X  : public AuthHandler {
+  int state;
+public:
+  CephAuth_X() : state(0) {}
+  int handle_request(bufferlist& bl, bufferlist& result_bl);
+};
+
+int CephAuth_X::handle_request(bufferlist& bl, bufferlist& result_bl)
+{
+  switch(state) {
+  case 0:
+    {
+      CephXResponse response;
+      response.server_challenge = 0x1234ffff;
+      ::encode(response, result_bl);
+    }
+    break;
+  case 1:
+    break;
+  default:
+    return -EINVAL;
+  }
+  state++;
+  return 0;
+}
+
+
+struct AuthInitReq {
+  map<uint32_t, bool> auth_types;
+
+  void encode(bufferlist& bl) const {
+    uint32_t num_auth = auth_types.size();
+    ::encode(num_auth, bl);
+
+    map<uint32_t, bool>::const_iterator iter = auth_types.begin();
+
+    for (iter = auth_types.begin(); iter != auth_types.end(); ++iter) {
+       uint32_t auth_type = iter->first;
+       ::encode(auth_type, bl);
+    }
+  }
+  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;
+    }
+  }
+
+  bool supports(uint32_t auth_type) {
+    return (auth_types.find(auth_type) != auth_types.end());
+  }
+};
+
+WRITE_CLASS_ENCODER(AuthInitReq)
+
+
+AuthHandler::~AuthHandler()
+{
+  if (instance)
+    delete instance;
+}
+
+AuthHandler *AuthHandler::get_instance() {
+  if (instance)
+    return instance;
+  return this;
+}
+
+int AuthHandler::handle_request(bufferlist& bl, bufferlist& result)
+{
+  bufferlist::iterator iter = bl.begin();
+  AuthInitReq req;
+  try {
+    req.decode(iter);
+  } catch (buffer::error *e) {
+    dout(0) << "failed to decode message auth message" << dendl;
+    delete e;
+    return -EINVAL;
+  }
+
+  if (req.supports(CEPH_AUTH_CEPH)) {
+    CephAuth_X *auth = new CephAuth_X();
+    if (!auth)
+      return -ENOMEM;
+    instance = auth;
+    return -EAGAIN;
+  }
+
+  return -EINVAL;
+}
+
+
+AuthHandler *AuthManager::get_auth_handler(entity_addr_t& addr)
+{
+  AuthHandler& handler = m[addr];
+
+  return handler.get_instance();
+}
+
+
diff --git a/src/auth/AuthManager.h b/src/auth/AuthManager.h
new file mode 100644 (file)
index 0000000..4b911cd
--- /dev/null
@@ -0,0 +1,54 @@
+// -*- 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 __AUTHMANAGER_H
+#define __AUTHMANAGER_H
+
+#include <map>
+#include <set>
+using namespace std;
+
+#include "include/types.h"
+
+#include "config.h"
+
+class Monitor;
+
+
+class AuthHandler {
+  Monitor *mon;
+  AuthHandler *instance;
+protected:
+  bufferlist response_payload;
+public:
+  AuthHandler() : instance(NULL) {}
+  void init(Monitor *m) { mon = m; }
+  virtual ~AuthHandler();
+  virtual int handle_request(bufferlist& bl, bufferlist& result);
+  AuthHandler *get_instance();
+  bufferlist& get_response_payload();
+};
+
+class AuthManager
+{
+  /* FIXME: map locking */
+  map<entity_addr_t, AuthHandler> m;
+  Monitor *mon;
+
+public:
+  AuthHandler *get_auth_handler(entity_addr_t& addr);
+  void init(Monitor *m) { mon = m; }
+};
+
+#endif
index 28b7fcb32728a70ba46c738a0d366b5039fc438f..57c14478007d5b7867fb863747a29623cc7efd20 100644 (file)
@@ -4,6 +4,7 @@
 #include "ceph_debug.h"
 #include "ceph_ver.h"
 #include "auth.h"
+#include "decode.h"
 #include "super.h"
 
 
@@ -48,27 +49,39 @@ static int ceph_x_auth_handle_response(struct ceph_client *client,
 {
        struct ceph_x_auth *auth_data = (struct ceph_x_auth *)data->private_data;
        const struct ceph_x_response *response;
+       u32 blob_len;
+
+       printk(KERN_ERR "ceph_x_auth_handle_response len=%d\n", len);
        if (err) {
                return err;
        }
 
+       if (len < sizeof(u32))
+               return -EINVAL;
+
+       ceph_decode_32_safe(&blob, blob + len, blob_len, bad);
+
        switch (auth_data->state) {
        case 0:
-               if (len != sizeof(struct ceph_x_response))
+               printk(KERN_ERR "blob_len=%d sizeof=%ld\n", blob_len, sizeof(struct ceph_x_response));
+               if (blob_len != sizeof(struct ceph_x_response))
                        return -EINVAL;
 
                response = (const struct ceph_x_response *)blob;
                auth_data->state++;
                auth_data->server_challenge = le64_to_cpu(response->server_challenge);
+               printk(KERN_ERR "server_challenge=%llx\b", auth_data->server_challenge);
                break;
        case 1:
-               if (len == 0)
+               if (blob_len == 0)
                        break;
        default:
                return -EINVAL;
        }
 
-       return 0;       
+       return 0;
+bad:
+       return err;
 }
                                        
 
index de78322fa45f40580f41aec8a7dd6139cf8ef94c..f7a5a929a062ad9d6a9ea7a7bfbec048fa407a1d 100644 (file)
@@ -357,6 +357,7 @@ static int handle_auth_reply(struct ceph_client *client, struct ceph_msg *msg)
                client->aops = ceph_x_auth_get_ops();
 
                err = client->aops->init(&client->auth_data);
+               pr_err("ceph_auth err=%d\n", err);
                if (err < 0)
                        goto out;
        }
@@ -932,6 +933,8 @@ static int build_sess_init_req(struct ceph_client *client,
                return -ENOMEM;
        }
 
+       req->num_auth = max_auth_types;
+
        for (i = 0; i < max_auth_types; i++) {
                req->auth_type[i].type = cpu_to_le32(ceph_supported_auth[i]);
        }
index 543033e99c4dd42d8e5c0368ad04ce9b19eb0386..96bd8c50fe7b4a5b5758a8eb618db22251a9855f 100644 (file)
@@ -159,13 +159,26 @@ bool ClientMonitor::check_mount(MClientMount *m)
 
 bool ClientMonitor::check_auth(MClientAuth *m)
 {
-    stringstream ss;
-    // already mounted?
-    dout(0) << "ClientMonitor::check_auth() blob_size=" << m->get_blob_len() << dendl;
-    entity_addr_t addr = m->get_orig_source_addr();
-    mon->messenger->send_message(new MClientAuthReply(0),
-                                  m->get_orig_source_inst());
-    return true;
+  stringstream ss;
+  // already mounted?
+  dout(0) << "ClientMonitor::check_auth() blob_size=" << m->get_auth_payload().length() << dendl;
+  entity_addr_t addr = m->get_orig_source_addr();
+
+  AuthHandler* handler = auth_mgr.get_auth_handler(addr);
+  assert(handler);
+
+  bufferlist response_bl;
+
+  int ret = handler->handle_request(m->get_auth_payload(), response_bl);
+  MClientAuthReply *reply = new MClientAuthReply(&response_bl, ret);
+
+  if (reply) {
+    mon->messenger->send_message(reply,
+                                  m->get_orig_source_inst());
+  } else {
+    /* out of memory.. what are we supposed to do now? */
+  }
+  return true;
 }
 
 bool ClientMonitor::preprocess_query(PaxosServiceMessage *m)
index 45b3eb4f227bf7fa1475132e546181160efaf5ca..e1810115cd3d3a42a27fe3e4ce490e91ab81bf3a 100644 (file)
@@ -31,12 +31,15 @@ using namespace std;
 #include "PaxosService.h"
 #include "ClientMap.h"
 
+#include "auth/AuthManager.h"
+
 class Monitor;
 class Paxos;
 class MClientAuth;
 class MClientMount;
 class MClientUnmount;
 class MMonCommand;
+class ClientAuthManager;
 
 
 class ClientMonitor : public PaxosService {
@@ -72,7 +75,7 @@ public:
   };
 
   ClientMap client_map;
-
+  AuthManager auth_mgr;
 private:
   // leader
   ClientMap::Incremental pending_inc;
@@ -96,7 +99,7 @@ private:
   bool prepare_command(MMonCommand *m);
 
  public:
-  ClientMonitor(Monitor *mn, Paxos *p) : PaxosService(mn, p) { }
+  ClientMonitor(Monitor *mn, Paxos *p) : PaxosService(mn, p) { auth_mgr.init(mn); }
   
   void tick();  // check state, take actions