From dfc1b1115b32fc31877b97462c02970485517079 Mon Sep 17 00:00:00 2001 From: Sage Weil Date: Thu, 4 Feb 2010 13:48:23 -0800 Subject: [PATCH] auth: fix KeyStore interface --- src/auth/Auth.h | 3 +- src/auth/AuthAuthorizeHandler.h | 2 +- src/auth/KeyRing.h | 2 +- src/auth/RotatingKeyRing.cc | 15 +++++++++- src/auth/RotatingKeyRing.h | 16 +++++++--- src/auth/cephx/CephxAuthorizeHandler.cc | 4 +-- src/auth/cephx/CephxAuthorizeHandler.h | 2 +- src/auth/cephx/CephxClientHandler.cc | 2 +- src/auth/cephx/CephxProtocol.cc | 36 ++++++++++++----------- src/auth/cephx/CephxProtocol.h | 4 +-- src/auth/cephx/CephxServiceHandler.cc | 6 ++-- src/auth/none/AuthNoneAuthorizeHandler.cc | 2 +- src/auth/none/AuthNoneAuthorizeHandler.h | 2 +- src/cmds.cc | 4 ++- src/cosd.cc | 2 +- src/mds/MDS.cc | 2 +- src/mon/MonClient.cc | 15 +++++----- src/mon/Monitor.cc | 2 +- src/osd/OSD.cc | 3 +- 19 files changed, 75 insertions(+), 49 deletions(-) diff --git a/src/auth/Auth.h b/src/auth/Auth.h index d005e5261680d..aab388d5ea741 100644 --- a/src/auth/Auth.h +++ b/src/auth/Auth.h @@ -278,7 +278,7 @@ class KeyStore { public: virtual ~KeyStore() {} virtual bool get_secret(EntityName& name, CryptoKey& secret) = 0; - //virtual bool get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret) = 0; + virtual bool get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret) = 0; }; static inline bool auth_principal_needs_rotating_keys(EntityName& name) @@ -287,5 +287,4 @@ static inline bool auth_principal_needs_rotating_keys(EntityName& name) (name.entity_type == CEPH_ENTITY_TYPE_MDS)); } - #endif diff --git a/src/auth/AuthAuthorizeHandler.h b/src/auth/AuthAuthorizeHandler.h index f7479c984d881..70ab3fd627d79 100644 --- a/src/auth/AuthAuthorizeHandler.h +++ b/src/auth/AuthAuthorizeHandler.h @@ -24,7 +24,7 @@ class RotatingKeyRing; struct AuthAuthorizeHandler { virtual ~AuthAuthorizeHandler() {} - virtual bool verify_authorizer(KeyRing *keys, RotatingKeyRing *rkeys, + virtual bool verify_authorizer(KeyStore *keys, bufferlist& authorizer_data, bufferlist& authorizer_reply, EntityName& entity_name, uint64_t& global_id, AuthCapsInfo& caps_info) = 0; }; diff --git a/src/auth/KeyRing.h b/src/auth/KeyRing.h index 533328c9d4d34..186c8489671b2 100644 --- a/src/auth/KeyRing.h +++ b/src/auth/KeyRing.h @@ -20,7 +20,7 @@ #include "auth/Crypto.h" #include "auth/Auth.h" -class KeyRing : public KeyStore { +class KeyRing { map keys; public: diff --git a/src/auth/RotatingKeyRing.cc b/src/auth/RotatingKeyRing.cc index 394ae5f990b90..010819ac0c134 100644 --- a/src/auth/RotatingKeyRing.cc +++ b/src/auth/RotatingKeyRing.cc @@ -6,6 +6,7 @@ #include "Crypto.h" #include "auth/RotatingKeyRing.h" +#include "auth/KeyRing.h" #define DOUT_SUBSYS auth #undef dout_prefix @@ -33,9 +34,21 @@ void RotatingKeyRing::dump_rotating() dout(0) << " id " << iter->first << " " << iter->second << dendl; } -bool RotatingKeyRing::get_service_secret(uint64_t secret_id, CryptoKey& secret) +bool RotatingKeyRing::get_secret(EntityName& name, CryptoKey& secret) { Mutex::Locker l(lock); + return keyring->get_secret(name, secret); +} + +bool RotatingKeyRing::get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret) +{ + Mutex::Locker l(lock); + + if (service_id != this->service_id) { + dout(0) << "do not have service " << ceph_entity_type_name(service_id) + << ", i am " << ceph_entity_type_name(this->service_id) << dendl; + return false; + } map::iterator iter = secrets.secrets.find(secret_id); if (iter == secrets.secrets.end()) { diff --git a/src/auth/RotatingKeyRing.h b/src/auth/RotatingKeyRing.h index f0482acbdc0a2..04cc2f82ea205 100644 --- a/src/auth/RotatingKeyRing.h +++ b/src/auth/RotatingKeyRing.h @@ -21,20 +21,28 @@ #include "auth/Auth.h" /* - * mediate access to a service's rotating secrets + * mediate access to a service's keyring and rotating secrets */ -class RotatingKeyRing { +class KeyRing; + +class RotatingKeyRing : public KeyStore { + uint32_t service_id; RotatingSecrets secrets; + KeyRing *keyring; Mutex lock; public: - RotatingKeyRing() : lock("RotatingKeyRing::lock") {} + RotatingKeyRing(uint32_t s, KeyRing *kr) : + service_id(s), + keyring(kr), + lock("RotatingKeyRing::lock") {} bool need_new_secrets(); void set_secrets(RotatingSecrets& s); void dump_rotating(); - bool get_service_secret(uint64_t secret_id, CryptoKey& secret); + bool get_secret(EntityName& name, CryptoKey& secret); + bool get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret); }; #endif diff --git a/src/auth/cephx/CephxAuthorizeHandler.cc b/src/auth/cephx/CephxAuthorizeHandler.cc index 385173168db9b..98b5138e3752f 100644 --- a/src/auth/cephx/CephxAuthorizeHandler.cc +++ b/src/auth/cephx/CephxAuthorizeHandler.cc @@ -5,7 +5,7 @@ #include "CephxAuthorizeHandler.h" -bool CephxAuthorizeHandler::verify_authorizer(KeyRing *keys, RotatingKeyRing *rkeys, +bool CephxAuthorizeHandler::verify_authorizer(KeyStore *keys, bufferlist& authorizer_data, bufferlist& authorizer_reply, EntityName& entity_name, uint64_t& global_id, AuthCapsInfo& caps_info) { @@ -18,7 +18,7 @@ bool CephxAuthorizeHandler::verify_authorizer(KeyRing *keys, RotatingKeyRing *rk CephXServiceTicketInfo auth_ticket_info; - bool isvalid = cephx_verify_authorizer(keys, rkeys, iter, auth_ticket_info, authorizer_reply); + bool isvalid = cephx_verify_authorizer(keys, iter, auth_ticket_info, authorizer_reply); dout(0) << "CephxAuthorizeHandler::verify_authorizer isvalid=" << isvalid << dendl; if (isvalid) { diff --git a/src/auth/cephx/CephxAuthorizeHandler.h b/src/auth/cephx/CephxAuthorizeHandler.h index 84672312ab24c..131f2a9001749 100644 --- a/src/auth/cephx/CephxAuthorizeHandler.h +++ b/src/auth/cephx/CephxAuthorizeHandler.h @@ -18,7 +18,7 @@ #include "../AuthAuthorizeHandler.h" struct CephxAuthorizeHandler : public AuthAuthorizeHandler { - bool verify_authorizer(KeyRing *keys, RotatingKeyRing *rkeys, + bool verify_authorizer(KeyStore *keys, bufferlist& authorizer_data, bufferlist& authorizer_reply, EntityName& entity_name, uint64_t& global_id, AuthCapsInfo& caps_info); }; diff --git a/src/auth/cephx/CephxClientHandler.cc b/src/auth/cephx/CephxClientHandler.cc index 72f3e4e5a684a..7d97d38c203c2 100644 --- a/src/auth/cephx/CephxClientHandler.cc +++ b/src/auth/cephx/CephxClientHandler.cc @@ -167,7 +167,7 @@ int CephxClientHandler::handle_response(int ret, bufferlist::iterator& indata) AuthAuthorizer *CephxClientHandler::build_authorizer(uint32_t service_id) { - dout(10) << "build_authorizer for service " << service_id << dendl; + dout(10) << "build_authorizer for service " << ceph_entity_type_name(service_id) << dendl; return tickets.build_authorizer(service_id); } diff --git a/src/auth/cephx/CephxProtocol.cc b/src/auth/cephx/CephxProtocol.cc index 4671f07f670b8..eb5e644ab48eb 100644 --- a/src/auth/cephx/CephxProtocol.cc +++ b/src/auth/cephx/CephxProtocol.cc @@ -197,11 +197,12 @@ void CephXTicketManager::set_have_need_key(uint32_t service_id, uint32_t& have, if (iter == tickets_map.end()) { have &= ~service_id; need |= service_id; - dout(10) << "couldn't find entry for service_id " << service_id << dendl; + dout(10) << "couldn't find entry for service_id " << ceph_entity_type_name(service_id) << dendl; return; } - dout(10) << "service_id=" << service_id << " need=" << iter->second.need_key() << " have=" << iter->second.have_key() << dendl; + dout(10) << "set_have_need_key service " << ceph_entity_type_name(service_id) << " (" << service_id << ")" + << " need=" << iter->second.need_key() << " have=" << iter->second.have_key() << dendl; if (iter->second.need_key()) need |= service_id; else @@ -230,7 +231,7 @@ bool CephXTicketManager::verify_service_ticket_reply(CryptoKey& secret, for (int i=0; i<(int)num; i++) { uint32_t type; ::decode(type, indata); - dout(10) << "got key for service_id=" << type << dendl; + dout(10) << "got key for service_id " << ceph_entity_type_name(type) << dendl; CephXTicketHandler& handler = tickets_map[type]; handler.service_id = type; if (!handler.verify_service_ticket_reply(secret, indata)) { @@ -284,7 +285,7 @@ CephXAuthorizer *CephXTicketManager::build_authorizer(uint32_t service_id) { map::iterator iter = tickets_map.find(service_id); if (iter == tickets_map.end()) { - dout(0) << "no TicketHandler for service " << service_id << dendl; + dout(0) << "no TicketHandler for service " << ceph_entity_type_name(service_id) << dendl; return NULL; } @@ -301,9 +302,10 @@ void CephXTicketManager::validate_tickets(uint32_t mask, uint32_t& have, uint32_ set_have_need_key(i, have, need); } } + dout(10) << "validate_tickets want " << mask << " have " << have << " need " << need << dendl; } -bool cephx_decode_ticket(KeyStore *keys, RotatingKeyRing *rkeys, uint32_t service_id, CephXTicketBlob& ticket_blob, CephXServiceTicketInfo& ticket_info) +bool cephx_decode_ticket(KeyStore *keys, uint32_t service_id, CephXTicketBlob& ticket_blob, CephXServiceTicketInfo& ticket_info) { uint64_t secret_id = ticket_blob.secret_id; CryptoKey service_secret; @@ -312,16 +314,16 @@ bool cephx_decode_ticket(KeyStore *keys, RotatingKeyRing *rkeys, uint32_t servic return false; } - if (secret_id == (uint64_t)-1 || rkeys == NULL) { + if (secret_id == (uint64_t)-1) { if (!keys->get_secret(*g_conf.entity_name, service_secret)) { dout(0) << "ceph_decode_ticket could not get general service secret for service_id=" - << service_id << " secret_id=" << secret_id << dendl; + << ceph_entity_type_name(service_id) << " secret_id=" << secret_id << dendl; return false; } } else { - if (!rkeys->get_service_secret(secret_id, service_secret)) { + if (!keys->get_service_secret(service_id, secret_id, service_secret)) { dout(0) << "ceph_decode_ticket could not get service secret for service_id=" - << service_id << " secret_id=" << secret_id << dendl; + << ceph_entity_type_name(service_id) << " secret_id=" << secret_id << dendl; return false; } } @@ -339,7 +341,7 @@ bool cephx_decode_ticket(KeyStore *keys, RotatingKeyRing *rkeys, uint32_t servic * * {timestamp + 1}^session_key */ -bool cephx_verify_authorizer(KeyStore *keys, RotatingKeyRing *rkeys, +bool cephx_verify_authorizer(KeyStore *keys, bufferlist::iterator& indata, CephXServiceTicketInfo& ticket_info, bufferlist& reply_bl) { @@ -356,21 +358,21 @@ bool cephx_verify_authorizer(KeyStore *keys, RotatingKeyRing *rkeys, // ticket blob CephXTicketBlob ticket; ::decode(ticket, indata); - dout(10) << "verify_authorizer decrypted service_id=" << service_id + dout(10) << "verify_authorizer decrypted service " << ceph_entity_type_name(service_id) << " secret_id=" << ticket.secret_id << dendl; - if (ticket.secret_id == (uint64_t)-1 || rkeys == NULL) { + if (ticket.secret_id == (uint64_t)-1) { EntityName name; name.entity_type = service_id; if (!keys->get_secret(name, service_secret)) { - dout(0) << "verify_authorizer could not get general service secret for service_id=" << service_id - << " secret_id=" << ticket.secret_id << dendl; + dout(0) << "verify_authorizer could not get general service secret for service " + << ceph_entity_type_name(service_id) << " secret_id=" << ticket.secret_id << dendl; return false; } } else { - if (!rkeys->get_service_secret(ticket.secret_id, service_secret)) { - dout(0) << "verify_authorizer could not get service secret for service_id=" << service_id - << " secret_id=" << ticket.secret_id << dendl; + if (!keys->get_service_secret(service_id, ticket.secret_id, service_secret)) { + dout(0) << "verify_authorizer could not get service secret for service " + << ceph_entity_type_name(service_id) << " secret_id=" << ticket.secret_id << dendl; return false; } } diff --git a/src/auth/cephx/CephxProtocol.h b/src/auth/cephx/CephxProtocol.h index 6498cba5c9d9a..0ead914e52c2b 100644 --- a/src/auth/cephx/CephxProtocol.h +++ b/src/auth/cephx/CephxProtocol.h @@ -372,13 +372,13 @@ WRITE_CLASS_ENCODER(CephXAuthorize); /* * Decode an extract ticket */ -bool cephx_decode_ticket(KeyStore *keys, RotatingKeyRing *rkeys, +bool cephx_decode_ticket(KeyStore *keys, uint32_t service_id, CephXTicketBlob& ticket_blob, CephXServiceTicketInfo& ticket_info); /* * Verify authorizer and generate reply authorizer */ -extern bool cephx_verify_authorizer(KeyStore *keys, RotatingKeyRing *rkeys, +extern bool cephx_verify_authorizer(KeyStore *keys, bufferlist::iterator& indata, CephXServiceTicketInfo& ticket_info, bufferlist& reply_bl); diff --git a/src/auth/cephx/CephxServiceHandler.cc b/src/auth/cephx/CephxServiceHandler.cc index 0ed890f380755..cdd0a956d096a 100644 --- a/src/auth/cephx/CephxServiceHandler.cc +++ b/src/auth/cephx/CephxServiceHandler.cc @@ -93,7 +93,7 @@ int CephxServiceHandler::handle_request(bufferlist::iterator& indata, bufferlist } CephXServiceTicketInfo old_ticket_info; - if (cephx_decode_ticket(key_server, NULL, CEPH_ENTITY_TYPE_AUTH, req.old_ticket, old_ticket_info)) { + if (cephx_decode_ticket(key_server, CEPH_ENTITY_TYPE_AUTH, req.old_ticket, old_ticket_info)) { global_id = old_ticket_info.ticket.global_id; dout(10) << "decoded old_ticket with global_id=" << global_id << dendl; should_enc_ticket = true; @@ -135,7 +135,7 @@ int CephxServiceHandler::handle_request(bufferlist::iterator& indata, bufferlist bufferlist tmp_bl; CephXServiceTicketInfo auth_ticket_info; - if (!cephx_verify_authorizer(key_server, NULL, indata, auth_ticket_info, tmp_bl)) { + if (!cephx_verify_authorizer(key_server, indata, auth_ticket_info, tmp_bl)) { ret = -EPERM; break; } @@ -148,7 +148,7 @@ int CephxServiceHandler::handle_request(bufferlist::iterator& indata, bufferlist vector info_vec; for (uint32_t service_id = 1; service_id <= ticket_req.keys; service_id <<= 1) { if (ticket_req.keys & service_id) { - dout(10) << " adding key for service " << service_id << dendl; + dout(10) << " adding key for service " << ceph_entity_type_name(service_id) << dendl; CephXSessionAuthInfo info; int r = key_server->build_session_auth_info(service_id, auth_ticket_info, info); if (r < 0) { diff --git a/src/auth/none/AuthNoneAuthorizeHandler.cc b/src/auth/none/AuthNoneAuthorizeHandler.cc index a11986fbfbba0..580965a4fe16e 100644 --- a/src/auth/none/AuthNoneAuthorizeHandler.cc +++ b/src/auth/none/AuthNoneAuthorizeHandler.cc @@ -3,7 +3,7 @@ #include "AuthNoneAuthorizeHandler.h" -bool AuthNoneAuthorizeHandler::verify_authorizer(KeyRing *keys, RotatingKeyRing *rkeys, +bool AuthNoneAuthorizeHandler::verify_authorizer(KeyStore *keys, bufferlist& authorizer_data, bufferlist& authorizer_reply, EntityName& entity_name, uint64_t& global_id, AuthCapsInfo& caps_info) { diff --git a/src/auth/none/AuthNoneAuthorizeHandler.h b/src/auth/none/AuthNoneAuthorizeHandler.h index 81ddc6c211bb7..6e4dc307658ec 100644 --- a/src/auth/none/AuthNoneAuthorizeHandler.h +++ b/src/auth/none/AuthNoneAuthorizeHandler.h @@ -18,7 +18,7 @@ #include "../AuthAuthorizeHandler.h" struct AuthNoneAuthorizeHandler : public AuthAuthorizeHandler { - bool verify_authorizer(KeyRing *keys, RotatingKeyRing *rkeys, + bool verify_authorizer(KeyStore *keys, bufferlist& authorizer_data, bufferlist& authorizer_reply, EntityName& entity_name, uint64_t& global_id, AuthCapsInfo& caps_info); }; diff --git a/src/cmds.cc b/src/cmds.cc index da2e814e00770..e58d3e1c8b779 100644 --- a/src/cmds.cc +++ b/src/cmds.cc @@ -33,6 +33,8 @@ using namespace std; #include "mon/MonClient.h" +#include "auth/KeyRing.h" + void usage() { cerr << "usage: cmds -i name [flags] [--mds rank] [--shadow rank]\n"; @@ -63,7 +65,7 @@ int main(int argc, const char **argv) if (g_conf.clock_tare) g_clock.tare(); // get monmap - RotatingKeyRing rkeys; + RotatingKeyRing rkeys(CEPH_ENTITY_TYPE_MDS, &g_keyring); MonClient mc(&rkeys); if (mc.build_initial_monmap() < 0) return -1; diff --git a/src/cosd.cc b/src/cosd.cc index ed22f54a4e47b..d04e538712164 100644 --- a/src/cosd.cc +++ b/src/cosd.cc @@ -92,7 +92,7 @@ int main(int argc, const char **argv) _dout_create_courtesy_output_symlink("osd", whoami); // get monmap - RotatingKeyRing rkeys; + RotatingKeyRing rkeys(CEPH_ENTITY_TYPE_OSD, &g_keyring); MonClient mc(&rkeys); if (mc.build_initial_monmap() < 0) return -1; diff --git a/src/mds/MDS.cc b/src/mds/MDS.cc index 3d5dfb912d8da..878b58b652610 100644 --- a/src/mds/MDS.cc +++ b/src/mds/MDS.cc @@ -1550,7 +1550,7 @@ bool MDS::ms_verify_authorizer(Connection *con, int peer_type, EntityName name; uint64_t global_id; - is_valid = authorize_handler->verify_authorizer(&g_keyring, monc->rotating_secrets, + is_valid = authorize_handler->verify_authorizer(monc->rotating_secrets, authorizer_data, authorizer_reply, name, global_id, caps_info); if (is_valid) { diff --git a/src/mon/MonClient.cc b/src/mon/MonClient.cc index 7390683b79246..63995d354f8d0 100644 --- a/src/mon/MonClient.cc +++ b/src/mon/MonClient.cc @@ -276,7 +276,7 @@ int MonClient::authenticate(double timeout) authenticate_cond.Wait(monc_lock); if (state == MC_STATE_HAVE_SESSION) { - dout(5) << "authenticate success, global_id" << global_id << dendl; + dout(5) << "authenticate success, global_id " << global_id << dendl; } return authenticate_err; @@ -506,14 +506,15 @@ int MonClient::_check_auth_rotating() _send_mon_message(m); } - if (!rotating_secrets) - return 0; - - if (!rotating_secrets->need_new_secrets()) + if (!rotating_secrets || + !auth_principal_needs_rotating_keys(entity_name)) { + dout(20) << "_check_auth_rotating not needed by " << entity_name << dendl; return 0; + } - if (!auth_principal_needs_rotating_keys(entity_name)) { - dout(20) << "_check_auth_rotating not needed by " << entity_name << dendl; + if (!rotating_secrets->need_new_secrets()) { + dout(20) << "_check_auth_rotating have uptodate secrets" << dendl; + rotating_secrets->dump_rotating(); return 0; } diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index 60793845f1b52..7d62d4b87384b 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -1034,7 +1034,7 @@ bool Monitor::ms_verify_authorizer(Connection *con, int peer_type, if (!authorizer_data.length()) return true; /* we're not picky */ - int ret = cephx_verify_authorizer(&key_server, NULL, iter, auth_ticket_info, authorizer_reply); + int ret = cephx_verify_authorizer(&key_server, iter, auth_ticket_info, authorizer_reply); dout(0) << "Monitor::verify_authorizer returns " << ret << dendl; isvalid = (ret >= 0); diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index c6453edc6240a..2da4ec9f00b61 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -445,6 +445,7 @@ int OSD::init() heartbeat_messenger->add_dispatcher_head(&heartbeat_dispatcher); + monc->set_want_keys(CEPH_ENTITY_TYPE_MON | CEPH_ENTITY_TYPE_OSD); monc->init(); monc->sub_want("monmap", 0); @@ -1597,7 +1598,7 @@ bool OSD::ms_verify_authorizer(Connection *con, int peer_type, EntityName name; uint64_t global_id; - isvalid = authorize_handler->verify_authorizer(&g_keyring, monc->rotating_secrets, + isvalid = authorize_handler->verify_authorizer(monc->rotating_secrets, authorizer_data, authorizer_reply, name, global_id, caps_info); dout(10) << "OSD::ms_verify_authorizer name=" << name << dendl; -- 2.39.5