mon: put auth_handler in mon Session

This commit is contained in:
Sage Weil 2009-09-23 14:51:46 -07:00
parent 3312f34703
commit bc691a9aab
7 changed files with 76 additions and 95 deletions

View File

@ -99,6 +99,8 @@ public:
static CephAuthServer auth_server;
/*
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
@ -107,12 +109,15 @@ class CephAuthService_X : public AuthServiceHandler {
int state;
uint64_t server_challenge;
public:
CephAuthService_X() : state(0) {}
CephAuthService_X(Monitor *m) : AuthServiceHandler(m), state(0) {}
~CephAuthService_X() {}
int handle_request(bufferlist& bl, 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::handle_request(bufferlist& bl, bufferlist& result_bl)
{
int ret = 0;
@ -297,56 +302,15 @@ void CephAuthService_X::build_cephx_response_header(int request_type, int status
::encode(header, bl);
}
AuthServiceHandler::~AuthServiceHandler()
// --------------
AuthServiceHandler *AuthServiceManager::get_auth_handler(set<__u32>& supported)
{
if (instance)
delete instance;
}
AuthServiceHandler *AuthServiceHandler::get_instance() {
if (instance)
return instance;
return this;
}
int AuthServiceHandler::handle_request(bufferlist& bl, bufferlist& result)
{
bufferlist::iterator iter = bl.begin();
CephAuthService_X *auth = NULL;
CephXEnvRequest1 req;
try {
CephXPremable pre;
::decode(pre, iter);
dout(0) << "CephXPremable id=" << pre.trans_id << dendl;
::encode(pre, result);
::decode(req, iter);
} catch (buffer::error *e) {
dout(0) << "failed to decode message auth message" << dendl;
delete e;
return -EINVAL;
if (supported.count(CEPH_AUTH_CEPH)) {
return new CephAuthService_X(mon);
}
if (req.supports(CEPH_AUTH_CEPH)) {
auth = new CephAuthService_X();
if (!auth)
return -ENOMEM;
instance = auth;
}
if (auth)
return auth->handle_request(bl, result);
return -EINVAL;
}
AuthServiceHandler *AuthServiceManager::get_auth_handler(entity_addr_t& addr)
{
AuthServiceHandler& handler = m[addr];
return handler.get_instance();
return NULL;
}

View File

@ -15,40 +15,29 @@
#ifndef __AUTHSERVICEMANAGER_H
#define __AUTHSERVICEMANAGER_H
#include <map>
#include <set>
using namespace std;
#include "include/types.h"
#include "config.h"
class Monitor;
class AuthServiceHandler {
Monitor *mon;
AuthServiceHandler *instance;
protected:
bufferlist response_payload;
public:
AuthServiceHandler() : instance(NULL) {}
void init(Monitor *m) { mon = m; }
virtual ~AuthServiceHandler();
virtual int handle_request(bufferlist& bl, bufferlist& result);
AuthServiceHandler *get_instance();
bufferlist& get_response_payload();
AuthServiceHandler(Monitor *m) : mon(m) { }
virtual ~AuthServiceHandler() { }
virtual int handle_request(bufferlist& bl, bufferlist& result) = 0;
};
class AuthServiceManager
{
/* FIXME: map locking */
map<entity_addr_t, AuthServiceHandler> m;
Monitor *mon;
public:
AuthServiceHandler *get_auth_handler(entity_addr_t& addr);
void init(Monitor *m) { mon = m; }
AuthServiceManager(Monitor *m) : mon(m) {}
AuthServiceHandler *get_auth_handler(set<__u32>& supported);
};
#endif

View File

