bl.append(os.str());
}
-bool KeyServer::prepare_rotating_update(bufferlist& rotating_bl)
+bool KeyServer::prepare_rotating_update(bufferlist& rotating_bl, bool wipe)
{
std::scoped_lock l{lock};
ldout(cct, 20) << __func__ << " before: data.rotating_ver=" << data.rotating_ver
KeyServerData pending_data(nullptr);
pending_data.rotating_ver = data.rotating_ver + 1;
- pending_data.rotating_secrets = data.rotating_secrets;
+ if (wipe) {
+ /* Always keep CEPH_ENTITY_TYPE_AUTH: existing auth service keys are needed
+ * to renew tickets by daemons/clients and the only information in an old
+ * ticket used is the global_id. Forging tickets is not a significant
+ * concern. A stolen auth service key is not worthwhile since you would
+ * be incaapable of generating useful service tickets with the associated
+ * service key (e.g. "osd").
+ */
+ RotatingSecrets& r = data.rotating_secrets[CEPH_ENTITY_TYPE_AUTH];
+ pending_data.rotating_secrets[CEPH_ENTITY_TYPE_AUTH] = r;
+ } else {
+ pending_data.rotating_secrets = data.rotating_secrets;
+ }
int added = 0;
added += _rotate_secret(CEPH_ENTITY_TYPE_AUTH, pending_data);
}
}
- bool prepare_rotating_update(ceph::buffer::list& rotating_bl);
+ bool prepare_rotating_update(ceph::buffer::list& rotating_bl, bool wipe);
bool get_rotating_encrypted(const EntityName& name, ceph::buffer::list& enc_bl) const;
{
KeyServerData::Incremental rot_inc;
rot_inc.op = KeyServerData::AUTH_INC_SET_ROTATING;
- if (mon.key_server.prepare_rotating_update(rot_inc.rotating_bl)) {
+ if (mon.key_server.prepare_rotating_update(rot_inc.rotating_bl, false)) {
dout(10) << __func__ << " updating rotating" << dendl;
push_cephx_inc(rot_inc);
return true;
cmd_getval(cmdmap, "prefix", prefix);
if (prefix == "auth add" ||
prefix == "auth rotate" ||
+ prefix == "auth dump-keys" ||
+ prefix == "auth wipe-rotating-service-keys" ||
prefix == "auth del" ||
prefix == "auth rm" ||
prefix == "auth get-or-create" ||
wait_for_commit(op, new Monitor::C_Command(mon, op, 0, rs, rdata,
get_last_committed() + 1));
return true;
+ } else if (prefix == "auth dump-keys") {
+ if (f) {
+ f->open_object_section("keys");
+ mon.key_server.dump(f.get());
+ f->close_section();
+ f->flush(ds);
+ err = 0;
+ } else {
+ err = -EINVAL;
+ }
+ goto done;
+ } else if (prefix == "auth wipe-rotating-service-keys") {
+ /* N.B.: doing this requires all service daemons to restart to get new service keys. */
+ /* is this true?? */
+ KeyServerData::Incremental rot_inc;
+ rot_inc.op = KeyServerData::AUTH_INC_SET_ROTATING;
+ bool modified = mon.key_server.prepare_rotating_update(rot_inc.rotating_bl, true);
+ ceph_assert(modified);
+ rs = "wiped rotating service keys!";
+ dout(5) << __func__ << " wiped rotating service keys!" << dendl;
+ push_cephx_inc(rot_inc);
+ wait_for_commit(op, new Monitor::C_Command(mon, op, 0, rs, rdata,
+ get_last_committed() + 1));
+ return true;
}
done:
rdata.append(ds);
,
"rotate entity key",
"auth", "rwx")
+COMMAND("auth dump-keys",
+ "dump keys",
+ "auth", "rwx")
+COMMAND("auth wipe-rotating-service-keys",
+ "wipe rotating keys",
+ "auth", "rwx")
COMMAND("auth get-or-create-key"
" name=entity,type=CephString"
" name=caps,type=CephString,n=N,req=false"
KeyServer ks(g_ceph_context, nullptr);
KeyServerData::Incremental auth_inc;
auth_inc.op = KeyServerData::AUTH_INC_SET_ROTATING;
- bool r = ks.prepare_rotating_update(auth_inc.rotating_bl);
+ bool r = ks.prepare_rotating_update(auth_inc.rotating_bl, false);
ceph_assert(r);
AuthMonitor::Incremental inc;
inc.inc_type = AuthMonitor::AUTH_DATA;