mirror of
https://github.com/ceph/ceph
synced 2025-01-20 10:01:45 +00:00
mon: put auth_handler in mon Session
This commit is contained in:
parent
3312f34703
commit
bc691a9aab
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
@ -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
|
||||
|
@ -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; }
|
||||
};
|
||||
|
@ -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());
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
}
|
||||
};
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user