From 00c2489685d1ebd4d0e6cbea743d4bb790535f76 Mon Sep 17 00:00:00 2001 From: Brad Hubbard Date: Sun, 12 Jun 2016 20:10:25 +1000 Subject: [PATCH] authtool: Enhance argument combinations validation Under certain circumstances ceph-authtool can create invalid key entries in the specified keyring and behave less than intuitively. What's worse these keys can currently cause ceph daemons to crash. This patch attempts to tighten the behaviour and eliminate the possibility an invalid key can be created. Fixes: http://tracker.ceph.com/issues/2904 Signed-off-by: Brad Hubbard --- src/tools/ceph_authtool.cc | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/src/tools/ceph_authtool.cc b/src/tools/ceph_authtool.cc index 55692e5bae928..d7c3724c908ec 100644 --- a/src/tools/ceph_authtool.cc +++ b/src/tools/ceph_authtool.cc @@ -86,6 +86,10 @@ int main(int argc, const char **argv) } else if (ceph_argparse_flag(args, i, "--gen-print-key", (char*)NULL)) { gen_print_key = true; } else if (ceph_argparse_witharg(args, i, &val, "-a", "--add-key", (char*)NULL)) { + if (val.empty()) { + cerr << "Option --add-key requires an argument" << std::endl; + exit(1); + } add_key = val; } else if (ceph_argparse_flag(args, i, "-l", "--list", (char*)NULL)) { list = true; @@ -140,13 +144,20 @@ int main(int argc, const char **argv) usage(); } if (gen_key && (!add_key.empty())) { - cerr << "can't both gen_key and add_key" << std::endl; + cerr << "can't both gen-key and add-key" << std::endl; usage(); } common_init_finish(g_ceph_context); EntityName ename(g_conf->name); + // Enforce the use of gen-key or add-key when creating to avoid ending up + // with an "empty" key (key = AAAAAAAAAAAAAAAA) + if (create_keyring && !gen_key && add_key.empty() && !caps.empty()) { + cerr << "must specify either gen-key or add-key when creating" << std::endl; + usage(); + } + if (gen_print_key) { CryptoKey key; key.create(g_ceph_context, CEPH_CRYPTO_AES); @@ -180,6 +191,17 @@ int main(int argc, const char **argv) } } + // Validate that "name" actually has an existing key in this keyring if we + // have not given gen-key or add-key options + if (!gen_key && add_key.empty() && !caps.empty()) { + CryptoKey key; + if (!keyring.get_secret(ename, key)) { + cerr << "can't find existing key for " << ename + << " and neither gen-key nor add-key specified" << std::endl; + exit(1); + } + } + // write commands if (!import_keyring.empty()) { KeyRing other; -- 2.39.5