summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorIlya Dryomov <idryomov@gmail.com>2022-11-19 13:30:55 +0100
committerIlya Dryomov <idryomov@gmail.com>2022-12-04 18:19:19 +0100
commite62e3b6613f93ffd40208d68d400c59a1c32edf9 (patch)
treee14c0a3c06a3a3cc99bd5fd6b8f235ed5ca460d9 /src
parentlibrbd: don't decay LUKS{1,2}EncryptionFormat into LUKSEncryptionFormat (diff)
downloadceph-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.t4
-rw-r--r--src/tools/rbd/ArgumentTypes.cc15
-rw-r--r--src/tools/rbd/Utils.cc74
-rw-r--r--src/tools/rbd/Utils.h41
-rw-r--r--src/tools/rbd_nbd/rbd-nbd.cc138
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;