@ -17,9 +17,9 @@
#include "messages/PaxosServiceMessage.h"
class MAuth : public PaxosServiceMessage {
struct MAuth : public PaxosServiceMessage {
bufferlist auth_payload;
public:
MAuth() : PaxosServiceMessage(CEPH_MSG_AUTH, 0) { }
const char *get_type_name() { return "client_auth"; }
@ -27,11 +27,11 @@ public:
void decode_payload() {
bufferlist::iterator p = payload.begin();
paxos_decode(p);
p.copy(payload.length() - p.get_off(), auth_payload);
::decode(auth_payload, p);
}
void encode_payload() {
paxos_encode();
payload.append(auth_payload);
::encode(auth_payload, payload);
}
bufferlist& get_auth_payload() { return auth_payload; }
};

View File

@ -243,19 +243,39 @@ void AuthMonitor::committed()
bool AuthMonitor::preprocess_auth(MAuth *m)
{
dout(0) << "preprocess_auth() blob_size=" << m->get_auth_payload().length() << dendl;
int ret = 0;
entity_addr_t addr = m->get_orig_source_addr();
dout(0) << "preprocess_auth() addr=" << addr << dendl;
AuthServiceHandler *handler = auth_mgr.get_auth_handler(addr);
assert(handler);
Session *s = (Session *)m->get_connection()->get_priv();
s->put();
// set up handler?
if (!s->auth_handler) {
set<__u32> supported;
bufferlist::iterator p = m->auth_payload.begin();
try {
::decode(supported, p);
} catch (buffer::error *e) {
dout(0) << "failed to decode message auth message" << dendl;
ret = -EINVAL;
}
if (!ret) {
s->auth_handler = auth_mgr.get_auth_handler(supported);
if (!s->auth_handler)
ret = -EPERM;
}
}
bufferlist response_bl;
int ret;
try {
ret = handler->handle_request(m->get_auth_payload(), response_bl);
} catch (buffer::error *err) {
ret = -EINVAL;
dout(0) << "caught error when trying to handle auth request, probably malformed request" << dendl;
if (s->auth_handler && !ret) {
// handle the request
try {
ret = s->auth_handler->handle_request(m->get_auth_payload(), response_bl);
} catch (buffer::error *err) {
ret = -EINVAL;
dout(0) << "caught error when trying to handle auth request, probably malformed request" << dendl;
}
}
MAuthReply *reply = new MAuthReply(&response_bl, ret);
mon->messenger->send_message(reply, m->get_orig_source_inst());

View File

@ -79,9 +79,8 @@ class AuthMonitor : public PaxosService {
void check_rotate();
public:
AuthMonitor(Monitor *mn, Paxos *p) : PaxosService(mn, p), last_rotating_ver(0) {
auth_mgr.init(mn);
}
AuthMonitor(Monitor *mn, Paxos *p) : PaxosService(mn, p), last_rotating_ver(0),
auth_mgr(mn) {}
void pre_auth(MAuth *m);
void tick(); // check state, take actions

View File

@ -360,7 +360,18 @@ void Monitor::stop_cluster()
bool Monitor::ms_dispatch(Message *m)
{
bool ret = true;
lock.Lock();
Session *s = (Session *)m->get_connection()->get_priv();
if (!s) {
s = session_map.new_session(m->get_source_inst());
m->get_connection()->set_priv(s->get());
dout(10) << "ms_dispatch new session " << s << " for " << s->inst << dendl;
} else {
dout(20) << "ms_dispatch existing session " << s << " for " << s->inst << dendl;
}
{
switch (m->get_type()) {
@ -470,12 +481,13 @@ bool Monitor::ms_dispatch(Message *m)
break;
default:
return false;
ret = false;
}
}
s->put();
lock.Unlock();
return true;
return ret;
}
void Monitor::handle_subscribe(MMonSubscribe *m)
@ -485,13 +497,6 @@ void Monitor::handle_subscribe(MMonSubscribe *m)
bool reply = false;
Session *s = (Session *)m->get_connection()->get_priv();
if (!s) {
s = session_map.new_session(m->get_source_inst());
m->get_connection()->set_priv(s->get());
dout(10) << " new session " << s << " for " << s->inst << dendl;
} else {
dout(10) << " existing session " << s << " for " << s->inst << dendl;
}
s->until = g_clock.now();
s->until += g_conf.mon_subscribe_interval;

View File

@ -18,6 +18,7 @@
#include "include/xlist.h"
#include "msg/msg_types.h"
#include "auth/Crypto.h"
#include "auth/AuthServiceManager.h"
struct Session;
@ -41,13 +42,16 @@ struct Session : public RefCountedObject {
map<nstring, Subscription*> sub_map;
CryptoKey session_key;
AuthServiceHandler *auth_handler;
Session(entity_inst_t i) : inst(i), closed(false), item(this) {}
Session(entity_inst_t i) : inst(i), closed(false), item(this),
auth_handler(NULL) {}
~Session() {
generic_dout(0) << "~Session " << this << dendl;
// we should have been removed before we get destructed; see SessionMap::remove_session()
assert(!item.is_on_xlist());
assert(sub_map.empty());
delete auth_handler;
}
};