auth/Crypto.cc \
auth/ExportControl.cc \
auth/KeyRing.cc \
- auth/KeysServer.cc \
+ auth/KeyServer.cc \
common/LogClient.cc \
msg/Message.cc \
common/Logger.cc \
auth/AuthProtocol.h\
auth/AuthServiceHandler.h\
auth/KeyRing.h\
- auth/KeysServer.h\
+ auth/KeyServer.h\
auth/Crypto.h\
auth/ExportControl.h\
ceph_ver.h \
#include "Auth.h"
-#include "KeysServer.h"
#include "common/Clock.h"
#include "config.h"
*
* {timestamp + 1}^session_key
*/
-bool verify_authorizer(KeysKeeper& keys, bufferlist::iterator& indata,
+bool verify_authorizer(KeyStore& keys, bufferlist::iterator& indata,
AuthServiceTicketInfo& ticket_info, bufferlist& reply_bl)
{
uint32_t service_id;
};
WRITE_CLASS_ENCODER(RotatingSecrets);
-class KeysKeeper {
+
+
+/*
+ * Key management
+ */
+#define KEY_ROTATE_TIME 20
+#define KEY_ROTATE_NUM 3
+
+class KeyStore {
public:
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;
*/
extern bool verify_service_ticket_request(AuthServiceTicketRequest& ticket_req,
bufferlist::iterator& indata);
-extern bool verify_authorizer(KeysKeeper& keys, bufferlist::iterator& indata,
+extern bool verify_authorizer(KeyStore& keys, bufferlist::iterator& indata,
AuthServiceTicketInfo& ticket_info, bufferlist& reply_bl);
#endif
CryptoKey secret;
dout(0) << "entity_name=" << entity_name.to_str() << dendl;
- if (!mon->keys_server.get_secret(entity_name, secret)) {
+ if (!mon->key_server.get_secret(entity_name, secret)) {
dout(0) << "couldn't find entity name: " << entity_name.to_str() << dendl;
ret = -EPERM;
break;
SessionAuthInfo info;
CryptoKey principal_secret;
- if (mon->keys_server.get_secret(req.name, principal_secret) < 0) {
+ if (mon->key_server.get_secret(req.name, principal_secret) < 0) {
ret = -EPERM;
break;
}
info.ticket.addr = req.addr;
info.ticket.init_timestamps(g_clock.now(), g_conf.auth_mon_ticket_ttl);
- mon->keys_server.generate_secret(session_key);
+ mon->key_server.generate_secret(session_key);
info.session_key = session_key;
info.service_id = CEPHX_PRINCIPAL_AUTH;
- if (!mon->keys_server.get_service_secret(CEPHX_PRINCIPAL_AUTH, info.service_secret, info.secret_id)) {
+ if (!mon->key_server.get_service_secret(CEPHX_PRINCIPAL_AUTH, info.service_secret, info.secret_id)) {
dout(0) << "could not get service secret for auth subsystem" << dendl;
ret = -EIO;
break;
{
bufferlist tmp_bl;
AuthServiceTicketInfo auth_ticket_info;
- if (!verify_authorizer(mon->keys_server, indata, auth_ticket_info, tmp_bl)) {
+ if (!verify_authorizer(mon->key_server, indata, auth_ticket_info, tmp_bl)) {
ret = -EPERM;
}
for (uint32_t service_id = 1; service_id != (CEPHX_PRINCIPAL_TYPE_MASK + 1); service_id <<= 1) {
if (ticket_req.keys & service_id) {
SessionAuthInfo info;
- int r = mon->keys_server.build_session_auth_info(service_id, auth_ticket_info, info);
+ int r = mon->key_server.build_session_auth_info(service_id, auth_ticket_info, info);
if (r < 0) {
ret = r;
break;
#include "Crypto.h"
#include "auth/KeyRing.h"
-#include "auth/KeysServer.h"
using namespace std;
key of that service
*/
-class KeyRing : public KeysKeeper {
+class KeyRing : public KeyStore {
CryptoKey master;
RotatingSecrets rotating_secrets;
Mutex lock;
--- /dev/null
+// -*- 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 <sage@newdream.net>
+ *
+ * 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 "config.h"
+
+#include "KeyServer.h"
+
+#include "Crypto.h"
+#include "common/Timer.h"
+#include "Auth.h"
+#include "AuthProtocol.h"
+
+#include <sstream>
+
+
+void RotatingSecrets::add(ExpiringCryptoKey& key)
+{
+ secrets[++max_ver] = key;
+
+ while (secrets.size() > KEY_ROTATE_NUM) {
+ map<uint64_t, ExpiringCryptoKey>::iterator iter = secrets.lower_bound(0);
+ secrets.erase(iter);
+ }
+}
+
+bool KeyServerData::get_service_secret(uint32_t service_id, ExpiringCryptoKey& secret, uint64_t& secret_id)
+{
+ map<uint32_t, RotatingSecrets>::iterator iter = rotating_secrets.find(service_id);
+ if (iter == rotating_secrets.end())
+ return false;
+
+ RotatingSecrets& secrets = iter->second;
+ map<uint64_t, ExpiringCryptoKey>::iterator riter = secrets.secrets.lower_bound(0);
+ if (secrets.secrets.size() > 1)
+ ++riter;
+
+
+ secret_id = riter->first;
+ secret = riter->second;
+
+ return true;
+}
+
+bool KeyServerData::get_service_secret(uint32_t service_id, CryptoKey& secret, uint64_t& secret_id)
+{
+ ExpiringCryptoKey e;
+
+ if (!get_service_secret(service_id, e, secret_id))
+ return false;
+
+ secret = e.key;
+
+ return true;
+}
+
+bool KeyServerData::get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret)
+{
+ map<uint32_t, RotatingSecrets>::iterator iter = rotating_secrets.find(service_id);
+ if (iter == rotating_secrets.end())
+ return false;
+
+ RotatingSecrets& secrets = iter->second;
+ map<uint64_t, ExpiringCryptoKey>::iterator riter = secrets.secrets.find(secret_id);
+
+ if (riter == secrets.secrets.end())
+ return false;
+
+ secret = riter->second.key;
+
+ return true;
+}
+
+bool KeyServerData::get_secret(EntityName& name, CryptoKey& secret)
+{
+ map<EntityName, EntityAuth>::iterator iter = secrets.find(name);
+ if (iter == secrets.end())
+ return false;
+
+ secret = iter->second.key;
+
+ return true;
+}
+
+bool KeyServerData::get_caps(EntityName& name, string& type, bufferlist& caps)
+{
+ dout(0) << "get_caps: name=" << name.to_str() << dendl;
+ map<EntityName, EntityAuth>::iterator iter = secrets.find(name);
+ if (iter == secrets.end())
+ return false;
+
+ dout(0) << "get_secret: num of caps=" << iter->second.caps.size() << dendl;
+ map<string, bufferlist>::iterator capsiter = iter->second.caps.find(type);
+ if (capsiter != iter->second.caps.end()) {
+ caps = capsiter->second;
+ }
+
+ return true;
+}
+
+KeyServer::KeyServer() : lock("KeyServer::lock")
+{
+}
+
+int KeyServer::start_server(bool init)
+{
+ Mutex::Locker l(lock);
+
+ if (init) {
+ _generate_all_rotating_secrets(init);
+ }
+ return 0;
+}
+
+void KeyServer::_generate_all_rotating_secrets(bool init)
+{
+ data.rotating_ver++;
+ data.next_rotating_time = g_clock.now();
+ data.next_rotating_time += KEY_ROTATE_TIME;
+ dout(0) << "generate_all_rotating_secrets()" << dendl;
+
+ int i = KEY_ROTATE_NUM;
+
+ if (init)
+ i = 1;
+
+ for (; i <= KEY_ROTATE_NUM; i++) {
+ _rotate_secret(CEPHX_PRINCIPAL_AUTH, i);
+ _rotate_secret(CEPHX_PRINCIPAL_MON, i);
+ _rotate_secret(CEPHX_PRINCIPAL_OSD, i);
+ _rotate_secret(CEPHX_PRINCIPAL_MDS, i);
+ }
+
+ dout(0) << "generated: " << dendl;
+
+ map<uint32_t, RotatingSecrets>::iterator iter = data.rotating_secrets.begin();
+
+ for (; iter != data.rotating_secrets.end(); ++iter) {
+ dout(0) << "service id: " << iter->first << dendl;
+ RotatingSecrets& key = iter->second;
+
+ map<uint64_t, ExpiringCryptoKey>::iterator mapiter = key.secrets.begin();
+ for (; mapiter != key.secrets.end(); ++mapiter) {
+ dout(0) << " id: " << mapiter->first << dendl;
+ bufferptr bp = mapiter->second.key.get_secret();
+ hexdump(" key", bp.c_str(), bp.length());
+ dout(0) << " expiration: " << mapiter->second.expiration << dendl;
+ }
+ }
+}
+
+void KeyServer::_rotate_secret(uint32_t service_id, int factor)
+{
+ ExpiringCryptoKey ek;
+ generate_secret(ek.key);
+ ek.expiration = g_clock.now();
+ ek.expiration += (KEY_ROTATE_TIME * factor);
+
+ data.add_rotating_secret(service_id, ek);
+}
+
+bool KeyServer::_check_rotate()
+{
+ if (g_clock.now() > data.next_rotating_time) {
+ dout(0) << "KeyServer::check_rotate: need to rotate keys" << dendl;
+ _generate_all_rotating_secrets(false);
+ return true;
+ }
+ return false;
+}
+
+bool KeyServer::get_secret(EntityName& name, CryptoKey& secret)
+{
+ Mutex::Locker l(lock);
+
+ return data.get_secret(name, secret);
+}
+
+bool KeyServer::get_caps(EntityName& name, string& type, bufferlist& caps)
+{
+ Mutex::Locker l(lock);
+
+ return data.get_caps(name, type, caps);
+}
+
+bool KeyServer::get_service_secret(uint32_t service_id, ExpiringCryptoKey& secret, uint64_t& secret_id)
+{
+ Mutex::Locker l(lock);
+
+ return data.get_service_secret(service_id, secret, secret_id);
+}
+
+bool KeyServer::get_service_secret(uint32_t service_id, CryptoKey& secret, uint64_t& secret_id)
+{
+ Mutex::Locker l(lock);
+
+ return data.get_service_secret(service_id, secret, secret_id);
+}
+
+bool KeyServer::get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret)
+{
+ Mutex::Locker l(lock);
+
+ return data.get_service_secret(service_id, secret_id, secret);
+}
+
+bool KeyServer::generate_secret(CryptoKey& secret)
+{
+ bufferptr bp;
+ CryptoHandler *crypto = ceph_crypto_mgr.get_crypto(CEPH_SECRET_AES);
+ if (!crypto)
+ return false;
+
+ if (crypto->create(bp) < 0)
+ return false;
+
+ secret.set_secret(CEPH_SECRET_AES, bp);
+
+ return true;
+}
+
+bool KeyServer::generate_secret(EntityName& name, CryptoKey& secret)
+{
+ if (!generate_secret(secret))
+ return false;
+
+ Mutex::Locker l(lock);
+
+ EntityAuth auth;
+ auth.key = secret;
+
+ data.add_auth(name, auth);
+
+ return true;
+}
+
+bool KeyServer::contains(EntityName& name)
+{
+ Mutex::Locker l(lock);
+
+ return data.contains(name);
+}
+
+void KeyServer::list_secrets(stringstream& ss)
+{
+ Mutex::Locker l(lock);
+
+ map<EntityName, EntityAuth>::iterator mapiter = data.secrets_begin();
+ if (mapiter != data.secrets_end()) {
+ ss << "installed auth entries: " << std::endl;
+
+ while (mapiter != data.secrets_end()) {
+ const EntityName& name = mapiter->first;
+ ss << name.to_str() << std::endl;
+
+ map<string, bufferlist>::iterator capsiter = mapiter->second.caps.begin();
+ for (; capsiter != mapiter->second.caps.end(); ++capsiter) {
+ bufferlist::iterator dataiter = capsiter->second.begin();
+ string caps;
+ ::decode(caps, dataiter);
+ ss << "\tcaps: [" << capsiter->first << "] " << caps << std::endl;
+ }
+
+ ++mapiter;
+ }
+ } else {
+ ss << "no installed auth entries!";
+ }
+}
+
+bool KeyServer::updated_rotating(bufferlist& rotating_bl, version_t& rotating_ver)
+{
+ Mutex::Locker l(lock);
+
+ _check_rotate();
+
+ if (data.rotating_ver <= rotating_ver)
+ return false;
+
+ ::encode(data.rotating_ver, rotating_bl);
+ ::encode(data.rotating_secrets, rotating_bl);
+
+ rotating_ver = data.rotating_ver;
+
+ return true;
+}
+
+void KeyServer::decode_rotating(bufferlist& rotating_bl)
+{
+ Mutex::Locker l(lock);
+
+ bufferlist::iterator iter = rotating_bl.begin();
+
+ ::decode(data.rotating_ver, iter);
+ ::decode(data.rotating_secrets, iter);
+}
+
+bool KeyServer::get_rotating_encrypted(EntityName& name, bufferlist& enc_bl)
+{
+ Mutex::Locker l(lock);
+
+ map<EntityName, EntityAuth>::iterator mapiter = data.find_name(name);
+ if (mapiter == data.secrets_end())
+ return false;
+
+ CryptoKey& specific_key = mapiter->second.key;
+
+ map<uint32_t, RotatingSecrets>::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);
+
+ return true;
+}
+
+int KeyServer::_build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info)
+{
+ info.ticket.name = auth_ticket_info.ticket.name;
+ info.ticket.addr = auth_ticket_info.ticket.addr;
+ info.ticket.init_timestamps(g_clock.now(), g_conf.auth_service_ticket_ttl);
+
+ generate_secret(info.session_key);
+
+ info.service_id = service_id;
+
+ string s;
+ get_entity_type_str(service_id, s);
+
+ if (!data.get_caps(info.ticket.name, s, info.ticket.caps)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+int KeyServer::build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info)
+{
+ if (get_service_secret(service_id, info.service_secret, info.secret_id) < 0) {
+ return -EPERM;
+ }
+
+ Mutex::Locker l(lock);
+
+ return _build_session_auth_info(service_id, auth_ticket_info, info);
+}
+
+int KeyServer::build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info,
+ CryptoKey& service_secret, uint64_t secret_id)
+{
+ info.service_secret = service_secret;
+ info.secret_id = secret_id;
+
+ return _build_session_auth_info(service_id, auth_ticket_info, info);
+}
+
--- /dev/null
+// -*- 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 <sage@newdream.net>
+ *
+ * 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 __KEYSSERVER_H
+#define __KEYSSERVER_H
+
+#include "config.h"
+
+#include "Crypto.h"
+#include "common/Timer.h"
+#include "Auth.h"
+
+struct KeyServerData {
+ version_t version;
+ version_t rotating_ver;
+ utime_t next_rotating_time;
+
+ /* for each entity */
+ map<EntityName, EntityAuth> secrets;
+
+ /* for each service type */
+ map<uint32_t, RotatingSecrets> rotating_secrets;
+
+ KeyServerData() : version(0), rotating_ver(0) {}
+
+ void encode(bufferlist& bl) const {
+ ::encode(version, bl);
+ ::encode(rotating_ver, bl);
+ ::encode(next_rotating_time, bl);
+ ::encode(secrets, bl);
+ ::encode(rotating_secrets, bl);
+ }
+ void decode(bufferlist::iterator& bl) {
+ ::decode(version, bl);
+ ::decode(rotating_ver, bl);
+ ::decode(next_rotating_time, bl);
+ ::decode(secrets, bl);
+ ::decode(rotating_secrets, bl);
+ }
+
+ bool contains(EntityName& name) {
+ return (secrets.find(name) != secrets.end());
+ }
+
+ void add_auth(const EntityName& name, EntityAuth& auth) {
+ secrets[name] = auth;
+ }
+
+ void remove_secret(const EntityName& name) {
+ map<EntityName, EntityAuth>::iterator iter = secrets.find(name);
+ if (iter == secrets.end())
+ return;
+ secrets.erase(iter);
+ }
+
+ void add_rotating_secret(uint32_t service_id, ExpiringCryptoKey& key) {
+ rotating_secrets[service_id].add(key);
+ }
+
+ bool get_service_secret(uint32_t service_id, ExpiringCryptoKey& secret, uint64_t& secret_id);
+ bool get_service_secret(uint32_t service_id, CryptoKey& secret, uint64_t& secret_id);
+ bool get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret);
+ bool get_secret(EntityName& name, CryptoKey& secret);
+ bool get_caps(EntityName& name, string& type, bufferlist& caps);
+
+ map<EntityName, EntityAuth>::iterator secrets_begin() { return secrets.begin(); }
+ map<EntityName, EntityAuth>::iterator secrets_end() { return secrets.end(); }
+ map<EntityName, EntityAuth>::iterator find_name(EntityName& name) { return secrets.find(name); }
+};
+WRITE_CLASS_ENCODER(KeyServerData);
+
+class KeyServer : public KeyStore {
+ KeyServerData data;
+
+ Mutex lock;
+
+ void _rotate_secret(uint32_t service_id, int factor);
+ void _generate_all_rotating_secrets(bool init);
+ bool _check_rotate();
+ int _build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info);
+public:
+ KeyServer();
+
+ bool generate_secret(CryptoKey& secret);
+
+ bool get_secret(EntityName& name, CryptoKey& secret);
+ bool get_caps(EntityName& name, string& type, bufferlist& caps);
+ bool get_active_rotating_secret(EntityName& name, CryptoKey& secret);
+ int start_server(bool init);
+ void rotate_timeout(double timeout);
+
+ int build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info);
+ int build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info,
+ CryptoKey& service_secret, uint64_t secret_id);
+
+ /* get current secret for specific service type */
+ bool get_service_secret(uint32_t service_id, ExpiringCryptoKey& service_key, uint64_t& secret_id);
+ bool get_service_secret(uint32_t service_id, CryptoKey& service_key, uint64_t& secret_id);
+ bool get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret);
+
+ bool generate_secret(EntityName& name, CryptoKey& secret);
+
+ void encode(bufferlist& bl) const {
+ ::encode(data, bl);
+ }
+ void decode(bufferlist::iterator& bl) {
+ Mutex::Locker l(lock);
+ ::decode(data, bl);
+ }
+ bool contains(EntityName& name);
+ void list_secrets(stringstream& ss);
+ version_t get_ver() {
+ Mutex::Locker l(lock);
+ return data.version;
+ }
+
+ void set_ver(version_t ver) {
+ Mutex::Locker l(lock);
+ data.version = ver;
+ }
+
+ void add_auth(const EntityName& name, EntityAuth& auth) {
+ Mutex::Locker l(lock);
+ data.add_auth(name, auth);
+ }
+
+ void remove_secret(const EntityName& name) {
+ Mutex::Locker l(lock);
+ data.remove_secret(name);
+ }
+
+ void add_rotating_secret(uint32_t service_id, ExpiringCryptoKey& key) {
+ Mutex::Locker l(lock);
+ data.add_rotating_secret(service_id, key);
+ }
+ void clone_to(KeyServerData& dst) {
+ Mutex::Locker l(lock);
+ dst = data;
+ }
+
+ 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);
+
+ Mutex& get_lock() { return lock; }
+};
+WRITE_CLASS_ENCODER(KeyServer);
+
+
+
+
+
+#endif
+++ /dev/null
-// -*- 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 <sage@newdream.net>
- *
- * 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 "config.h"
-
-#include "KeysServer.h"
-
-#include "Crypto.h"
-#include "common/Timer.h"
-#include "Auth.h"
-#include "AuthProtocol.h"
-
-#include <sstream>
-
-
-void RotatingSecrets::add(ExpiringCryptoKey& key)
-{
- secrets[++max_ver] = key;
-
- while (secrets.size() > KEY_ROTATE_NUM) {
- map<uint64_t, ExpiringCryptoKey>::iterator iter = secrets.lower_bound(0);
- secrets.erase(iter);
- }
-}
-
-bool KeysServerData::get_service_secret(uint32_t service_id, ExpiringCryptoKey& secret, uint64_t& secret_id)
-{
- map<uint32_t, RotatingSecrets>::iterator iter = rotating_secrets.find(service_id);
- if (iter == rotating_secrets.end())
- return false;
-
- RotatingSecrets& secrets = iter->second;
- map<uint64_t, ExpiringCryptoKey>::iterator riter = secrets.secrets.lower_bound(0);
- if (secrets.secrets.size() > 1)
- ++riter;
-
-
- secret_id = riter->first;
- secret = riter->second;
-
- return true;
-}
-
-bool KeysServerData::get_service_secret(uint32_t service_id, CryptoKey& secret, uint64_t& secret_id)
-{
- ExpiringCryptoKey e;
-
- if (!get_service_secret(service_id, e, secret_id))
- return false;
-
- secret = e.key;
-
- return true;
-}
-
-bool KeysServerData::get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret)
-{
- map<uint32_t, RotatingSecrets>::iterator iter = rotating_secrets.find(service_id);
- if (iter == rotating_secrets.end())
- return false;
-
- RotatingSecrets& secrets = iter->second;
- map<uint64_t, ExpiringCryptoKey>::iterator riter = secrets.secrets.find(secret_id);
-
- if (riter == secrets.secrets.end())
- return false;
-
- secret = riter->second.key;
-
- return true;
-}
-
-bool KeysServerData::get_secret(EntityName& name, CryptoKey& secret)
-{
- map<EntityName, EntityAuth>::iterator iter = secrets.find(name);
- if (iter == secrets.end())
- return false;
-
- secret = iter->second.key;
-
- return true;
-}
-
-bool KeysServerData::get_caps(EntityName& name, string& type, bufferlist& caps)
-{
- dout(0) << "get_caps: name=" << name.to_str() << dendl;
- map<EntityName, EntityAuth>::iterator iter = secrets.find(name);
- if (iter == secrets.end())
- return false;
-
- dout(0) << "get_secret: num of caps=" << iter->second.caps.size() << dendl;
- map<string, bufferlist>::iterator capsiter = iter->second.caps.find(type);
- if (capsiter != iter->second.caps.end()) {
- caps = capsiter->second;
- }
-
- return true;
-}
-
-KeysServer::KeysServer() : lock("KeysServer::lock")
-{
-}
-
-int KeysServer::start_server(bool init)
-{
- Mutex::Locker l(lock);
-
- if (init) {
- _generate_all_rotating_secrets(init);
- }
- return 0;
-}
-
-void KeysServer::_generate_all_rotating_secrets(bool init)
-{
- data.rotating_ver++;
- data.next_rotating_time = g_clock.now();
- data.next_rotating_time += KEY_ROTATE_TIME;
- dout(0) << "generate_all_rotating_secrets()" << dendl;
-
- int i = KEY_ROTATE_NUM;
-
- if (init)
- i = 1;
-
- for (; i <= KEY_ROTATE_NUM; i++) {
- _rotate_secret(CEPHX_PRINCIPAL_AUTH, i);
- _rotate_secret(CEPHX_PRINCIPAL_MON, i);
- _rotate_secret(CEPHX_PRINCIPAL_OSD, i);
- _rotate_secret(CEPHX_PRINCIPAL_MDS, i);
- }
-
- dout(0) << "generated: " << dendl;
-
- map<uint32_t, RotatingSecrets>::iterator iter = data.rotating_secrets.begin();
-
- for (; iter != data.rotating_secrets.end(); ++iter) {
- dout(0) << "service id: " << iter->first << dendl;
- RotatingSecrets& key = iter->second;
-
- map<uint64_t, ExpiringCryptoKey>::iterator mapiter = key.secrets.begin();
- for (; mapiter != key.secrets.end(); ++mapiter) {
- dout(0) << " id: " << mapiter->first << dendl;
- bufferptr bp = mapiter->second.key.get_secret();
- hexdump(" key", bp.c_str(), bp.length());
- dout(0) << " expiration: " << mapiter->second.expiration << dendl;
- }
- }
-}
-
-void KeysServer::_rotate_secret(uint32_t service_id, int factor)
-{
- ExpiringCryptoKey ek;
- generate_secret(ek.key);
- ek.expiration = g_clock.now();
- ek.expiration += (KEY_ROTATE_TIME * factor);
-
- data.add_rotating_secret(service_id, ek);
-}
-
-bool KeysServer::_check_rotate()
-{
- if (g_clock.now() > data.next_rotating_time) {
- dout(0) << "KeysServer::check_rotate: need to rotate keys" << dendl;
- _generate_all_rotating_secrets(false);
- return true;
- }
- return false;
-}
-
-bool KeysServer::get_secret(EntityName& name, CryptoKey& secret)
-{
- Mutex::Locker l(lock);
-
- return data.get_secret(name, secret);
-}
-
-bool KeysServer::get_caps(EntityName& name, string& type, bufferlist& caps)
-{
- Mutex::Locker l(lock);
-
- return data.get_caps(name, type, caps);
-}
-
-bool KeysServer::get_service_secret(uint32_t service_id, ExpiringCryptoKey& secret, uint64_t& secret_id)
-{
- Mutex::Locker l(lock);
-
- return data.get_service_secret(service_id, secret, secret_id);
-}
-
-bool KeysServer::get_service_secret(uint32_t service_id, CryptoKey& secret, uint64_t& secret_id)
-{
- Mutex::Locker l(lock);
-
- return data.get_service_secret(service_id, secret, secret_id);
-}
-
-bool KeysServer::get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret)
-{
- Mutex::Locker l(lock);
-
- return data.get_service_secret(service_id, secret_id, secret);
-}
-
-bool KeysServer::generate_secret(CryptoKey& secret)
-{
- bufferptr bp;
- CryptoHandler *crypto = ceph_crypto_mgr.get_crypto(CEPH_SECRET_AES);
- if (!crypto)
- return false;
-
- if (crypto->create(bp) < 0)
- return false;
-
- secret.set_secret(CEPH_SECRET_AES, bp);
-
- return true;
-}
-
-bool KeysServer::generate_secret(EntityName& name, CryptoKey& secret)
-{
- if (!generate_secret(secret))
- return false;
-
- Mutex::Locker l(lock);
-
- EntityAuth auth;
- auth.key = secret;
-
- data.add_auth(name, auth);
-
- return true;
-}
-
-bool KeysServer::contains(EntityName& name)
-{
- Mutex::Locker l(lock);
-
- return data.contains(name);
-}
-
-void KeysServer::list_secrets(stringstream& ss)
-{
- Mutex::Locker l(lock);
-
- map<EntityName, EntityAuth>::iterator mapiter = data.secrets_begin();
- if (mapiter != data.secrets_end()) {
- ss << "installed auth entries: " << std::endl;
-
- while (mapiter != data.secrets_end()) {
- const EntityName& name = mapiter->first;
- ss << name.to_str() << std::endl;
-
- map<string, bufferlist>::iterator capsiter = mapiter->second.caps.begin();
- for (; capsiter != mapiter->second.caps.end(); ++capsiter) {
- bufferlist::iterator dataiter = capsiter->second.begin();
- string caps;
- ::decode(caps, dataiter);
- ss << "\tcaps: [" << capsiter->first << "] " << caps << std::endl;
- }
-
- ++mapiter;
- }
- } else {
- ss << "no installed auth entries!";
- }
-}
-
-bool KeysServer::updated_rotating(bufferlist& rotating_bl, version_t& rotating_ver)
-{
- Mutex::Locker l(lock);
-
- _check_rotate();
-
- if (data.rotating_ver <= rotating_ver)
- return false;
-
- ::encode(data.rotating_ver, rotating_bl);
- ::encode(data.rotating_secrets, rotating_bl);
-
- rotating_ver = data.rotating_ver;
-
- return true;
-}
-
-void KeysServer::decode_rotating(bufferlist& rotating_bl)
-{
- Mutex::Locker l(lock);
-
- bufferlist::iterator iter = rotating_bl.begin();
-
- ::decode(data.rotating_ver, iter);
- ::decode(data.rotating_secrets, iter);
-}
-
-bool KeysServer::get_rotating_encrypted(EntityName& name, bufferlist& enc_bl)
-{
- Mutex::Locker l(lock);
-
- map<EntityName, EntityAuth>::iterator mapiter = data.find_name(name);
- if (mapiter == data.secrets_end())
- return false;
-
- CryptoKey& specific_key = mapiter->second.key;
-
- map<uint32_t, RotatingSecrets>::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);
-
- return true;
-}
-
-int KeysServer::_build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info)
-{
- info.ticket.name = auth_ticket_info.ticket.name;
- info.ticket.addr = auth_ticket_info.ticket.addr;
- info.ticket.init_timestamps(g_clock.now(), g_conf.auth_service_ticket_ttl);
-
- generate_secret(info.session_key);
-
- info.service_id = service_id;
-
- string s;
- get_entity_type_str(service_id, s);
-
- if (!data.get_caps(info.ticket.name, s, info.ticket.caps)) {
- return -EINVAL;
- }
-
- return 0;
-}
-
-int KeysServer::build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info)
-{
- if (get_service_secret(service_id, info.service_secret, info.secret_id) < 0) {
- return -EPERM;
- }
-
- Mutex::Locker l(lock);
-
- return _build_session_auth_info(service_id, auth_ticket_info, info);
-}
-
-int KeysServer::build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info,
- CryptoKey& service_secret, uint64_t secret_id)
-{
- info.service_secret = service_secret;
- info.secret_id = secret_id;
-
- return _build_session_auth_info(service_id, auth_ticket_info, info);
-}
-
+++ /dev/null
-// -*- 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 <sage@newdream.net>
- *
- * 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 __KEYSSERVER_H
-#define __KEYSSERVER_H
-
-#include "config.h"
-
-#include "Crypto.h"
-#include "common/Timer.h"
-#include "Auth.h"
-
-#define KEY_ROTATE_TIME 20
-#define KEY_ROTATE_NUM 3
-
-
-struct KeysServerData {
- version_t version;
- version_t rotating_ver;
- utime_t next_rotating_time;
-
- /* for each entity */
- map<EntityName, EntityAuth> secrets;
-
- /* for each service type */
- map<uint32_t, RotatingSecrets> rotating_secrets;
-
- KeysServerData() : version(0), rotating_ver(0) {}
-
- void encode(bufferlist& bl) const {
- ::encode(version, bl);
- ::encode(rotating_ver, bl);
- ::encode(next_rotating_time, bl);
- ::encode(secrets, bl);
- ::encode(rotating_secrets, bl);
- }
- void decode(bufferlist::iterator& bl) {
- ::decode(version, bl);
- ::decode(rotating_ver, bl);
- ::decode(next_rotating_time, bl);
- ::decode(secrets, bl);
- ::decode(rotating_secrets, bl);
- }
-
- bool contains(EntityName& name) {
- return (secrets.find(name) != secrets.end());
- }
-
- void add_auth(const EntityName& name, EntityAuth& auth) {
- secrets[name] = auth;
- }
-
- void remove_secret(const EntityName& name) {
- map<EntityName, EntityAuth>::iterator iter = secrets.find(name);
- if (iter == secrets.end())
- return;
- secrets.erase(iter);
- }
-
- void add_rotating_secret(uint32_t service_id, ExpiringCryptoKey& key) {
- rotating_secrets[service_id].add(key);
- }
-
- bool get_service_secret(uint32_t service_id, ExpiringCryptoKey& secret, uint64_t& secret_id);
- bool get_service_secret(uint32_t service_id, CryptoKey& secret, uint64_t& secret_id);
- bool get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret);
- bool get_secret(EntityName& name, CryptoKey& secret);
- bool get_caps(EntityName& name, string& type, bufferlist& caps);
-
- map<EntityName, EntityAuth>::iterator secrets_begin() { return secrets.begin(); }
- map<EntityName, EntityAuth>::iterator secrets_end() { return secrets.end(); }
- map<EntityName, EntityAuth>::iterator find_name(EntityName& name) { return secrets.find(name); }
-};
-WRITE_CLASS_ENCODER(KeysServerData);
-
-class KeysServer : public KeysKeeper {
- KeysServerData data;
-
- Mutex lock;
-
- void _rotate_secret(uint32_t service_id, int factor);
- void _generate_all_rotating_secrets(bool init);
- bool _check_rotate();
- int _build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info);
-public:
- KeysServer();
-
- bool generate_secret(CryptoKey& secret);
-
- bool get_secret(EntityName& name, CryptoKey& secret);
- bool get_caps(EntityName& name, string& type, bufferlist& caps);
- bool get_active_rotating_secret(EntityName& name, CryptoKey& secret);
- int start_server(bool init);
- void rotate_timeout(double timeout);
-
- int build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info);
- int build_session_auth_info(uint32_t service_id, AuthServiceTicketInfo& auth_ticket_info, SessionAuthInfo& info,
- CryptoKey& service_secret, uint64_t secret_id);
-
- /* get current secret for specific service type */
- bool get_service_secret(uint32_t service_id, ExpiringCryptoKey& service_key, uint64_t& secret_id);
- bool get_service_secret(uint32_t service_id, CryptoKey& service_key, uint64_t& secret_id);
- bool get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret);
-
- bool generate_secret(EntityName& name, CryptoKey& secret);
-
- void encode(bufferlist& bl) const {
- ::encode(data, bl);
- }
- void decode(bufferlist::iterator& bl) {
- Mutex::Locker l(lock);
- ::decode(data, bl);
- }
- bool contains(EntityName& name);
- void list_secrets(stringstream& ss);
- version_t get_ver() {
- Mutex::Locker l(lock);
- return data.version;
- }
-
- void set_ver(version_t ver) {
- Mutex::Locker l(lock);
- data.version = ver;
- }
-
- void add_auth(const EntityName& name, EntityAuth& auth) {
- Mutex::Locker l(lock);
- data.add_auth(name, auth);
- }
-
- void remove_secret(const EntityName& name) {
- Mutex::Locker l(lock);
- data.remove_secret(name);
- }
-
- void add_rotating_secret(uint32_t service_id, ExpiringCryptoKey& key) {
- Mutex::Locker l(lock);
- data.add_rotating_secret(service_id, key);
- }
- void clone_to(KeysServerData& dst) {
- Mutex::Locker l(lock);
- dst = data;
- }
-
- 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);
-
- Mutex& get_lock() { return lock; }
-};
-WRITE_CLASS_ENCODER(KeysServer);
-
-
-
-
-
-#endif
#include "common/ConfUtils.h"
#include "common/common_init.h"
#include "auth/Crypto.h"
-#include "auth/KeysServer.h"
#include "auth/Auth.h"
void usage()
{
bufferlist::iterator p = notify->bl.begin();
if (notify->is_latest) {
- KeysServerData data;
+ KeyServerData data;
::decode(data, p);
dout(0) << " auth " << dendl;
#if 0
#include "include/types.h"
#include "include/encoding.h"
#include "auth/Auth.h"
-#include "auth/KeysServer.h"
struct AuthLibEntry {
bool rotating;
uint32_t want = peer_id_to_entity_type(dest_type);
if (monclient.auth.build_authorizer(want, authorizer) < 0)
return false;
-
return true;
}
void ms_handle_connect(Connection *con);
void AuthMonitor::check_rotate()
{
AuthLibEntry entry;
- if (!mon->keys_server.updated_rotating(entry.rotating_bl, last_rotating_ver))
+ if (!mon->key_server.updated_rotating(entry.rotating_bl, last_rotating_ver))
return;
dout(0) << "AuthMonitor::tick() updated rotating, now calling propose_pending" << dendl;
if (!mon->is_leader())
return;
- mon->keys_server.start_server(true);
+ mon->key_server.start_server(true);
/*
check_rotate();
*/
{
dout(0) << "AuthMonitor::update_from_paxos()" << dendl;
version_t paxosv = paxos->get_version();
- version_t keys_ver = mon->keys_server.get_ver();
+ version_t keys_ver = mon->key_server.get_ver();
if (paxosv == keys_ver) return true;
assert(paxosv >= keys_ver);
if (v) {
dout(7) << "update_from_paxos startup: loading summary e" << v << dendl;
bufferlist::iterator p = latest.begin();
- ::decode(mon->keys_server, p);
+ ::decode(mon->key_server, p);
}
}
case AUTH_INC_ADD:
if (!entry.rotating) {
derr(0) << "got entry name=" << entry.name.to_str() << dendl;
- mon->keys_server.add_auth(entry.name, entry.auth);
+ mon->key_server.add_auth(entry.name, entry.auth);
} else {
derr(0) << "got AUTH_INC_ADD with entry.rotating" << dendl;
}
break;
case AUTH_INC_DEL:
- mon->keys_server.remove_secret(entry.name);
+ mon->key_server.remove_secret(entry.name);
break;
case AUTH_INC_SET_ROTATING:
{
dout(0) << "AuthMonitor::update_from_paxos: decode_rotating" << dendl;
- mon->keys_server.decode_rotating(entry.rotating_bl);
+ mon->key_server.decode_rotating(entry.rotating_bl);
}
break;
case AUTH_INC_NOP:
}
}
keys_ver++;
- mon->keys_server.set_ver(keys_ver);
+ mon->key_server.set_ver(keys_ver);
}
bufferlist bl;
- Mutex::Locker l(mon->keys_server.get_lock());
- ::encode(mon->keys_server, bl);
+ Mutex::Locker l(mon->key_server.get_lock());
+ ::encode(mon->key_server, bl);
paxos->stash_latest(paxosv, bl);
return true;
void AuthMonitor::init()
{
version_t paxosv = paxos->get_version();
- version_t keys_ver = mon->keys_server.get_ver();
+ version_t keys_ver = mon->key_server.get_ver();
dout(0) << "AuthMonitor::init() paxosv=" << paxosv << dendl;
if (v) {
dout(0) << "AuthMonitor::init() startup: loading summary e" << v << dendl;
bufferlist::iterator p = latest.begin();
- ::decode(mon->keys_server, p);
+ ::decode(mon->key_server, p);
}
}
if (!reply)
return true;
- if (mon->keys_server.get_rotating_encrypted(m->entity_name, reply->response_bl)) {
+ if (mon->key_server.get_rotating_encrypted(m->entity_name, reply->response_bl)) {
reply->status = 0;
} else {
reply->status = -EPERM;
for (deque<AuthLibEntry>::iterator p = m->info.begin();
p != m->info.end();
p++) {
- if (!mon->keys_server.contains((*p).name))
+ if (!mon->key_server.contains((*p).name))
num_new++;
}
if (!num_new) {
string name = m->cmd[2];
AuthLibEntry entry;
entry.name.from_str(name);
- if (!mon->keys_server.contains(entry.name)) {
+ if (!mon->key_server.contains(entry.name)) {
ss << "couldn't find entry " << name;
rs = -ENOENT;
goto done;
paxos->wait_for_commit(new Monitor::C_Command(mon, m, 0, rs, paxos->get_version()));
return true;
} else if (m->cmd[1] == "list") {
- mon->keys_server.list_secrets(ss);
+ mon->key_server.list_secrets(ss);
err = 0;
goto done;
} else {
#include "include/AuthLibrary.h"
-#include "auth/KeysServer.h"
+#include "auth/KeyServer.h"
class MMonCommand;
class MAuth;
#include "auth/Auth.h"
#include "auth/AuthProtocol.h"
-#include "auth/KeysServer.h"
#include "auth/KeyRing.h"
#include "config.h"
AuthServiceTicketInfo auth_ticket_info;
bufferlist tmp_bl;
- ret = verify_authorizer(keys_server, indata, auth_ticket_info, tmp_bl);
+ ret = verify_authorizer(key_server, indata, auth_ticket_info, tmp_bl);
result_bl.claim_append(tmp_bl);
}
break;
dout(0) << "ms_get_authorizer service_id=" << service_id << dendl;
if (service_id != CEPHX_PRINCIPAL_MON) {
- ret = keys_server.build_session_auth_info(service_id, auth_ticket_info, info);
+ ret = key_server.build_session_auth_info(service_id, auth_ticket_info, info);
if (ret < 0) {
return false;
}
name.entity_type = CEPHX_PRINCIPAL_MON;
CryptoKey secret;
- if (!keys_server.get_secret(name, secret)) {
+ if (!key_server.get_secret(name, secret)) {
dout(0) << "couldn't get secret for mon service!" << dendl;
stringstream ss;
- keys_server.list_secrets(ss);
+ key_server.list_secrets(ss);
dout(0) << ss.str() << dendl;
return false;
}
/* mon to mon authentication uses the private monitor shared key and not the
rotating key */
- ret = keys_server.build_session_auth_info(service_id, auth_ticket_info, info, secret, (uint64_t)-1);
+ ret = key_server.build_session_auth_info(service_id, auth_ticket_info, info, secret, (uint64_t)-1);
if (ret < 0) {
return false;
}
if (!authorizer_data.length())
return true; /* we're not picky */
- int ret = verify_authorizer(keys_server, iter, auth_ticket_info, authorizer_reply);
+ int ret = verify_authorizer(key_server, iter, auth_ticket_info, authorizer_reply);
dout(0) << "Monitor::verify_authorizer returns " << ret << dendl;
isvalid = (ret >= 0);
#include "common/LogClient.h"
-#include "auth/KeysServer.h"
+#include "auth/KeyServer.h"
class MonitorStore;
void reset_tick();
friend class C_Mon_Tick;
- KeysServer keys_server;
+ KeyServer key_server;
#include "common/ClassHandler.h"
-#include "auth/KeysServer.h"
-
#include <iostream>
#include <errno.h>
#include <sys/stat.h>
-#include "auth/KeysServer.h"
+#include "auth/KeyServer.h"
#include "config.h"
int main(int argc, char *argv[])
{
- KeysServer server;
+ KeyServer server;
dout(0) << "server created" << dendl;