diff options
author | Ilya Dryomov <idryomov@gmail.com> | 2022-11-19 13:30:55 +0100 |
---|---|---|
committer | Ilya Dryomov <idryomov@gmail.com> | 2022-12-04 18:19:19 +0100 |
commit | e62e3b6613f93ffd40208d68d400c59a1c32edf9 (patch) | |
tree | e14c0a3c06a3a3cc99bd5fd6b8f235ed5ca460d9 /src | |
parent | librbd: don't decay LUKS{1,2}EncryptionFormat into LUKSEncryptionFormat (diff) | |
download | ceph-e62e3b6613f93ffd40208d68d400c59a1c32edf9.tar.xz ceph-e62e3b6613f93ffd40208d68d400c59a1c32edf9.zip |
rbd, rbd-nbd: accept "luks", "luks1" and "luks2" formats
Since RBD_ENCRYPTION_FORMAT_LUKS1, RBD_ENCRYPTION_FORMAT_LUKS2
and RBD_ENCRYPTION_FORMAT_LUKS aren't treated the same when loading
encryption anymore, "luks1" and "luks2" formats need to be accepted
in addition to "luks" format.
Signed-off-by: Ilya Dryomov <idryomov@gmail.com>
Diffstat (limited to 'src')
-rw-r--r-- | src/test/cli/rbd/help.t | 4 | ||||
-rw-r--r-- | src/tools/rbd/ArgumentTypes.cc | 15 | ||||
-rw-r--r-- | src/tools/rbd/Utils.cc | 74 | ||||
-rw-r--r-- | src/tools/rbd/Utils.h | 41 | ||||
-rw-r--r-- | src/tools/rbd_nbd/rbd-nbd.cc | 138 |
5 files changed, 162 insertions, 110 deletions
diff --git a/src/test/cli/rbd/help.t b/src/test/cli/rbd/help.t index 5c2a38031a5..c70d76f4cd7 100644 --- a/src/test/cli/rbd/help.t +++ b/src/test/cli/rbd/help.t @@ -878,7 +878,7 @@ --namespace arg namespace name --image arg image name --no-progress disable progress output - --encryption-format arg encryption formats [possible values: luks] + --encryption-format arg encryption format (luks, luks1, luks2) --encryption-passphrase-file arg path to file containing passphrase for unlocking the image @@ -2253,7 +2253,7 @@ -s [ --size ] arg image size (in M/G/T) [default: M] --allow-shrink permit shrinking --no-progress disable progress output - --encryption-format arg encryption formats [possible values: luks] + --encryption-format arg encryption format (luks, luks1, luks2) --encryption-passphrase-file arg path to file containing passphrase for unlocking the image diff --git a/src/tools/rbd/ArgumentTypes.cc b/src/tools/rbd/ArgumentTypes.cc index 5d75d02abb3..231264e57b2 100644 --- a/src/tools/rbd/ArgumentTypes.cc +++ b/src/tools/rbd/ArgumentTypes.cc @@ -331,9 +331,9 @@ void add_snap_create_options(po::options_description *opt) { void add_encryption_options(boost::program_options::options_description *opt) { opt->add_options() - (ENCRYPTION_FORMAT.c_str(), - po::value<std::vector<EncryptionFormat>>(), - "encryption formats [possible values: luks]"); + (ENCRYPTION_FORMAT.c_str(), + po::value<std::vector<EncryptionFormat>>(), + "encryption format (luks, luks1, luks2)"); opt->add_options() (ENCRYPTION_PASSPHRASE_FILE.c_str(), @@ -538,14 +538,15 @@ void validate(boost::any& v, const std::vector<std::string>& values, EncryptionFormat *target_type, int) { po::validators::check_first_occurrence(v); const std::string &s = po::validators::get_single_string(values); - EncryptionFormat format; if (s == "luks") { - format.format = RBD_ENCRYPTION_FORMAT_LUKS; + v = boost::any(EncryptionFormat{RBD_ENCRYPTION_FORMAT_LUKS}); + } else if (s == "luks1") { + v = boost::any(EncryptionFormat{RBD_ENCRYPTION_FORMAT_LUKS1}); + } else if (s == "luks2") { + v = boost::any(EncryptionFormat{RBD_ENCRYPTION_FORMAT_LUKS2}); } else { throw po::validation_error(po::validation_error::invalid_option_value); } - - v = boost::any(format); } void validate(boost::any& v, const std::vector<std::string>& values, diff --git a/src/tools/rbd/Utils.cc b/src/tools/rbd/Utils.cc index e3a1f6c8ced..47203dcba1c 100644 --- a/src/tools/rbd/Utils.cc +++ b/src/tools/rbd/Utils.cc @@ -721,20 +721,16 @@ int get_snap_create_flags(const po::variables_map &vm, uint32_t *flags) { } int get_encryption_options(const boost::program_options::variables_map &vm, - EncryptionOptions* opts) { + EncryptionOptions* result) { std::vector<std::string> passphrase_files; if (vm.count(at::ENCRYPTION_PASSPHRASE_FILE)) { passphrase_files = vm[at::ENCRYPTION_PASSPHRASE_FILE].as<std::vector<std::string>>(); } - std::vector<librbd::encryption_format_t> formats; + std::vector<at::EncryptionFormat> formats; if (vm.count(at::ENCRYPTION_FORMAT)) { - auto& format_structs = - vm[at::ENCRYPTION_FORMAT].as<std::vector<at::EncryptionFormat>>(); - for (auto& format_struct : format_structs) { - formats.push_back((librbd::encryption_format_t)format_struct.format); - } + formats = vm[at::ENCRYPTION_FORMAT].as<decltype(formats)>(); } if (formats.size() != passphrase_files.size()) { @@ -743,45 +739,45 @@ int get_encryption_options(const boost::program_options::variables_map &vm, return -EINVAL; } - auto spec_count = formats.size(); - if (spec_count == 0) { - return 0; - } - - opts->luks_opts.reserve(spec_count); - - auto& specs = opts->specs; - specs.resize(spec_count); - for (size_t i = 0; i < spec_count; ++i) { + result->specs.clear(); + result->specs.reserve(formats.size()); + for (size_t i = 0; i < formats.size(); ++i) { std::ifstream file(passphrase_files[i], std::ios::in | std::ios::binary); - auto sg = make_scope_guard([&] { file.close(); }); - - specs[i].format = formats[i]; - std::string* passphrase; - switch (specs[i].format) { - case RBD_ENCRYPTION_FORMAT_LUKS: { - auto& luks_opts = opts->luks_opts; - luks_opts.emplace_back(); - specs[i].opts = &luks_opts.back(); - specs[i].opts_size = sizeof(luks_opts.back()); - passphrase = &luks_opts.back().passphrase; - break; - } - default: - std::cerr << "rbd: unsupported encryption format: " << specs[i].format - << std::endl; - return -ENOTSUP; - } - - passphrase->assign((std::istreambuf_iterator<char>(file)), - (std::istreambuf_iterator<char>())); - if (file.fail()) { std::cerr << "rbd: unable to open passphrase file '" << passphrase_files[i] << "': " << cpp_strerror(errno) << std::endl; return -errno; } + std::string passphrase((std::istreambuf_iterator<char>(file)), + std::istreambuf_iterator<char>()); + file.close(); + + switch (formats[i].format) { + case RBD_ENCRYPTION_FORMAT_LUKS: { + auto opts = new librbd::encryption_luks_format_options_t{ + std::move(passphrase)}; + result->specs.push_back( + {RBD_ENCRYPTION_FORMAT_LUKS, opts, sizeof(*opts)}); + break; + } + case RBD_ENCRYPTION_FORMAT_LUKS1: { + auto opts = new librbd::encryption_luks1_format_options_t{ + .passphrase = std::move(passphrase)}; + result->specs.push_back( + {RBD_ENCRYPTION_FORMAT_LUKS1, opts, sizeof(*opts)}); + break; + } + case RBD_ENCRYPTION_FORMAT_LUKS2: { + auto opts = new librbd::encryption_luks2_format_options_t{ + .passphrase = std::move(passphrase)}; + result->specs.push_back( + {RBD_ENCRYPTION_FORMAT_LUKS2, opts, sizeof(*opts)}); + break; + } + default: + ceph_abort(); + } } return 0; diff --git a/src/tools/rbd/Utils.h b/src/tools/rbd/Utils.h index 5bfdeae0659..5076fd7fe9c 100644 --- a/src/tools/rbd/Utils.h +++ b/src/tools/rbd/Utils.h @@ -86,15 +86,40 @@ struct ProgressContext : public librbd::ProgressContext { int get_percentage(uint64_t part, uint64_t whole); struct EncryptionOptions { - std::vector<librbd::encryption_spec_t> specs; - std::vector<librbd::encryption_luks_format_options_t> luks_opts; - - ~EncryptionOptions() { - for (auto& opts : luks_opts) { - auto& passphrase = opts.passphrase; - ceph_memzero_s(&passphrase[0], passphrase.size(), passphrase.size()); + std::vector<librbd::encryption_spec_t> specs; + + ~EncryptionOptions() { + for (auto& spec : specs) { + switch (spec.format) { + case RBD_ENCRYPTION_FORMAT_LUKS: { + auto opts = + static_cast<librbd::encryption_luks_format_options_t*>(spec.opts); + ceph_memzero_s(opts->passphrase.data(), opts->passphrase.size(), + opts->passphrase.size()); + delete opts; + break; + } + case RBD_ENCRYPTION_FORMAT_LUKS1: { + auto opts = + static_cast<librbd::encryption_luks1_format_options_t*>(spec.opts); + ceph_memzero_s(opts->passphrase.data(), opts->passphrase.size(), + opts->passphrase.size()); + delete opts; + break; + } + case RBD_ENCRYPTION_FORMAT_LUKS2: { + auto opts = + static_cast<librbd::encryption_luks2_format_options_t*>(spec.opts); + ceph_memzero_s(opts->passphrase.data(), opts->passphrase.size(), + opts->passphrase.size()); + delete opts; + break; + } + default: + ceph_abort(); } } + } }; template <typename T, void(T::*MF)(int)> @@ -176,7 +201,7 @@ int get_snap_create_flags(const boost::program_options::variables_map &vm, uint32_t *flags); int get_encryption_options(const boost::program_options::variables_map &vm, - EncryptionOptions* opts); + EncryptionOptions* result); void init_context(); diff --git a/src/tools/rbd_nbd/rbd-nbd.cc b/src/tools/rbd_nbd/rbd-nbd.cc index b5af8b5fd11..cc42491ca08 100644 --- a/src/tools/rbd_nbd/rbd-nbd.cc +++ b/src/tools/rbd_nbd/rbd-nbd.cc @@ -119,8 +119,8 @@ struct Config { std::string format; bool pretty_format = false; - std::vector<librbd::encryption_format_t> encryption_format; - std::vector<std::string> encryption_passphrase_file; + std::vector<librbd::encryption_format_t> encryption_formats; + std::vector<std::string> encryption_passphrase_files; Command command = None; int pid = 0; @@ -152,8 +152,8 @@ static void usage() << " [options] list-mapped List mapped nbd devices\n" << "Map and attach options:\n" << " --device <device path> Specify nbd device path (/dev/nbd{num})\n" - << " --encryption-format Image encryption format\n" - << " (possible values: luks)\n" + << " --encryption-format luks|luks1|luks2\n" + << " Image encryption format\n" << " --encryption-passphrase-file Path of file containing passphrase for unlocking image encryption\n" << " --exclusive Forbid writes by other clients\n" << " --notrim Turn off trim/discard\n" @@ -943,6 +943,43 @@ private: } }; +struct EncryptionOptions { + std::vector<librbd::encryption_spec_t> specs; + + ~EncryptionOptions() { + for (auto& spec : specs) { + switch (spec.format) { + case RBD_ENCRYPTION_FORMAT_LUKS: { + auto opts = + static_cast<librbd::encryption_luks_format_options_t*>(spec.opts); + ceph_memzero_s(opts->passphrase.data(), opts->passphrase.size(), + opts->passphrase.size()); + delete opts; + break; + } + case RBD_ENCRYPTION_FORMAT_LUKS1: { + auto opts = + static_cast<librbd::encryption_luks1_format_options_t*>(spec.opts); + ceph_memzero_s(opts->passphrase.data(), opts->passphrase.size(), + opts->passphrase.size()); + delete opts; + break; + } + case RBD_ENCRYPTION_FORMAT_LUKS2: { + auto opts = + static_cast<librbd::encryption_luks2_format_options_t*>(spec.opts); + ceph_memzero_s(opts->passphrase.data(), opts->passphrase.size(), + opts->passphrase.size()); + delete opts; + break; + } + default: + ceph_abort(); + } + } + } +}; + static std::string get_cookie(const std::string &devpath) { std::string cookie; @@ -1588,7 +1625,6 @@ static int do_map(int argc, const char *argv[], Config *cfg, bool reconnect) unsigned long size; unsigned long blksize = RBD_NBD_BLKSIZE; bool use_netlink; - auto encryption_format_count = cfg->encryption_format.size(); int fd[2]; @@ -1679,55 +1715,53 @@ static int do_map(int argc, const char *argv[], Config *cfg, bool reconnect) } } - if (encryption_format_count > 0) { - std::vector<librbd::encryption_spec_t> specs(encryption_format_count); - std::vector<librbd::encryption_luks_format_options_t> luks_opts; - - luks_opts.reserve(encryption_format_count); + if (!cfg->encryption_formats.empty()) { + EncryptionOptions encryption_options; + encryption_options.specs.reserve(cfg->encryption_formats.size()); - auto sg = make_scope_guard([&] { - for (auto& opts : luks_opts) { - auto& passphrase = opts.passphrase; - ceph_memzero_s(&passphrase[0], passphrase.size(), passphrase.size()); - } - }); - - for (size_t i = 0; i < encryption_format_count; ++i) { - std::ifstream file(cfg->encryption_passphrase_file[i], + for (size_t i = 0; i < cfg->encryption_formats.size(); ++i) { + std::ifstream file(cfg->encryption_passphrase_files[i], std::ios::in | std::ios::binary); - auto sg2 = make_scope_guard([&] { file.close(); }); - - specs[i].format = cfg->encryption_format[i]; - std::string* passphrase; - switch (specs[i].format) { - case RBD_ENCRYPTION_FORMAT_LUKS: { - luks_opts.emplace_back(); - specs[i].opts = &luks_opts.back(); - specs[i].opts_size = sizeof(luks_opts.back()); - passphrase = &luks_opts.back().passphrase; - break; - } - default: - r = -ENOTSUP; - cerr << "rbd-nbd: unsupported encryption format: " << specs[i].format - << std::endl; - goto close_fd; - } - - passphrase->assign((std::istreambuf_iterator<char>(file)), - (std::istreambuf_iterator<char>())); - if (file.fail()) { r = -errno; std::cerr << "rbd-nbd: unable to open passphrase file '" - << cfg->encryption_passphrase_file[i] << "': " - << cpp_strerror(errno) << std::endl; + << cfg->encryption_passphrase_files[i] << "': " + << cpp_strerror(r) << std::endl; goto close_fd; } + std::string passphrase((std::istreambuf_iterator<char>(file)), + std::istreambuf_iterator<char>()); + file.close(); + + switch (cfg->encryption_formats[i]) { + case RBD_ENCRYPTION_FORMAT_LUKS: { + auto opts = new librbd::encryption_luks_format_options_t{ + std::move(passphrase)}; + encryption_options.specs.push_back( + {RBD_ENCRYPTION_FORMAT_LUKS, opts, sizeof(*opts)}); + break; + } + case RBD_ENCRYPTION_FORMAT_LUKS1: { + auto opts = new librbd::encryption_luks1_format_options_t{ + .passphrase = std::move(passphrase)}; + encryption_options.specs.push_back( + {RBD_ENCRYPTION_FORMAT_LUKS1, opts, sizeof(*opts)}); + break; + } + case RBD_ENCRYPTION_FORMAT_LUKS2: { + auto opts = new librbd::encryption_luks2_format_options_t{ + .passphrase = std::move(passphrase)}; + encryption_options.specs.push_back( + {RBD_ENCRYPTION_FORMAT_LUKS2, opts, sizeof(*opts)}); + break; + } + default: + ceph_abort(); + } } - r = image.encryption_load2(&specs[0], encryption_format_count); - + r = image.encryption_load2(encryption_options.specs.data(), + encryption_options.specs.size()); if (r != 0) { cerr << "rbd-nbd: failed to load encryption: " << cpp_strerror(r) << std::endl; @@ -2142,15 +2176,11 @@ static int parse_args(vector<const char*>& args, std::ostream *err_msg, } else if (ceph_argparse_witharg(args, i, &arg_value, "--encryption-format", (char *)NULL)) { if (arg_value == "luks1") { - cfg->encryption_format.push_back(RBD_ENCRYPTION_FORMAT_LUKS); - *err_msg << "rbd-nbd: specifying luks1 when loading encryption " - "is deprecated, use luks"; + cfg->encryption_formats.push_back(RBD_ENCRYPTION_FORMAT_LUKS1); } else if (arg_value == "luks2") { - cfg->encryption_format.push_back(RBD_ENCRYPTION_FORMAT_LUKS); - *err_msg << "rbd-nbd: specifying luks2 when loading encryption " - "is deprecated, use luks"; + cfg->encryption_formats.push_back(RBD_ENCRYPTION_FORMAT_LUKS2); } else if (arg_value == "luks") { - cfg->encryption_format.push_back(RBD_ENCRYPTION_FORMAT_LUKS); + cfg->encryption_formats.push_back(RBD_ENCRYPTION_FORMAT_LUKS); } else { *err_msg << "rbd-nbd: Invalid encryption format"; return -EINVAL; @@ -2158,13 +2188,13 @@ static int parse_args(vector<const char*>& args, std::ostream *err_msg, } else if (ceph_argparse_witharg(args, i, &arg_value, "--encryption-passphrase-file", (char *)NULL)) { - cfg->encryption_passphrase_file.push_back(arg_value); + cfg->encryption_passphrase_files.push_back(arg_value); } else { ++i; } } - if (cfg->encryption_format.size() != cfg->encryption_passphrase_file.size()) { + if (cfg->encryption_formats.size() != cfg->encryption_passphrase_files.size()) { *err_msg << "rbd-nbd: Encryption formats count does not match " << "passphrase files count"; return -EINVAL; |