# 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 \
--- /dev/null
+// -*- 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();
+}
+
+
--- /dev/null
+// -*- 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
#include "ceph_debug.h"
#include "ceph_ver.h"
#include "auth.h"
+#include "decode.h"
#include "super.h"
{
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;
}
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;
}
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]);
}
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)
#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 {
};
ClientMap client_map;
-
+ AuthManager auth_mgr;
private:
// leader
ClientMap::Incremental pending_inc;
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