bin_PROGRAMS += dumpjournal dupstore streamtest
test_trans_SOURCES = test_trans.cc
-test_trans_LDADD = libos.a libcommon.a -lpthread -lm
+test_trans_LDADD = libos.a libcommon.a -lpthread -lm -lcrypto
bin_PROGRAMS += test_trans
# synthetic client
return s;
}
- bool from_str(string& s) {
+ bool from_str(const string& s) {
int pos = s.find('.');
if (pos < 0)
KeyRing g_keyring;
-bool KeyRing::load_master(const char *filename_list)
+bool KeyRing::load(const char *filename_list)
{
string k = filename_list;
string filename;
list<string> ls;
get_str_list(k, ls);
- int fd = -1;
+ bufferlist bl;
+ bool loaded = false;
for (list<string>::iterator p = ls.begin(); p != ls.end(); p++) {
// subst in home dir?
size_t pos = p->find("~/");
if (pos != string::npos)
p->replace(pos, 1, getenv("HOME"));
- fd = open(p->c_str(), O_RDONLY);
- if (fd >= 0) {
+ if (bl.read_file(p->c_str(), true) == 0) {
+ loaded = true;
filename = *p;
break;
}
}
- if (fd < 0) {
+ if (!loaded) {
dout(0) << "can't open key file(s) " << filename_list << dendl;
return false;
}
- // get size
- struct stat st;
- int rc = fstat(fd, &st);
- if (rc != 0) {
- dout(0) << "error stat'ing key file " << filename << dendl;
- return false;
- }
- __int32_t len = st.st_size;
-
- bufferlist bl;
+ bufferlist::iterator p = bl.begin();
+ decode(p);
- bufferptr bp(len);
- int off = 0;
- while (off < len) {
- int r = read(fd, bp.c_str()+off, len-off);
- if (r < 0) {
- derr(0) << "errno on read " << strerror(errno) << dendl;
- return false;
+ dout(1) << "loaded key file " << filename << dendl;
+ return true;
+}
+
+void KeyRing::print(ostream& out)
+{
+ for (map<string, EntityAuth>::iterator p = keys.begin();
+ p != keys.end();
+ ++p) {
+ string n = p->first;
+ if (n.empty()) {
+ out << "<default key>" << std::endl;
+ } else {
+ out << n << std::endl;
+ }
+ out << "\tkey: " << p->second.key << std::endl;
+
+ for (map<string, bufferlist>::iterator q = p->second.caps.begin();
+ q != p->second.caps.end();
+ ++q) {
+ bufferlist::iterator dataiter = q->second.begin();
+ string caps;
+ ::decode(caps, dataiter);
+ out << "\tcaps: [" << q->first << "] " << caps << std::endl;
}
- off += r;
}
- bl.append(bp);
- close(fd);
-
- bufferlist::iterator iter = bl.begin();
-
- map<string, EntityAuth> m;
- map<string, EntityAuth>::iterator miter;
-
- ::decode(m, iter);
-
- string name = g_conf.entity_name->to_str();
-
- dout(10) << "looking for key entry name=" << name << dendl;
+}
- miter = m.find(name);
- if (miter == m.end()) {
- miter = m.find("");
- if (miter == m.end())
- return false;
+void KeyRing::import(KeyRing& other)
+{
+ for (map<string, EntityAuth>::iterator p = other.keys.begin();
+ p != other.keys.end();
+ ++p) {
+ dout(10) << " importing " << p->first << " " << p->second << dendl;
+ keys[p->first] = p->second;
}
- master = miter->second.key;
- dout(1) << "loaded key file " << filename << dendl;
- return true;
}
+// ----------------
+// rotating crap
+
void KeyRing::set_rotating(RotatingSecrets& secrets)
{
Mutex::Locker l(lock);
}
}
-void KeyRing::get_master(CryptoKey& dest)
-{
- Mutex::Locker l(lock);
-
- dest = master;
-}
-
bool KeyRing::need_rotating_secrets()
{
Mutex::Locker l(lock);
return false;
}
+
*/
class KeyRing : public KeyStore {
- CryptoKey master;
+ map<string, EntityAuth> keys;
RotatingSecrets rotating_secrets;
Mutex lock;
public:
KeyRing() : lock("KeyRing") {}
- bool load_master(const char *filename);
- void set_rotating(RotatingSecrets& secrets);
-
- void get_master(CryptoKey& dest);
+ map<string, EntityAuth>& get_keys() { return keys; } // yuck
- bool need_rotating_secrets();
+ bool load(const char *filename);
+ void print(ostream& out);
+ bool get_auth(EntityName& name, EntityAuth &a) {
+ string n = name.to_str();
+ if (keys.count(n)) {
+ a = keys[n];
+ return true;
+ }
+ return false;
+ }
bool get_secret(EntityName& name, CryptoKey& secret) {
- get_master(secret);
- return true;
+ string n = name.to_str();
+ if (keys.count(n)) {
+ secret = keys[n].key;
+ return true;
+ }
+ return false;
+ }
+ void get_master(CryptoKey& dest) {
+ get_secret(*g_conf.entity_name, dest);
+ }
+
+ //
+ void add(EntityName& name, EntityAuth &a) {
+ string s = name.to_str();
+ keys[s] = a;
}
+ void set_caps(EntityName& name, map<string, bufferlist>& caps) {
+ string s = name.to_str();
+ keys[s].caps = caps;
+ }
+ void import(KeyRing& other);
+
+ // weirdness
+ void set_rotating(RotatingSecrets& secrets);
+ bool need_rotating_secrets();
bool get_service_secret(uint32_t service_id, uint64_t secret_id, CryptoKey& secret);
+
+ void encode(bufferlist& bl) const {
+ __u8 v = 1;
+ ::encode(v, bl);
+ ::encode(keys, bl);
+ }
+ void decode(bufferlist::iterator& bl) {
+ __u8 v;
+ ::decode(v, bl);
+ ::decode(keys, bl);
+ }
};
+WRITE_CLASS_ENCODER(KeyRing)
extern KeyRing g_keyring;
#include "common/common_init.h"
#include "auth/Crypto.h"
#include "auth/Auth.h"
+#include "auth/KeyRing.h"
void usage()
{
const char *fn = 0;
bool gen_key = false;
bool list = false;
- bool print_key = true;
+ bool print_key = false;
bool create_keyring = false;
const char *name = "";
const char *caps_fn = NULL;
+ const char *import_keyring = NULL;
FOR_EACH_ARG(args) {
if (CONF_ARG_EQ("gen-key", 'g')) {
CONF_SAFE_SET_ARG_VAL(&print_key, OPT_BOOL);
} else if (CONF_ARG_EQ("create-keyring", 'c')) {
CONF_SAFE_SET_ARG_VAL(&create_keyring, OPT_BOOL);
+ } else if (CONF_ARG_EQ("import-keyring", '\0')) {
+ CONF_SAFE_SET_ARG_VAL(&import_keyring, OPT_STR);
} else if (!fn) {
fn = args[i];
} else
usage();
}
- map<string, EntityAuth> keys_map;
+ bool modified = false;
+ KeyRing keyring;
string s = name;
+ EntityName ename;
+ ename.from_str(s);
if (caps_fn) {
if (!name || !(*name)) {
}
bufferlist bl;
- int r = bl.read_file(fn, true);
- if (r >= 0) {
- try {
- bufferlist::iterator iter = bl.begin();
- ::decode(keys_map, iter);
- } catch (buffer::error *err) {
- cerr << "error reading file " << fn << std::endl;
- exit(1);
- }
- } else if (create_keyring && r == -ENOENT) {
+ int r = 0;
+ if (create_keyring) {
cout << "creating " << fn << std::endl;
} else {
- cerr << "can't open " << fn << ": " << strerror(errno) << std::endl;
- exit(1);
+ r = bl.read_file(fn, true);
+ if (r >= 0) {
+ try {
+ bufferlist::iterator iter = bl.begin();
+ ::decode(keyring, iter);
+ } catch (buffer::error *err) {
+ cerr << "error reading file " << fn << std::endl;
+ exit(1);
+ }
+ } else {
+ cerr << "can't open " << fn << ": " << strerror(-r) << std::endl;
+ exit(1);
+ }
}
if (gen_key) {
- CryptoKey key;
- key.create(CEPH_CRYPTO_AES);
- keys_map[s].key = key;
+ EntityAuth eauth;
+ eauth.key.create(CEPH_CRYPTO_AES);
+ keyring.add(ename, eauth);
+ modified = true;
} else if (list) {
- map<string, EntityAuth>::iterator iter = keys_map.begin();
- for (; iter != keys_map.end(); ++iter) {
- string n = iter->first;
- if (n.empty()) {
- cout << "<default key>" << std::endl;
- } else {
- cout << n << std::endl;
- }
- cout << "\tkey: " << iter->second.key << std::endl;
- map<string, bufferlist>::iterator capsiter = iter->second.caps.begin();
- for (; capsiter != iter->second.caps.end(); ++capsiter) {
- bufferlist::iterator dataiter = capsiter->second.begin();
- string caps;
- ::decode(caps, dataiter);
- cout << "\tcaps: [" << capsiter->first << "] " << caps << std::endl;
- }
- }
+ keyring.print(cout);
} else if (print_key) {
- if (keys_map.count(s)) {
+ CryptoKey key;
+ if (keyring.get_secret(ename, key)) {
string a;
- keys_map[s].key.encode_base64(a);
+ key.encode_base64(a);
cout << a << std::endl;
+ } else {
+ cerr << "entity " << ename << " not found" << std::endl;
}
- else
- cerr << "entity " << s << " not found" << std::endl;
+ } else if (import_keyring) {
+ KeyRing other;
+ bufferlist obl;
+ int r = obl.read_file(import_keyring);
+ if (r >= 0) {
+ try {
+ bufferlist::iterator iter = obl.begin();
+ ::decode(other, iter);
+ } catch (buffer::error *err) {
+ cerr << "error reading file " << import_keyring << std::endl;
+ exit(1);
+ }
+
+ cout << "importing contents of " << import_keyring << " into " << fn << std::endl;
+ //other.print(cout);
+ keyring.import(other);
+ modified = true;
+
+ } else {
+ cerr << "can't open " << import_keyring << ": " << strerror(-r) << std::endl;
+ exit(1);
+ }
+ } else {
+ cerr << "no command specified" << std::endl;
+ usage();
}
+
if (caps_fn) {
- map<string, bufferlist>& caps = keys_map[s].caps;
ConfFile *cf = new ConfFile(caps_fn);
if (!cf->parse()) {
cerr << "could not parse caps file " << caps_fn << std::endl;
exit(1);
}
+ map<string, bufferlist> caps;
const char *key_names[] = { "mon", "osd", "mds", NULL };
for (int i=0; key_names[i]; i++) {
char *val;
free(val);
}
}
+ keyring.set_caps(ename, caps);
+ modified = true;
}
- if (gen_key) {
- bufferlist bl2;
- ::encode(keys_map, bl2);
- r = bl2.write_file(fn);
-
+ if (modified) {
+ bufferlist bl;
+ ::encode(keyring, bl);
+ r = bl.write_file(fn);
if (r < 0) {
cerr << "could not write " << fn << std::endl;
}
+ //cout << "wrote " << bl.length() << " bytes to " << fn << std::endl;
}
return 0;
_dout_open_log();
if (init_keys && is_supported_auth(CEPH_AUTH_CEPHX)) {
- g_keyring.load_master(g_conf.keyring);
+ g_keyring.load(g_conf.keyring);
}
}
#include "common/Timer.h"
#include "auth/AuthServiceHandler.h"
+#include "auth/KeyRing.h"
#include "osd/osd_types.h"
#include "osd/PG.h" // yuck
{
dout(0) << "create_initial -- creating initial map" << dendl;
if (g_conf.keyring) {
- map<string, EntityAuth> keys_map;
dout(0) << "reading initial keyring " << dendl;
bufferlist bl;
if ((r = bl.read_file(g_conf.keyring)) >= 0)
break;
if (r >= 0) {
+ KeyRing keyring;
bool read_ok = false;
try {
bufferlist::iterator iter = bl.begin();
- ::decode(keys_map, iter);
+ ::decode(keyring, iter);
read_ok = true;
} catch (buffer::error *err) {
cerr << "error reading file " << g_conf.keyring << std::endl;
}
if (read_ok) {
- map<string, EntityAuth>::iterator iter = keys_map.begin();
- for (; iter != keys_map.end(); ++iter) {
- string n = iter->first;
- if (!n.empty()) {
- dout(0) << "read key for entry: " << n << dendl;
- KeyServerData::Incremental auth_inc;
- if (!auth_inc.name.from_str(n)) {
- dout(0) << "bad entity name " << n << dendl;
- continue;
- }
- auth_inc.auth = iter->second;
- auth_inc.op = KeyServerData::AUTH_INC_ADD;
- push_cephx_inc(auth_inc);
- }
- }
+ string def;
+ import_keyring(keyring, def);
}
-
}
}
return true;
}
+void AuthMonitor::import_keyring(KeyRing& keyring, string& def)
+{
+ for (map<string, EntityAuth>::iterator p = keyring.get_keys().begin();
+ p != keyring.get_keys().end();
+ p++) {
+ KeyServerData::Incremental auth_inc;
+ if (p->first.empty()) {
+ if (def.empty())
+ continue;
+ if (!auth_inc.name.from_str(def)) {
+ dout(0) << "bad entity name" << def << dendl;
+ }
+ } else {
+ if (!auth_inc.name.from_str(p->first)) {
+ dout(0) << "bad entity name " << p->first << dendl;
+ continue;
+ }
+ }
+ auth_inc.auth = p->second;
+ auth_inc.op = KeyServerData::AUTH_INC_ADD;
+ dout(10) << " importing " << auth_inc.name << " " << auth_inc.auth << dendl;
+ push_cephx_inc(auth_inc);
+ }
+}
bool AuthMonitor::prepare_command(MMonCommand *m)
{
bufferlist bl = m->get_data();
dout(0) << "AuthMonitor::prepare_command bl.length()=" << bl.length() << dendl;
bufferlist::iterator iter = bl.begin();
- map<string, EntityAuth> crypto_map;
+ KeyRing keyring;
try {
- ::decode(crypto_map, iter);
+ ::decode(keyring, iter);
} catch (buffer::error *err) {
- ss << "error decoding key";
+ ss << "error decoding keyring";
rs = -EINVAL;
goto done;
}
- for (map<string, EntityAuth>::iterator miter = crypto_map.begin(); miter != crypto_map.end(); ++miter) {
- KeyServerData::Incremental auth_inc;
- dout(0) << "storing auth for " << entity_name << dendl;
- if (miter->first.empty()) {
- if (entity_name.empty())
- continue;
- auth_inc.name.from_str(entity_name);
- } else {
- string s = miter->first;
- auth_inc.name.from_str(s);
- }
- auth_inc.auth = miter->second;
- auth_inc.op = KeyServerData::AUTH_INC_ADD;
- push_cephx_inc(auth_inc);
- }
+ import_keyring(keyring, entity_name);
ss << "updated";
getline(ss, rs);
paxos->wait_for_commit(new Monitor::C_Command(mon, m, 0, rs, paxos->get_version()));
class MAuth;
class MAuthMon;
class MMonGlobalID;
+class KeyRing;
#define MIN_GLOBAL_ID 0x1000
uint64_t max_global_id;
uint64_t last_allocated_id;
+ void import_keyring(KeyRing& keyring, string& def);
+
void push_cephx_inc(KeyServerData::Incremental& auth_inc) {
Incremental inc;
inc.inc_type = AUTH_DATA;