diff --git a/src/auth/AuthServiceManager.cc b/src/auth/AuthServiceManager.cc index 4da0a7ae4f5..d5800610396 100644 --- a/src/auth/AuthServiceManager.cc +++ b/src/auth/AuthServiceManager.cc @@ -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; } diff --git a/src/auth/AuthServiceManager.h b/src/auth/AuthServiceManager.h index 617fa64dbcb..c5b1b230734 100644 --- a/src/auth/AuthServiceManager.h +++ b/src/auth/AuthServiceManager.h @@ -15,40 +15,29 @@ #ifndef __AUTHSERVICEMANAGER_H #define __AUTHSERVICEMANAGER_H -#include -#include -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 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 diff --git a/src/messages/MAuth.h b/src/messages/MAuth.h index 1f6fbbd1a86..ea56e06e74a 100644 --- a/src/messages/MAuth.h +++ b/src/messages/MAuth.h @@ -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; } }; diff --git a/src/mon/AuthMonitor.cc b/src/mon/AuthMonitor.cc index d66f2204d3b..06ef3cd0e33 100644 --- a/src/mon/AuthMonitor.cc +++ b/src/mon/AuthMonitor.cc @@ -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()); diff --git a/src/mon/AuthMonitor.h b/src/mon/AuthMonitor.h index 4d15e5073b4..f5d9ba6bac3 100644 --- a/src/mon/AuthMonitor.h +++ b/src/mon/AuthMonitor.h @@ -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 diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 0f7c0ec0640..e7d1f950946 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -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; diff --git a/src/mon/Session.h b/src/mon/Session.h index 932483bfe1e..d03364f84ed 100644 --- a/src/mon/Session.h +++ b/src/mon/Session.h @@ -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 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; } };