.. option:: --encryption-format
Image encryption format.
- Possible values: *luks*
+ Possible values: *luks*, *luks1*, *luks2*
.. option:: --encryption-passphrase-file
sudo rbd device unmap -t nbd $LIBRBD_DEV
# flatten
- rbd flatten testimg2 --encryption-format luks --encryption-format luks --encryption-passphrase-file /tmp/passphrase2 --encryption-passphrase-file /tmp/passphrase
+ expect_false rbd flatten testimg2 --encryption-format luks1 --encryption-format luks2 --encryption-passphrase-file /tmp/passphrase2 --encryption-passphrase-file /tmp/passphrase
+ rbd flatten testimg2 --encryption-format luks2 --encryption-format luks1 --encryption-passphrase-file /tmp/passphrase2 --encryption-passphrase-file /tmp/passphrase
# verify with cryptsetup
RAW_FLAT_DEV=$(_sudo rbd -p rbd map testimg2 -t nbd)
--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
-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
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(),
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,
}
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()) {
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;
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)>
uint32_t *flags);
int get_encryption_options(const boost::program_options::variables_map &vm,
- EncryptionOptions* opts);
+ EncryptionOptions* result);
void init_context();
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;
<< " [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"
}
};
+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;
unsigned long size;
unsigned long blksize = RBD_NBD_BLKSIZE;
bool use_netlink;
- auto encryption_format_count = cfg->encryption_format.size();
int fd[2];
}
}
- 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;
} 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;
} 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;