Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Online re-encrypt #3651

Draft
wants to merge 4 commits into
base: master
Choose a base branch
from
Draft
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -142,7 +142,7 @@ version = "0.2.155"
optional = true

[dependencies.libcryptsetup-rs]
version = "0.11.0"
version = "0.11.2"
features = ["mutex"]
optional = true

9 changes: 2 additions & 7 deletions src/bin/stratis-legacy-pool.rs
Original file line number Diff line number Diff line change
@@ -9,7 +9,7 @@ use serde_json::{json, Map, Value};

use stratisd::{
engine::{
register_clevis_token, EncryptionInfo, KeyDescription, ProcessedPathInfos, StratPool,
register_clevis_token, InputEncryptionInfo, KeyDescription, ProcessedPathInfos, StratPool,
CLEVIS_TANG_TRUST_URL,
},
stratis::StratisResult,
@@ -120,12 +120,7 @@ fn main() -> StratisResult<()> {
)?
.unpack()
.1;
let encryption_info = match (key_desc, clevis_info) {
(Some(kd), Some(ci)) => Some(EncryptionInfo::Both(kd, ci)),
(Some(kd), _) => Some(EncryptionInfo::KeyDesc(kd)),
(_, Some(ci)) => Some(EncryptionInfo::ClevisInfo(ci)),
(_, _) => None,
};
let encryption_info = InputEncryptionInfo::new_legacy(key_desc, clevis_info);
register_clevis_token()?;
StratPool::initialize(name.as_str(), unowned, encryption_info.as_ref())?;
Ok(())
295 changes: 199 additions & 96 deletions src/bin/stratis-min/stratis-min.rs

Large diffs are not rendered by default.

9 changes: 5 additions & 4 deletions src/dbus_api/api/manager_3_0/methods.rs
Original file line number Diff line number Diff line change
@@ -22,9 +22,9 @@ use crate::{
util::{engine_to_dbus_err_tuple, get_next_arg, tuple_to_option},
},
engine::{
CreateAction, DeleteAction, EncryptionInfo, EngineAction, IntegritySpec, KeyDescription,
MappingCreateAction, MappingDeleteAction, PoolIdentifier, PoolUuid, SetUnlockAction,
UnlockMethod,
CreateAction, DeleteAction, EngineAction, InputEncryptionInfo, IntegritySpec,
KeyDescription, MappingCreateAction, MappingDeleteAction, PoolIdentifier, PoolUuid,
SetUnlockAction, UnlockMethod,
},
stratis::StratisError,
};
@@ -322,12 +322,13 @@ pub fn create_pool(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {
},
None => None,
};
let encryption_info = InputEncryptionInfo::new_legacy(key_desc, clevis_info);

let dbus_context = m.tree.get_data();
let create_result = handle_action!(block_on(dbus_context.engine.create_pool(
name,
&devs.map(Path::new).collect::<Vec<&Path>>(),
EncryptionInfo::from_options((key_desc, clevis_info)).as_ref(),
encryption_info.as_ref(),
IntegritySpec::default(),
)));
match create_result {
4 changes: 2 additions & 2 deletions src/dbus_api/api/manager_3_2/methods.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ use crate::{
types::{DbusErrorEnum, TData, OK_STRING},
util::{engine_to_dbus_err_tuple, get_next_arg, tuple_to_option},
},
engine::{PoolIdentifier, PoolUuid, StartAction, StopAction, UnlockMethod},
engine::{PoolIdentifier, PoolUuid, StartAction, StopAction, TokenUnlockMethod, UnlockMethod},
stratis::StratisError,
};

