From 8a11a563abe2cd3ceed2d239551f5f68735921d1 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Fri, 2 Oct 2009 14:31:04 -0700 Subject: [PATCH] auth: separate authenticate and authorize messages and handling --- src/Makefile.am | 3 + src/auth/Auth.cc | 2 +- src/auth/Auth.h | 7 +- src/auth/AuthClientHandler.cc | 35 +++++++-- src/auth/AuthClientHandler.h | 10 ++- src/auth/AuthServiceManager.cc | 5 +- src/auth/AuthorizeServer.cc | 128 +++++++++++++++++++++++++++++++++ src/auth/AuthorizeServer.h | 51 +++++++++++++ src/auth/KeyRing.cc | 18 +++++ src/auth/KeyRing.h | 4 +- src/auth/KeysServer.h | 2 +- src/include/ceph_fs.h | 3 +- src/librados.cc | 2 +- src/messages/MAuthorize.h | 37 ++++++++++ src/mon/MonClient.h | 1 + src/mon/Monitor.cc | 4 ++ src/mon/Monitor.h | 6 ++ src/msg/Message.cc | 4 ++ 18 files changed, 306 insertions(+), 16 deletions(-) create mode 100644 src/auth/AuthorizeServer.cc create mode 100644 src/auth/AuthorizeServer.h create mode 100644 src/messages/MAuthorize.h diff --git a/src/Makefile.am b/src/Makefile.am index 95b091af72e38..bc2b3876d388a 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -290,6 +290,7 @@ libcommon_a_SOURCES = \ libcommon_files = \ auth/Auth.cc \ auth/AuthClientHandler.cc \ + auth/AuthorizeServer.cc \ auth/AuthServiceManager.cc \ auth/Crypto.cc \ auth/ExportControl.cc \ @@ -390,6 +391,7 @@ libclient_a_SOURCES = \ # that autotools doesn't magically identify. noinst_HEADERS = \ auth/Auth.h\ + auth/AuthorizeServer.h\ auth/AuthProtocol.h\ auth/AuthServiceManager.h\ auth/KeyRing.h\ @@ -574,6 +576,7 @@ noinst_HEADERS = \ mds/mdstypes.h\ mds/snap.h\ messages/MAuth.h\ + messages/MAuthorize.h\ messages/MAuthReply.h\ messages/MAuthRotating.h\ messages/MClass.h\ diff --git a/src/auth/Auth.cc b/src/auth/Auth.cc index 00b9ea60aadfa..a7bd30678c2ff 100644 --- a/src/auth/Auth.cc +++ b/src/auth/Auth.cc @@ -189,7 +189,7 @@ bool AuthTicketsManager::build_authorizer(uint32_t service_id, bufferlist& bl, A * * {timestamp + 1}^session_key */ -bool verify_authorizer(uint32_t service_id, KeysServer& keys, bufferlist::iterator& indata, +bool verify_authorizer(uint32_t service_id, KeysKeeper& keys, bufferlist::iterator& indata, AuthServiceTicketInfo& ticket_info, bufferlist& reply_bl) { uint64_t secret_id; diff --git a/src/auth/Auth.h b/src/auth/Auth.h index 01396a4ea5467..bba59aa4d9e6e 100644 --- a/src/auth/Auth.h +++ b/src/auth/Auth.h @@ -284,6 +284,11 @@ struct RotatingSecrets { }; WRITE_CLASS_ENCODER(RotatingSecrets); +class KeysKeeper { +public: + virtual bool get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret) = 0; +}; + template int decode_decrypt(T& t, CryptoKey key, bufferlist::iterator& iter) { uint64_t magic; @@ -334,7 +339,7 @@ extern bool verify_service_ticket_request(AuthServiceTicketRequest& ticket_req, class KeysServer; -extern bool verify_authorizer(uint32_t service_id, KeysServer& keys, bufferlist::iterator& indata, +extern bool verify_authorizer(uint32_t service_id, KeysKeeper& keys, bufferlist::iterator& indata, AuthServiceTicketInfo& ticket_info, bufferlist& reply_bl); #endif diff --git a/src/auth/AuthClientHandler.cc b/src/auth/AuthClientHandler.cc index f055b301d7547..0b3911c8d8019 100644 --- a/src/auth/AuthClientHandler.cc +++ b/src/auth/AuthClientHandler.cc @@ -20,6 +20,7 @@ #include "KeyRing.h" #include "messages/MAuth.h" +#include "messages/MAuthorize.h" #include "messages/MAuthReply.h" @@ -38,11 +39,11 @@ AuthClientProtocolHandler::~AuthClientProtocolHandler() int AuthClientProtocolHandler::build_request() { - msg = new MAuth; + msg = _get_new_msg(); if (!msg) return -ENOMEM; + bufferlist& bl = _get_msg_bl(msg); - bufferlist& bl = msg->get_auth_payload(); CephXPremable pre; dout(0) << "pre=" << id << dendl; pre.trans_id = id; @@ -308,13 +309,38 @@ bool AuthClientAuthenticateHandler::request_pending() { int AuthClientAuthenticateHandler::_build_request() { - bufferlist& bl = msg->get_auth_payload(); + MAuth *m = (MAuth *)msg; + bufferlist& bl = m->get_auth_payload(); int ret = generate_authenticate_request(bl); return ret; } +Message *AuthClientAuthenticateHandler::_get_new_msg() +{ + MAuth *m = new MAuth; + + return m; +} + +bufferlist& AuthClientAuthenticateHandler::_get_msg_bl(Message *m) +{ + return ((MAuth *)m)->get_auth_payload(); +} + +Message *AuthClientAuthorizeHandler::_get_new_msg() +{ + MAuthorize *m = new MAuthorize; + + return m; +} + +bufferlist& AuthClientAuthorizeHandler::_get_msg_bl(Message *m) +{ + return ((MAuthorize *)m)->get_auth_payload(); +} + int AuthClientAuthorizeHandler::_build_request() { CephXRequestHeader header; @@ -325,7 +351,8 @@ int AuthClientAuthorizeHandler::_build_request() header.request_type = CEPHX_OPEN_SESSION; - bufferlist& bl = msg->get_auth_payload(); + MAuthorize *m = (MAuthorize *)msg; + bufferlist& bl = m->get_auth_payload(); ::encode(header, bl); utime_t now; diff --git a/src/auth/AuthClientHandler.h b/src/auth/AuthClientHandler.h index 4d771264c176b..3429d38c9eea2 100644 --- a/src/auth/AuthClientHandler.h +++ b/src/auth/AuthClientHandler.h @@ -24,8 +24,6 @@ #include "common/Timer.h" -class MAuth; -class MAuthReply; class Message; class AuthClient; @@ -47,7 +45,7 @@ class AuthClientProtocolHandler { protected: AuthClientHandler *client; - MAuth *msg; + Message *msg; bool got_response; bool got_timeout; Context *timeout_event; @@ -69,6 +67,8 @@ protected: virtual int _handle_response(int ret, bufferlist::iterator& iter) = 0; virtual int _build_request() = 0; + virtual Message *_get_new_msg() = 0; + virtual bufferlist& _get_msg_bl(Message *m) = 0; void _request_timeout(double timeout); public: @@ -113,6 +113,8 @@ protected: int _build_request(); int _handle_response(int ret, bufferlist::iterator& iter); + Message *_get_new_msg(); + bufferlist& _get_msg_bl(Message *m); public: AuthClientAuthenticateHandler(AuthClientHandler *client, uint32_t _want, uint32_t _have) : AuthClientProtocolHandler(client), want(_want), have(_have) { reset(); } @@ -126,6 +128,8 @@ class AuthClientAuthorizeHandler : public AuthClientProtocolHandler { protected: int _build_request(); int _handle_response(int ret, bufferlist::iterator& iter); + Message *_get_new_msg(); + bufferlist& _get_msg_bl(Message *m); public: AuthClientAuthorizeHandler(AuthClientHandler *client, uint32_t sid) : AuthClientProtocolHandler(client), service_id(sid) {} }; diff --git a/src/auth/AuthServiceManager.cc b/src/auth/AuthServiceManager.cc index ea19764ccc7af..061b070046d50 100644 --- a/src/auth/AuthServiceManager.cc +++ b/src/auth/AuthServiceManager.cc @@ -214,7 +214,7 @@ int CephAuthService_X::handle_cephx_protocol(bufferlist::iterator& indata, buffe ret = 0; } break; - +#if 0 case CEPHX_OPEN_SESSION: { dout(0) << "CEPHX_OPEN_SESSION " << cephx_header.request_type << dendl; @@ -228,10 +228,9 @@ int CephAuthService_X::handle_cephx_protocol(bufferlist::iterator& indata, buffe } build_cephx_response_header(request_type, ret, result_bl); result_bl.claim_append(tmp_bl); - break; } break; - +#endif default: ret = -EINVAL; build_cephx_response_header(request_type, -EINVAL, result_bl); diff --git a/src/auth/AuthorizeServer.cc b/src/auth/AuthorizeServer.cc new file mode 100644 index 0000000000000..8914722b924ef --- /dev/null +++ b/src/auth/AuthorizeServer.cc @@ -0,0 +1,128 @@ +// -*- 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 + * + * 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 + +using namespace std; + +#include "config.h" + +#include "AuthorizeServer.h" +#include "Auth.h" +#include "msg/SimpleMessenger.h" +#include "messages/MAuthorize.h" +#include "messages/MAuthReply.h" +#include "mon/Session.h" + +AuthorizeServer::~AuthorizeServer() +{ +} + +bool AuthorizeServer::init() +{ + messenger->add_dispatcher_tail(this); + return true; +} + +bool AuthorizeServer::ms_dispatch(Message *m) +{ + lock.Lock(); + bool ret = _dispatch(m); + lock.Unlock(); + return ret; +} + +bool AuthorizeServer::_dispatch(Message *m) +{ + switch (m->get_type()) { + case CEPH_MSG_AUTHORIZE: + handle_request((class MAuthorize*)m); + break; + default: + return false; + } + return true; +} + +void AuthorizeServer::handle_request(MAuthorize *m) +{ + dout(0) << "AuthorizeServer::handle_request() blob_size=" << m->get_auth_payload().length() << dendl; + int ret = 0; + + Session *s = (Session *)m->get_connection()->get_priv(); + s->put(); + + bufferlist response_bl; + bufferlist::iterator indata = m->auth_payload.begin(); + + CephXPremable pre; + ::decode(pre, indata); + dout(0) << "CephXPremable id=" << pre.trans_id << dendl; + ::encode(pre, response_bl); + + // handle the request + try { + ret = do_authorize(indata, response_bl); + } catch (buffer::error *err) { + ret = -EINVAL; + dout(0) << "caught error when trying to handle authorize request, probably malformed request" << dendl; + } + MAuthReply *reply = new MAuthReply(&response_bl, ret); + messenger->send_message(reply, m->get_orig_source_inst()); +} + +int AuthorizeServer::do_authorize(bufferlist::iterator& indata, bufferlist& result_bl) +{ + struct CephXRequestHeader cephx_header; + + ::decode(cephx_header, indata); + + uint16_t request_type = cephx_header.request_type & CEPHX_REQUEST_TYPE_MASK; + int ret; + + dout(0) << "request_type=" << request_type << dendl; + + switch (request_type) { + case CEPHX_OPEN_SESSION: + { + dout(0) << "CEPHX_OPEN_SESSION " << cephx_header.request_type << dendl; + + ret = 0; + bufferlist tmp_bl; + AuthServiceTicketInfo auth_ticket_info; + if (!verify_authorizer(CEPHX_PRINCIPAL_MON, *keys, indata, auth_ticket_info, tmp_bl)) { + dout(0) << "could not verify authorizer" << dendl; + ret = -EPERM; + } + result_bl.claim_append(tmp_bl); + } + break; + default: + ret = -EINVAL; + break; + } + build_cephx_response_header(request_type, ret, result_bl); + + return ret; +} + +void AuthorizeServer::build_cephx_response_header(int request_type, int status, bufferlist& bl) +{ + struct CephXResponseHeader header; + header.request_type = request_type; + header.status = status; + ::encode(header, bl); +} + + diff --git a/src/auth/AuthorizeServer.h b/src/auth/AuthorizeServer.h new file mode 100644 index 0000000000000..dbe74a14547ca --- /dev/null +++ b/src/auth/AuthorizeServer.h @@ -0,0 +1,51 @@ +// -*- 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 + * + * 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 __AUTHORIZESERVER_H +#define __AUTHORIZESERVER_H + +#include "config.h" + +#include "msg/SimpleMessenger.h" + +class Messenger; +class KeysKeeper; +class Message; +class MAuthorize; + +class AuthorizeServer : public Dispatcher { + Messenger *messenger; + + bool _dispatch(Message *m); + bool ms_dispatch(Message *m); + + bool ms_handle_reset(Connection *con, const entity_addr_t& peer) { return false; } + void ms_handle_failure(Connection *con, Message *m, const entity_addr_t& peer) { } + void ms_handle_remote_reset(Connection *con, const entity_addr_t& peer) {} + + KeysKeeper *keys; + + Mutex lock; + + int do_authorize(bufferlist::iterator& indata, bufferlist& result_bl); + void build_cephx_response_header(int request_type, int status, bufferlist& bl); +public: + AuthorizeServer(Messenger *m, KeysKeeper *k) : messenger(m), keys(k), lock("auth_server") {} + ~AuthorizeServer(); + + bool init(); + void handle_request(MAuthorize *m); +}; + +#endif diff --git a/src/auth/KeyRing.cc b/src/auth/KeyRing.cc index 6a590da09408f..9ae32db12219a 100644 --- a/src/auth/KeyRing.cc +++ b/src/auth/KeyRing.cc @@ -123,3 +123,21 @@ bool KeyRing::need_rotating_secrets() return false; } + +bool KeyRing::get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret) +{ + Mutex::Locker l(lock); + /* we ignore the service id, there's only one service id that we're handling */ + + map::iterator iter = rotating_secrets.secrets.find(secret_id); + if (iter == rotating_secrets.secrets.end()) + return false; + + ExpiringCryptoKey& key = iter->second; + if (key.expiration < g_clock.now()) { + secret = key.key; + return true; + } + return false; +} + diff --git a/src/auth/KeyRing.h b/src/auth/KeyRing.h index 171e6e8411c2d..826f45c1c1051 100644 --- a/src/auth/KeyRing.h +++ b/src/auth/KeyRing.h @@ -25,7 +25,7 @@ key of that service */ -class KeyRing { +class KeyRing : public KeysKeeper { CryptoKey master; RotatingSecrets rotating_secrets; Mutex lock; @@ -38,6 +38,8 @@ public: void get_master(CryptoKey& dest); bool need_rotating_secrets(); + + bool get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret); }; extern KeyRing g_keyring; diff --git a/src/auth/KeysServer.h b/src/auth/KeysServer.h index ce8d1ba2ac4a9..62e9d47bc366d 100644 --- a/src/auth/KeysServer.h +++ b/src/auth/KeysServer.h @@ -80,7 +80,7 @@ struct KeysServerData { }; WRITE_CLASS_ENCODER(KeysServerData); -class KeysServer { +class KeysServer : public KeysKeeper { class C_RotateTimeout : public Context { protected: KeysServer *server; diff --git a/src/include/ceph_fs.h b/src/include/ceph_fs.h index f2a74c8ff6216..622ca12aaaa9f 100644 --- a/src/include/ceph_fs.h +++ b/src/include/ceph_fs.h @@ -286,7 +286,8 @@ struct ceph_secret { #define CEPH_MSG_MON_SUBSCRIBE 15 #define CEPH_MSG_MON_SUBSCRIBE_ACK 16 #define CEPH_MSG_AUTH 17 -#define CEPH_MSG_AUTH_REPLY 18 +#define CEPH_MSG_AUTHORIZE 18 +#define CEPH_MSG_AUTH_REPLY 19 /* client <-> mds */ #define CEPH_MSG_MDS_GETMAP 20 diff --git a/src/librados.cc b/src/librados.cc index e66a036d74dfe..2a8f13bc1cbb6 100644 --- a/src/librados.cc +++ b/src/librados.cc @@ -3,7 +3,7 @@ /* * Ceph - scalable distributed file system * - * Copyright (C) 2004-2006 Sage Weil + * Copyright (C) 2004-2009 Sage Weil * * This is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public diff --git a/src/messages/MAuthorize.h b/src/messages/MAuthorize.h new file mode 100644 index 0000000000000..68628fd643487 --- /dev/null +++ b/src/messages/MAuthorize.h @@ -0,0 +1,37 @@ +// -*- 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 + * + * 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 __MAUTHORIZE_H +#define __MAUTHORIZE_H + +#include "msg/Message.h" + +struct MAuthorize : public Message { + bufferlist auth_payload; + + MAuthorize() : Message(CEPH_MSG_AUTHORIZE) { } + + const char *get_type_name() { return "authorize"; } + + void decode_payload() { + bufferlist::iterator p = payload.begin(); + ::decode(auth_payload, p); + } + void encode_payload() { + ::encode(auth_payload, payload); + } + bufferlist& get_auth_payload() { return auth_payload; } +}; + +#endif diff --git a/src/mon/MonClient.h b/src/mon/MonClient.h index 107b95fe99070..01e7d409c9899 100644 --- a/src/mon/MonClient.h +++ b/src/mon/MonClient.h @@ -31,6 +31,7 @@ class MonMap; class MMonMap; class MClientMountAck; class MMonSubscribeAck; +class MAuthReply; class MAuthRotating; diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index dde0a8aeafc7b..9f8abd190e58d 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -53,6 +53,8 @@ #include "osd/OSDMap.h" +#include "auth/AuthorizeServer.h" + #include "config.h" #define DOUT_SUBSYS mon @@ -78,6 +80,7 @@ Monitor::Monitor(int w, MonitorStore *s, Messenger *m, MonMap *map) : monmap(map), logclient(messenger, monmap), timer(lock), tick_timer(0), + authorizer(m, &keys_server), store(s), state(STATE_STARTING), stopping(false), @@ -129,6 +132,7 @@ void Monitor::init() // i'm ready! messenger->add_dispatcher_tail(this); messenger->add_dispatcher_head(&logclient); + authorizer.init(); // start ticker reset_tick(); diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h index 31b2b983c3fcb..c3019df12ff1f 100644 --- a/src/mon/Monitor.h +++ b/src/mon/Monitor.h @@ -38,6 +38,7 @@ #include "common/LogClient.h" #include "auth/KeysServer.h" +#include "auth/AuthorizeServer.h" class MonitorStore; @@ -51,6 +52,8 @@ class MClass; class MAuthRotating; class MRoute; +class AuthorizeServer; + class Monitor : public Dispatcher { public: // me @@ -71,6 +74,9 @@ public: KeysServer keys_server; + AuthorizeServer authorizer; + + // -- local storage -- public: MonitorStore *store; diff --git a/src/msg/Message.cc b/src/msg/Message.cc index f1e17a2228f00..e06ee3f500099 100644 --- a/src/msg/Message.cc +++ b/src/msg/Message.cc @@ -66,6 +66,7 @@ using namespace std; #include "messages/MMonGetMap.h" #include "messages/MAuth.h" +#include "messages/MAuthorize.h" #include "messages/MAuthReply.h" #include "messages/MClientMount.h" #include "messages/MClientMountAck.h" @@ -327,6 +328,9 @@ Message *decode_message(ceph_msg_header& header, ceph_msg_footer& footer, case CEPH_MSG_AUTH: m = new MAuth; break; + case CEPH_MSG_AUTHORIZE: + m = new MAuthorize; + break; case CEPH_MSG_AUTH_REPLY: m = new MAuthReply; break; -- 2.39.5