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 9 commits into
base: master
Choose a base branch
from
9 changes: 2 additions & 7 deletions src/bin/stratis-legacy-pool.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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(())
Expand Down
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
Expand Up @@ -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,
};
Expand Down Expand Up @@ -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 {
Expand Down
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
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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(_)) => {
Expand Down
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
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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(_)) => {
Expand Down
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
Expand Up @@ -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,
};

Expand Down Expand Up @@ -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 {
Expand Down
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
Expand Up @@ -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
Expand All @@ -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.
Expand Down
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
Expand Up @@ -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,
};
Expand Down Expand Up @@ -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);

Expand Down Expand Up @@ -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)?;
Expand All @@ -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);
Expand All @@ -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,
Expand Down
2 changes: 2 additions & 0 deletions src/dbus_api/consts.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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";
Expand Down
23 changes: 13 additions & 10 deletions src/dbus_api/pool/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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))
Expand Down Expand Up @@ -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),
Expand Down
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
Expand Up @@ -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)
}

Expand Down
Loading
Loading