From bf4cf7d670e06278df4975678bc5e509ffb3dcc5 Mon Sep 17 00:00:00 2001 From: Yehuda Sadeh Date: Mon, 21 Sep 2009 15:59:15 -0700 Subject: [PATCH] auth: entity can request rotating keys (in progress) --- src/Makefile.am | 1 + src/auth/Auth.h | 32 +++++++++++++++++++++++ src/auth/KeysServer.cc | 19 ++++++++++++++ src/auth/KeysServer.h | 37 +++------------------------ src/messages/MAuthRotating.h | 46 +++++++++++++++++++++++++++++++++ src/mon/AuthMonitor.cc | 21 ++++++++++++++++ src/mon/AuthMonitor.h | 2 ++ src/mon/MonClient.cc | 49 ++++++++++++++++++++++++++++++++++++ src/mon/MonClient.h | 28 +++++++++++++++++++++ src/mon/Monitor.cc | 12 +++++++++ src/mon/Monitor.h | 2 ++ src/msg/Message.cc | 5 ++++ src/msg/Message.h | 1 + src/osd/OSD.cc | 13 ++++++++++ src/vstart.sh | 2 ++ 15 files changed, 236 insertions(+), 34 deletions(-) create mode 100644 src/messages/MAuthRotating.h diff --git a/src/Makefile.am b/src/Makefile.am index 3f07de4f9a3f3..e958e22cc861d 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -570,6 +570,7 @@ noinst_HEADERS = \ mds/snap.h\ messages/MAuth.h\ messages/MAuthReply.h\ + messages/MAuthRotating.h\ messages/MClass.h\ messages/MClassAck.h\ messages/MClientCaps.h\ diff --git a/src/auth/Auth.h b/src/auth/Auth.h index c1253fabae42d..ad4fbeca5b23a 100644 --- a/src/auth/Auth.h +++ b/src/auth/Auth.h @@ -323,6 +323,38 @@ struct AuthAuthorize { }; WRITE_CLASS_ENCODER(AuthAuthorize); +struct ExpiringCryptoKey { + CryptoKey key; + utime_t expiration; + + void encode(bufferlist& bl) const { + ::encode(key, bl); + ::encode(expiration, bl); + } + void decode(bufferlist::iterator& bl) { + ::decode(key, bl); + ::decode(expiration, bl); + } +}; +WRITE_CLASS_ENCODER(ExpiringCryptoKey); + +struct RotatingSecrets { + map secrets; + version_t max_ver; + + void encode(bufferlist& bl) const { + ::encode(secrets, bl); + ::encode(max_ver, bl); + } + void decode(bufferlist::iterator& bl) { + ::decode(secrets, bl); + ::decode(max_ver, bl); + } + + void add(ExpiringCryptoKey& key); +}; +WRITE_CLASS_ENCODER(RotatingSecrets); + template int decode_decrypt(T& t, CryptoKey key, bufferlist::iterator& iter) { bufferlist bl_enc, bl; diff --git a/src/auth/KeysServer.cc b/src/auth/KeysServer.cc index 9de7b78b8c042..51892c2b11d98 100644 --- a/src/auth/KeysServer.cc +++ b/src/auth/KeysServer.cc @@ -221,3 +221,22 @@ void KeysServer::decode_rotating(bufferlist& rotating_bl) ::decode(data.rotating_secrets, iter); } +bool KeysServer::get_rotating_encrypted(EntityName& name, bufferlist& enc_bl) +{ + Mutex::Locker l(lock); + + map::iterator mapiter = data.find_name(name); + if (mapiter == data.secrets_end()) + return false; + + CryptoKey& specific_key = mapiter->second; + + map::iterator rotate_iter = data.rotating_secrets.find(name.entity_type); + if (rotate_iter == data.rotating_secrets.end()) + return false; + + RotatingSecrets secrets = rotate_iter->second; + + encode_encrypt(secrets, specific_key, enc_bl); +} + diff --git a/src/auth/KeysServer.h b/src/auth/KeysServer.h index ae2f9b38a69b1..e100d2b96dab9 100644 --- a/src/auth/KeysServer.h +++ b/src/auth/KeysServer.h @@ -24,40 +24,6 @@ #define KEY_ROTATE_TIME 5 #define KEY_ROTATE_NUM 3 -struct ExpiringCryptoKey { - CryptoKey key; - utime_t expiration; - - void encode(bufferlist& bl) const { - ::encode(key, bl); - ::encode(expiration, bl); - } - void decode(bufferlist::iterator& bl) { - ::decode(key, bl); - ::decode(expiration, bl); - } -}; -WRITE_CLASS_ENCODER(ExpiringCryptoKey); - - - -struct RotatingSecrets { - map secrets; - version_t max_ver; - - void encode(bufferlist& bl) const { - ::encode(secrets, bl); - ::encode(max_ver, bl); - } - void decode(bufferlist::iterator& bl) { - ::decode(secrets, bl); - ::decode(max_ver, bl); - } - - void add(ExpiringCryptoKey& key); -}; -WRITE_CLASS_ENCODER(RotatingSecrets); - struct KeysServerData { version_t version; @@ -108,6 +74,7 @@ struct KeysServerData { map::iterator secrets_begin() { return secrets.begin(); } map::iterator secrets_end() { return secrets.end(); } + map::iterator find_name(EntityName& name) { return secrets.find(name); } }; WRITE_CLASS_ENCODER(KeysServerData); @@ -186,6 +153,8 @@ public: bool updated_rotating(bufferlist& rotating_bl, version_t& rotating_ver); void decode_rotating(bufferlist& rotating_bl); + + bool get_rotating_encrypted(EntityName& name, bufferlist& enc_bl); }; WRITE_CLASS_ENCODER(KeysServer); diff --git a/src/messages/MAuthRotating.h b/src/messages/MAuthRotating.h new file mode 100644 index 0000000000000..1223fd79f2875 --- /dev/null +++ b/src/messages/MAuthRotating.h @@ -0,0 +1,46 @@ +// -*- 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 __MAUTHROTATING_H +#define __MAUTHROTATING_H + +#include "messages/PaxosServiceMessage.h" +#include "auth/Auth.h" + +class MAuthRotating : public PaxosServiceMessage { +public: + bufferlist response_bl; + uint32_t status; + EntityName entity_name; + + MAuthRotating() : PaxosServiceMessage(MSG_AUTH_ROTATING, 0) { } + + const char *get_type_name() { return "get auth_rotating_secret request/response"; } + + void decode_payload() { + bufferlist::iterator p = payload.begin(); + paxos_decode(p); + ::decode(status, p); + ::decode(entity_name, p); + ::decode(response_bl, p); + } + void encode_payload() { + paxos_encode(); + ::encode(status, payload); + ::encode(entity_name, payload); + ::encode(response_bl, payload); + } +}; + +#endif diff --git a/src/mon/AuthMonitor.cc b/src/mon/AuthMonitor.cc index 810669a31374c..7cae40c99ce1a 100644 --- a/src/mon/AuthMonitor.cc +++ b/src/mon/AuthMonitor.cc @@ -20,6 +20,7 @@ #include "messages/MMonCommand.h" #include "messages/MAuthMon.h" #include "messages/MAuthMonAck.h" +#include "messages/MAuthRotating.h" #include "include/AuthLibrary.h" #include "common/Timer.h" @@ -386,3 +387,23 @@ done: mon->reply_command(m, err, rs, paxos->get_version()); return false; } + + +void AuthMonitor::handle_request(MAuthRotating *m) +{ + dout(10) << "handle_request " << *m << " from " << m->get_orig_source() << dendl; + MAuthRotating *reply = new MAuthRotating(); + + if (!reply) + return; + + if (keys_server.get_rotating_encrypted(m->entity_name, reply->response_bl)) { + reply->status = 0; + } else { + reply->status = -EPERM; + } + + mon->messenger->send_message(reply, m->get_orig_source_inst()); + delete m; +} + diff --git a/src/mon/AuthMonitor.h b/src/mon/AuthMonitor.h index 23fb65b6824b9..85795077a4fee 100644 --- a/src/mon/AuthMonitor.h +++ b/src/mon/AuthMonitor.h @@ -29,6 +29,7 @@ using namespace std; class MMonCommand; class MAuthMon; +class MAuthRotating; class AuthMonitor : public PaxosService { void auth_usage(stringstream& ss); @@ -70,6 +71,7 @@ class AuthMonitor : public PaxosService { public: AuthMonitor(Monitor *mn, Paxos *p) : PaxosService(mn, p), last_rotating_ver(0) { } void handle_request(MAuthMon *m); + void handle_request(MAuthRotating *m); void tick(); // check state, take actions }; diff --git a/src/mon/MonClient.cc b/src/mon/MonClient.cc index 88bc37b0b7502..5068de98d815a 100644 --- a/src/mon/MonClient.cc +++ b/src/mon/MonClient.cc @@ -24,6 +24,7 @@ #include "messages/MClientMountAck.h" #include "messages/MMonSubscribe.h" #include "messages/MMonSubscribeAck.h" +#include "messages/MAuthRotating.h" #include "common/ConfUtils.h" #include "MonClient.h" @@ -179,8 +180,13 @@ bool MonClient::ms_dispatch(Message *m) case CEPH_MSG_MON_SUBSCRIBE_ACK: handle_subscribe_ack((MMonSubscribeAck*)m); return true; + + case MSG_AUTH_ROTATING: + handle_auth_rotating_response((MAuthRotating*)m); + return true; } + return false; } @@ -374,3 +380,46 @@ int MonClient::authorize(double timeout) return auth.authorize(CEPHX_PRINCIPAL_MON, timeout); } +int MonClient::start_auth_rotating(EntityName& name, double timeout) +{ + MAuthRotating *m = new MAuthRotating(); + if (!m) + return -ENOMEM; + send_mon_message(m); + + auth_timeout_event = new C_AuthRotatingTimeout(this, timeout); + if (!auth_timeout_event) + return -ENOMEM; + timer.add_event_after(timeout, auth_timeout_event); + + dout(0) << "MonClient::start_auth_rotating waiting" << dendl; + auth_cond.Wait(monc_lock); + dout(0) << "MonClient::start_auth_rotating wait ended" << dendl; + + timer.cancel_event(auth_timeout_event); + auth_timeout_event = NULL; + + if (auth_got_timeout) { + dout(0) << "MonClient::start_auth_rotating got timeout" << dendl; + return -ETIMEDOUT; + } + + return 0; +} + +void MonClient::handle_auth_rotating_response(MAuthRotating *m) +{ + Mutex::Locker l(monc_lock); + + if (auth_got_timeout) + return; + + auth_cond.Signal(); + + timer.cancel_event(auth_timeout_event); + auth_timeout_event = NULL; + + + dout(0) << "MonClient::handle_auth_rotating_response got_response status=" << m->status << " length=" << m->response_bl.length() << dendl; +} + diff --git a/src/mon/MonClient.h b/src/mon/MonClient.h index c8bc75a695a6d..c411b786f82b7 100644 --- a/src/mon/MonClient.h +++ b/src/mon/MonClient.h @@ -31,6 +31,7 @@ class MonMap; class MMonMap; class MClientMountAck; class MMonSubscribeAck; +class MAuthRotating; class MonClient : public Dispatcher, public AuthClient { public: @@ -62,6 +63,24 @@ private: }; void tick(); + Context *auth_timeout_event; + bool auth_got_timeout; + Cond auth_cond; + + class C_AuthRotatingTimeout : public Context { + protected: + MonClient *client; + double timeout; + public: + C_AuthRotatingTimeout(MonClient *c, double to) : + client(c), timeout(to) { + } + void finish(int r) { + if (r >= 0) client->_auth_rotating_timeout(timeout); + } + }; + + void handle_auth_rotating_response(MAuthRotating *m); // mount private: client_t clientid; @@ -76,6 +95,13 @@ private: void handle_mount_ack(MClientMountAck* m); public: + void _auth_rotating_timeout(double timeout) { + auth_got_timeout = true; + auth_cond.Signal(); + } + + int start_auth_rotating(EntityName& name, double timeout); + int mount(double mount_timeout); int authenticate(double timeout); int authorize(double timeout); @@ -127,6 +153,8 @@ public: monc_lock("MonClient::monc_lock"), timer(monc_lock), hunting(false), + auth_timeout_event(NULL), + auth_got_timeout(false), mounting(0), mount_err(0) { } ~MonClient() { timer.cancel_all_events(); diff --git a/src/mon/Monitor.cc b/src/mon/Monitor.cc index b89253c1826e3..92c0cace84d60 100644 --- a/src/mon/Monitor.cc +++ b/src/mon/Monitor.cc @@ -491,6 +491,9 @@ bool Monitor::ms_dispatch(Message *m) handle_class((MClass *)m); break; + case MSG_AUTH_ROTATING: + handle_rotating((MAuthRotating *)m); + break; default: return false; } @@ -679,6 +682,15 @@ void Monitor::handle_class(MClass *m) } } +/* + get auth rotating secret request + */ + +void Monitor::handle_rotating(MAuthRotating *m) +{ + authmon()->handle_request(m); +} + void Monitor::handle_route(MRoute *m) { diff --git a/src/mon/Monitor.h b/src/mon/Monitor.h index bb9c9f5db452c..e4eb691d6cd11 100644 --- a/src/mon/Monitor.h +++ b/src/mon/Monitor.h @@ -45,6 +45,7 @@ class MMonGetMap; class MMonObserve; class MMonSubscribe; class MClass; +class MAuthRotating; class MRoute; class Monitor : public Dispatcher { @@ -135,6 +136,7 @@ public: void handle_command(class MMonCommand *m); void handle_observe(MMonObserve *m); void handle_class(MClass *m); + void handle_rotating(MAuthRotating *m); void handle_route(MRoute *m); void reply_command(MMonCommand *m, int rc, const string &rs, version_t version); diff --git a/src/msg/Message.cc b/src/msg/Message.cc index f62c674a20089..f1e17a2228f00 100644 --- a/src/msg/Message.cc +++ b/src/msg/Message.cc @@ -126,6 +126,7 @@ using namespace std; #include "messages/MLock.h" #include "messages/MClass.h" +#include "messages/MAuthRotating.h" #include "config.h" @@ -507,6 +508,10 @@ Message *decode_message(ceph_msg_header& header, ceph_msg_footer& footer, m = new MClass(); break; + case MSG_AUTH_ROTATING: + m = new MAuthRotating(); + break; + default: dout(0) << "can't decode unknown message type " << type << " MSG_AUTH=" << CEPH_MSG_AUTH << dendl; assert(0); diff --git a/src/msg/Message.h b/src/msg/Message.h index d56234cbdd3e5..85c6795dafffa 100644 --- a/src/msg/Message.h +++ b/src/msg/Message.h @@ -38,6 +38,7 @@ #define MSG_AUTHMON 60 #define MSG_AUTHMON_ACK 61 +#define MSG_AUTH_ROTATING 62 #define MSG_POOLOP 49 #define MSG_POOLOPREPLY 48 diff --git a/src/osd/OSD.cc b/src/osd/OSD.cc index f22033373d040..935d0d2df400e 100644 --- a/src/osd/OSD.cc +++ b/src/osd/OSD.cc @@ -80,6 +80,8 @@ #include "common/ClassHandler.h" +#include "auth/KeysServer.h" + #include #include #include @@ -421,6 +423,10 @@ int OSD::init() monc->init(); + EntityName ename; + ename.entity_type = CEPHX_PRINCIPAL_OSD; + ename.name = g_conf.id; + // announce to monitor i exist and have booted. do_mon_report(); @@ -437,6 +443,13 @@ int OSD::init() signal(SIGTERM, handle_signal); signal(SIGINT, handle_signal); + int ret = monc->start_auth_rotating(ename, KEY_ROTATE_TIME); + if (ret < 0) { + dout(0) << "could not start rotating keys, err=" << ret << dendl; + return ret; + } + dout(0) << "started rotating keys" << dendl; + return 0; } diff --git a/src/vstart.sh b/src/vstart.sh index f382c3d295e74..cc0d008cce70b 100755 --- a/src/vstart.sh +++ b/src/vstart.sh @@ -263,6 +263,8 @@ EOF echo mkfs osd$osd echo $SUDO $CEPH_BIN/cosd -i $osd $ARGS --mkfs # --debug_journal 20 --debug_osd 20 --debug_filestore 20 --debug_ebofs 20 $SUDO $CEPH_BIN/cosd -i $osd $ARGS --mkfs # --debug_journal 20 --debug_osd 20 --debug_filestore 20 --debug_ebofs 20 + $SUDO $CEPH_BIN/authtool --gen-key dev/osd$osd/key.bin + $SUDO $CEPH_BIN/ceph -i dev/osd$osd/key.bin auth add osd.$osd fi echo start osd$osd run 'osd' $SUDO $CEPH_BIN/cosd -i $osd $ARGS $COSD_ARGS -- 2.39.5