@@ -63,7 +63,7 @@ pub fn start_pool(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {

let ret = match handle_action!(block_on(dbus_context.engine.start_pool(
PoolIdentifier::Uuid(pool_uuid),
unlock_method,
TokenUnlockMethod::from(unlock_method),
None
))) {
Ok(StartAction::Started(_)) => {
4 changes: 2 additions & 2 deletions src/dbus_api/api/manager_3_4/methods.rs
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ use crate::{
types::{DbusErrorEnum, TData, OK_STRING},
util::{engine_to_dbus_err_tuple, get_next_arg, tuple_to_option},
},
engine::{Name, PoolIdentifier, PoolUuid, StartAction, UnlockMethod},
engine::{Name, PoolIdentifier, PoolUuid, StartAction, TokenUnlockMethod, UnlockMethod},
stratis::StratisError,
};

@@ -69,7 +69,7 @@ pub fn start_pool(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {

let ret = match handle_action!(block_on(dbus_context.engine.start_pool(
id.clone(),
unlock_method,
TokenUnlockMethod::from(unlock_method),
None
))) {
Ok(StartAction::Started(_)) => {
4 changes: 2 additions & 2 deletions src/dbus_api/api/manager_3_5/methods.rs
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ use crate::{
types::{DbusErrorEnum, TData, OK_STRING},
util::{engine_to_dbus_err_tuple, get_next_arg, tuple_to_option},
},
engine::{CreateAction, EncryptionInfo, IntegritySpec, KeyDescription, PoolIdentifier},
engine::{CreateAction, InputEncryptionInfo, IntegritySpec, KeyDescription, PoolIdentifier},
stratis::StratisError,
};

@@ -64,7 +64,7 @@ pub fn create_pool(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {
let create_result = handle_action!(block_on(dbus_context.engine.create_pool(
name,
&devs.map(Path::new).collect::<Vec<&Path>>(),
EncryptionInfo::from_options((key_desc, clevis_info)).as_ref(),
InputEncryptionInfo::new_legacy(key_desc, clevis_info).as_ref(),
IntegritySpec::default(),
)));
match create_result {
24 changes: 13 additions & 11 deletions src/dbus_api/api/manager_3_8/api.rs
Original file line number Diff line number Diff line change
@@ -20,7 +20,7 @@ pub fn start_pool_method(f: &Factory<MTSync<TData>, TData>) -> Method<MTSync<TDa
f.method("StartPool", (), start_pool)
.in_arg(("id", "s"))
.in_arg(("id_type", "s"))
.in_arg(("unlock_method", "(bs)"))
.in_arg(("unlock_method", "(b(bu))"))
.in_arg(("key_fd", "(bh)"))
// In order from left to right:
// b: true if the pool was newly started
@@ -38,21 +38,23 @@ pub fn create_pool_method(f: &Factory<MTSync<TData>, TData>) -> Method<MTSync<TD
f.method("CreatePool", (), create_pool)
.in_arg(("name", "s"))
.in_arg(("devices", "as"))
// Optional key description of key in the kernel keyring
// b: true if the pool should be encrypted and able to be
// unlocked with a passphrase associated with this key description.
// Optional key descriptions of key in the kernel keyring
// a: array of zero or more elements
// b: true if a token slot is specified
// i: token slot
// s: key description
//
// Rust representation: (bool, String)
.in_arg(("key_desc", "(bs)"))
// Optional Clevis information for binding on initialization.
// b: true if the pool should be encrypted and able to be unlocked
// using Clevis.
// Rust representation: Vec<((bool, u32), String)>
.in_arg(("key_desc", "a((bu)s)"))
// Optional Clevis infos for binding on initialization.
// a: array of zero or more elements
// b: true if a token slot is specified
// i: token slot
// s: pin name
// s: JSON config for Clevis use
//
// Rust representation: (bool, (String, String))
.in_arg(("clevis_info", "(b(ss))"))
// Rust representation: Vec<((bool, u32), String, String)>
.in_arg(("clevis_info", "a((bu)ss)"))
// Optional journal size for integrity metadata reservation.
// b: true if the size should be specified.
// false if the default should be used.
78 changes: 40 additions & 38 deletions src/dbus_api/api/manager_3_8/methods.rs
Original file line number Diff line number Diff line change
@@ -10,21 +10,21 @@ use dbus::{
};
use dbus_tree::{MTSync, MethodInfo, MethodResult};
use futures::executor::block_on;
use serde_json::from_str;

use devicemapper::Bytes;

use crate::{
dbus_api::{
api::shared::EncryptionParams,
blockdev::create_dbus_blockdev,
filesystem::create_dbus_filesystem,
pool::create_dbus_pool,
types::{DbusErrorEnum, TData, OK_STRING},
types::{DbusErrorEnum, EncryptionInfos, TData, OK_STRING},
util::{engine_to_dbus_err_tuple, get_next_arg, tuple_to_option},
},
engine::{
CreateAction, EncryptionInfo, IntegritySpec, IntegrityTagSpec, KeyDescription, Name,
PoolIdentifier, PoolUuid, StartAction, UnlockMethod,
CreateAction, InputEncryptionInfo, IntegritySpec, IntegrityTagSpec, KeyDescription, Name,
PoolIdentifier, PoolUuid, StartAction, TokenUnlockMethod,
},
stratis::StratisError,
};
@@ -64,23 +64,9 @@ pub fn start_pool(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {
}
}
};
let unlock_method = {
let unlock_method_tup: (bool, &str) = get_next_arg(&mut iter, 2)?;
match tuple_to_option(unlock_method_tup) {
Some(unlock_method_str) => {
match UnlockMethod::try_from(unlock_method_str).map_err(|_| {
StratisError::Msg(format!("{unlock_method_str} is an invalid unlock method"))
}) {
Ok(um) => Some(um),
Err(e) => {
let (rc, rs) = engine_to_dbus_err_tuple(&e);
return Ok(vec![return_message.append3(default_return, rc, rs)]);
}
}
}
None => None,
}
};
let unlock_method_tup: (bool, (bool, u32)) = get_next_arg(&mut iter, 2)?;
let unlock_method =
TokenUnlockMethod::from_options(tuple_to_option(unlock_method_tup).map(tuple_to_option));
let fd_opt: (bool, OwnedFd) = get_next_arg(&mut iter, 3)?;
let fd = tuple_to_option(fd_opt);

@@ -153,10 +139,8 @@ pub fn create_pool(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {

let name: &str = get_next_arg(&mut iter, 0)?;
let devs: Array<'_, &str, _> = get_next_arg(&mut iter, 1)?;
let (key_desc_tuple, clevis_tuple): EncryptionParams = (
Some(get_next_arg(&mut iter, 2)?),
Some(get_next_arg(&mut iter, 3)?),
);
let (key_desc_array, clevis_array): EncryptionInfos<'_> =
(get_next_arg(&mut iter, 2)?, get_next_arg(&mut iter, 3)?);
let journal_size_tuple: (bool, u64) = get_next_arg(&mut iter, 4)?;
let tag_spec_tuple: (bool, String) = get_next_arg(&mut iter, 5)?;
let allocate_superblock_tuple: (bool, bool) = get_next_arg(&mut iter, 6)?;
@@ -166,26 +150,44 @@ pub fn create_pool(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {
let default_return: (bool, (dbus::Path<'static>, Vec<dbus::Path<'static>>)) =
(false, (dbus::Path::default(), Vec::new()));

let key_desc = match key_desc_tuple.and_then(tuple_to_option) {
Some(kds) => match KeyDescription::try_from(kds) {
Ok(kd) => Some(kd),
let key_descs =
match key_desc_array
.into_iter()
.try_fold(Vec::new(), |mut vec, (ts_opt, kd_str)| {
let token_slot = tuple_to_option(ts_opt);
let kd = KeyDescription::try_from(kd_str.to_string())?;
vec.push((token_slot, kd));
Ok(vec)
}) {
Ok(kds) => kds,
Err(e) => {
let (rc, rs) = engine_to_dbus_err_tuple(&e);
return Ok(vec![return_message.append3(default_return, rc, rs)]);
}
},
None => None,
};
};

let clevis_info = match clevis_tuple.and_then(tuple_to_option) {
Some((pin, json_string)) => match serde_json::from_str(json_string.as_str()) {
Ok(j) => Some((pin, j)),
let clevis_infos =
match clevis_array
.into_iter()
.try_fold(Vec::new(), |mut vec, (ts_opt, pin, json_str)| {
let token_slot = tuple_to_option(ts_opt);
let json = from_str(json_str)?;
vec.push((token_slot, (pin.to_owned(), json)));
Ok(vec)
}) {
Ok(cis) => cis,
Err(e) => {
let (rc, rs) = engine_to_dbus_err_tuple(&StratisError::Serde(e));
let (rc, rs) = engine_to_dbus_err_tuple(&e);
return Ok(vec![return_message.append3(default_return, rc, rs)]);
}
},
None => None,
};

let ei = match InputEncryptionInfo::new(key_descs, clevis_infos) {
Ok(opt) => opt,
Err(e) => {
let (rc, rs) = engine_to_dbus_err_tuple(&e);
return Ok(vec![return_message.append3(default_return, rc, rs)]);
}
};

let journal_size = tuple_to_option(journal_size_tuple).map(Bytes::from);
@@ -208,7 +210,7 @@ pub fn create_pool(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {
let create_result = handle_action!(block_on(dbus_context.engine.create_pool(
name,
&devs.map(Path::new).collect::<Vec<&Path>>(),
EncryptionInfo::from_options((key_desc, clevis_info)).as_ref(),
ei.as_ref(),
IntegritySpec {
journal_size,
tag_spec,
2 changes: 2 additions & 0 deletions src/dbus_api/consts.rs
Original file line number Diff line number Diff line change
@@ -44,9 +44,11 @@ pub const POOL_HAS_CACHE_PROP: &str = "HasCache";
pub const POOL_ENCRYPTED_PROP: &str = "Encrypted";
pub const POOL_AVAIL_ACTIONS_PROP: &str = "AvailableActions";
pub const POOL_KEY_DESC_PROP: &str = "KeyDescription";
pub const POOL_KEY_DESCS_PROP: &str = "KeyDescriptions";
pub const POOL_TOTAL_SIZE_PROP: &str = "TotalPhysicalSize";
pub const POOL_TOTAL_USED_PROP: &str = "TotalPhysicalUsed";
pub const POOL_CLEVIS_INFO_PROP: &str = "ClevisInfo";
pub const POOL_CLEVIS_INFOS_PROP: &str = "ClevisInfos";
pub const POOL_ALLOC_SIZE_PROP: &str = "AllocatedSize";
pub const POOL_FS_LIMIT_PROP: &str = "FsLimit";
pub const POOL_OVERPROV_PROP: &str = "Overprovisioning";
23 changes: 13 additions & 10 deletions src/dbus_api/pool/mod.rs
Original file line number Diff line number Diff line change
@@ -19,6 +19,7 @@ mod pool_3_3;
mod pool_3_5;
mod pool_3_6;
mod pool_3_7;
mod pool_3_8;
pub mod prop_conv;
mod shared;

@@ -281,24 +282,26 @@ pub fn create_dbus_pool<'a>(
.add_m(pool_3_7::destroy_filesystems_method(&f))
.add_m(pool_3_0::snapshot_filesystem_method(&f))
.add_m(pool_3_0::add_blockdevs_method(&f))
.add_m(pool_3_0::bind_clevis_method(&f))
.add_m(pool_3_0::unbind_clevis_method(&f))
.add_m(pool_3_8::bind_clevis_method(&f))
.add_m(pool_3_8::unbind_clevis_method(&f))
.add_m(pool_3_5::init_cache_method(&f))
.add_m(pool_3_0::add_cachedevs_method(&f))
.add_m(pool_3_0::bind_keyring_method(&f))
.add_m(pool_3_0::unbind_keyring_method(&f))
.add_m(pool_3_0::rebind_keyring_method(&f))
.add_m(pool_3_0::rebind_clevis_method(&f))
.add_m(pool_3_8::bind_keyring_method(&f))
.add_m(pool_3_8::unbind_keyring_method(&f))
.add_m(pool_3_8::rebind_keyring_method(&f))
.add_m(pool_3_8::rebind_clevis_method(&f))
.add_m(pool_3_0::rename_method(&f))
.add_m(pool_3_3::grow_physical_device_method(&f))
.add_m(pool_3_7::get_metadata_method(&f))
.add_m(pool_3_7::get_fs_metadata_method(&f))
.add_m(pool_3_8::encrypt_pool_method(&f))
.add_m(pool_3_8::reencrypt_pool_method(&f))
.add_p(pool_3_0::name_property(&f))
.add_p(pool_3_0::uuid_property(&f))
.add_p(pool_3_0::encrypted_property(&f))
.add_p(pool_3_0::avail_actions_property(&f))
.add_p(pool_3_0::key_desc_property(&f))
.add_p(pool_3_0::clevis_info_property(&f))
.add_p(pool_3_8::key_descs_property(&f))
.add_p(pool_3_8::clevis_infos_property(&f))
.add_p(pool_3_0::has_cache_property(&f))
.add_p(pool_3_0::alloc_size_property(&f))
.add_p(pool_3_0::used_size_property(&f))
@@ -444,8 +447,8 @@ pub fn get_pool_properties(
consts::POOL_UUID_PROP => uuid_to_string!(pool_uuid),
consts::POOL_ENCRYPTED_PROP => shared::pool_enc_prop(pool),
consts::POOL_AVAIL_ACTIONS_PROP => shared::pool_avail_actions_prop(pool),
consts::POOL_KEY_DESC_PROP => shared::pool_key_desc_prop(pool),
consts::POOL_CLEVIS_INFO_PROP => shared::pool_clevis_info_prop(pool),
consts::POOL_KEY_DESCS_PROP => shared::pool_key_descs_prop(pool),
consts::POOL_CLEVIS_INFOS_PROP => shared::pool_clevis_infos_prop(pool),
consts::POOL_HAS_CACHE_PROP => shared::pool_has_cache_prop(pool),
consts::POOL_ALLOC_SIZE_PROP => shared::pool_allocated_size(pool),
consts::POOL_TOTAL_USED_PROP => shared::pool_used_size(pool),
2 changes: 1 addition & 1 deletion src/dbus_api/pool/pool_3_0/api.rs
Original file line number Diff line number Diff line change
@@ -130,7 +130,7 @@ pub fn add_cachedevs_method(f: &Factory<MTSync<TData>, TData>) -> Method<MTSync<
pub fn encrypted_property(f: &Factory<MTSync<TData>, TData>) -> Property<MTSync<TData>, TData> {
f.property::<bool, _>(consts::POOL_ENCRYPTED_PROP, ())
.access(Access::Read)
.emits_changed(EmitsChangedSignal::Const)
.emits_changed(EmitsChangedSignal::True)
.on_get(get_pool_encrypted)
}

Loading
Loading