Skip to content

Commit

Permalink
Add infrastructure for supporting multiple token slots per unlock method
Browse files Browse the repository at this point in the history
  • Loading branch information
jbaublitz committed Nov 20, 2024
1 parent 6486432 commit 713979c
Show file tree
Hide file tree
Showing 39 changed files with 2,252 additions and 1,477 deletions.
4 changes: 0 additions & 4 deletions Cargo.lock

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

2 changes: 2 additions & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -145,10 +145,12 @@ optional = true
version = "0.11.0"
features = ["mutex"]
optional = true
path = "../libcryptsetup-rs"

[dependencies.libcryptsetup-rs-sys]
version = "0.4.0"
optional = true
path = "../libcryptsetup-rs/libcryptsetup-rs-sys"

[dependencies.libmount]
version = "0.1.9"
Expand Down
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
304 changes: 202 additions & 102 deletions src/bin/stratis-min/stratis-min.rs

Large diffs are not rendered by default.

5 changes: 3 additions & 2 deletions src/dbus_api/api/manager_3_0/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ use crate::{
util::{engine_to_dbus_err_tuple, get_next_arg, tuple_to_option},
},
engine::{
CreateAction, DeleteAction, EncryptionInfo, EngineAction, KeyDescription,
CreateAction, DeleteAction, EngineAction, InputEncryptionInfo, KeyDescription,
MappingCreateAction, MappingDeleteAction, PoolIdentifier, PoolUuid, SetUnlockAction,
UnlockMethod,
},
Expand Down Expand Up @@ -323,12 +323,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(),
)));
match create_result {
Ok(pool_uuid_action) => match pool_uuid_action {
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, KeyDescription, PoolIdentifier},
engine::{CreateAction, InputEncryptionInfo, 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(),
)));
match create_result {
Ok(pool_uuid_action) => match pool_uuid_action {
Expand Down
4 changes: 2 additions & 2 deletions src/dbus_api/api/manager_3_8/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 @@ -71,7 +71,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),
fd.map(|f| f.into_fd()),
))) {
Ok(StartAction::Started(_)) => {
Expand Down
20 changes: 12 additions & 8 deletions src/dbus_api/pool/pool_3_0/methods.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ use crate::{
util::{engine_to_dbus_err_tuple, get_next_arg, tuple_to_option},
},
engine::{
CreateAction, DeleteAction, EngineAction, FilesystemUuid, KeyDescription, Name, PoolUuid,
RenameAction,
CreateAction, DeleteAction, EngineAction, FilesystemUuid, KeyDescription, Name,
OptionalTokenSlotInput, PoolUuid, RenameAction,
},
stratis::StratisError,
};
Expand Down Expand Up @@ -376,7 +376,7 @@ pub fn bind_clevis(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {
}
};
let msg = match handle_action!(
pool.bind_clevis(pin.as_str(), &json),
pool.bind_clevis(OptionalTokenSlotInput::Legacy, pin.as_str(), &json),
dbus_context,
pool_path.get_name()
) {
Expand Down Expand Up @@ -416,7 +416,7 @@ pub fn unbind_clevis(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {

let mut pool = get_mut_pool!(dbus_context.engine; pool_uuid; default_return; return_message);

let msg = match handle_action!(pool.unbind_clevis(), dbus_context, pool_path.get_name()) {
let msg = match handle_action!(pool.unbind_clevis(None), dbus_context, pool_path.get_name()) {
Ok(DeleteAction::Identity) => {
return_message.append3(false, DbusErrorEnum::OK as u16, OK_STRING.to_string())
}
Expand Down Expand Up @@ -464,7 +464,7 @@ pub fn bind_keyring(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {
let mut pool = get_mut_pool!(dbus_context.engine; pool_uuid; default_return; return_message);

let msg = match handle_action!(
pool.bind_keyring(&key_desc),
pool.bind_keyring(OptionalTokenSlotInput::Legacy, &key_desc),
dbus_context,
pool_path.get_name()
) {
Expand Down Expand Up @@ -504,7 +504,11 @@ pub fn unbind_keyring(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult

let mut pool = get_mut_pool!(dbus_context.engine; pool_uuid; default_return; return_message);

let msg = match handle_action!(pool.unbind_keyring(), dbus_context, pool_path.get_name()) {
let msg = match handle_action!(
pool.unbind_keyring(None),
dbus_context,
pool_path.get_name()
) {
Ok(DeleteAction::Identity) => {
return_message.append3(false, DbusErrorEnum::OK as u16, OK_STRING.to_string())
}
Expand Down Expand Up @@ -552,7 +556,7 @@ pub fn rebind_keyring(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult
let mut pool = get_mut_pool!(dbus_context.engine; pool_uuid; default_return; return_message);

let msg = match handle_action!(
pool.rebind_keyring(&key_desc),
pool.rebind_keyring(None, &key_desc),
dbus_context,
pool_path.get_name()
) {
Expand Down Expand Up @@ -599,7 +603,7 @@ pub fn rebind_clevis(m: &MethodInfo<'_, MTSync<TData>, TData>) -> MethodResult {

let mut pool = get_mut_pool!(dbus_context.engine; pool_uuid; default_return; return_message);

let msg = match handle_action!(pool.rebind_clevis(), dbus_context, pool_path.get_name()) {
let msg = match handle_action!(pool.rebind_clevis(None), dbus_context, pool_path.get_name()) {
Ok(_) => {
dbus_context.push_pool_clevis_info_change(pool_path.get_name(), pool.encryption_info());
return_message.append3(true, DbusErrorEnum::OK as u16, OK_STRING.to_string())
Expand Down
83 changes: 63 additions & 20 deletions src/engine/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,17 +21,20 @@ use crate::{
structures::{AllLockReadGuard, AllLockWriteGuard, SomeLockReadGuard, SomeLockWriteGuard},
types::{
ActionAvailability, BlockDevTier, Clevis, CreateAction, DeleteAction, DevUuid,
EncryptionInfo, FilesystemUuid, GrowAction, Key, KeyDescription, LockedPoolsInfo,
FilesystemUuid, GrowAction, InputEncryptionInfo, Key, KeyDescription, LockedPoolsInfo,
MappingCreateAction, MappingDeleteAction, Name, PoolDiff, PoolEncryptionInfo,
PoolIdentifier, PoolUuid, RegenAction, RenameAction, ReportType, SetCreateAction,
SetDeleteAction, SetUnlockAction, StartAction, StopAction, StoppedPoolsInfo,
StratFilesystemDiff, StratSigblockVersion, UdevEngineEvent, UnlockMethod,
StratFilesystemDiff, StratSigblockVersion, UdevEngineEvent,
},
},
stratis::StratisResult,
};

use super::{types::StratBlockDevDiff, PropChangeAction};
use super::{
types::{OptionalTokenSlotInput, StratBlockDevDiff, TokenUnlockMethod},
PropChangeAction, UnlockMethod,
};

pub const DEV_PATH: &str = "/dev/stratis";
/// The maximum size of pool passphrases stored in the kernel keyring
Expand Down Expand Up @@ -179,30 +182,70 @@ pub trait Pool: Debug + Send + Sync {
tier: BlockDevTier,
) -> StratisResult<(SetCreateAction<DevUuid>, Option<PoolDiff>)>;

/// Bind all devices in the given pool for automated unlocking
/// using clevis.
/// V1: Binds all devices in the pool to a given Clevis config.
/// * token_slot is always Legacy
///
/// V2: Binds crypt device to a given Clevis config.
/// * if token slot is Legacy bind with the assumption that there is only one Clevis token
/// slot allowed.
/// * if token_slot is Some(_): bind to specific token slot
/// * if token_slot is None: bind to any available token_slot
fn bind_clevis(
&mut self,
token_slot: OptionalTokenSlotInput,
pin: &str,
clevis_info: &Value,
) -> StratisResult<CreateAction<Clevis>>;

/// Unbind all devices in the given pool from using clevis.
fn unbind_clevis(&mut self) -> StratisResult<DeleteAction<Clevis>>;
/// V1: Binds all devices in the pool to a given key description.
/// * token_slot is always None
///
/// V2: Binds crypt device to a given key description.
/// * if token slot is Legacy bind with the assumption that there is only one keyring token
/// slot allowed.
/// * if token_slot is Some(_): bind to specific token slot
/// * if token_slot is None: bind to any available token slot
fn bind_keyring(
&mut self,
token_slot: OptionalTokenSlotInput,
key_desc: &KeyDescription,
) -> StratisResult<CreateAction<Key>>;

/// Bind all devices in the given pool for unlocking using a passphrase
/// in the kernel keyring.
fn bind_keyring(&mut self, key_desc: &KeyDescription) -> StratisResult<CreateAction<Key>>;
/// V1: Rebinds all devices in the pool to a given key description.
/// * token_slot is always None
///
/// V2: Rebinds crypt device to a given key description.
/// * if token_slot is Some(_): rebind specific token slot
/// * if token_slot is None: rebind first keyring token slot
fn rebind_keyring(
&mut self,
token_slot: Option<u32>,
new_key_desc: &KeyDescription,
) -> StratisResult<RenameAction<Key>>;

/// Unbind all devices in the given pool from the registered keyring passphrase.
fn unbind_keyring(&mut self) -> StratisResult<DeleteAction<Key>>;
/// V1: Rebinds all devices in the pool to a given Clevis config.
/// * token_slot is always None
///
/// V2: Rebinds crypt device to a given Clevis config.
/// * if token_slot is Some(_): rebind specific token slot
/// * if token_slot is None: rebind first Clevis token slot
fn rebind_clevis(&mut self, token_slot: Option<u32>) -> StratisResult<RegenAction>;

/// Change the key description and passphrase associated with a pool.
fn rebind_keyring(&mut self, new_key_desc: &KeyDescription)
-> StratisResult<RenameAction<Key>>;
/// V1: Unbinds crypt device from the key description token
/// * token_slot is always None
///
/// V2: Unbinds crypt device from the given key description token specified by token slot.
/// * if token_slot is Some(_): unbind specific token slot
/// * if token_slot is None: unbind first key description token slot
fn unbind_keyring(&mut self, token_slot: Option<u32>) -> StratisResult<DeleteAction<Key>>;

/// Regenerate the Clevis bindings associated with a pool.
fn rebind_clevis(&mut self) -> StratisResult<RegenAction>;
/// V1: Unbinds crypt device from the Clevis token
/// * token_slot is always None
///
/// V2: Unbinds crypt device from the given Clevis token specified by token slot.
/// * if token_slot is Some(_): unbind specific token slot
/// * if token_slot is None: unbind first Clevis token slot
fn unbind_clevis(&mut self, token_slot: Option<u32>) -> StratisResult<DeleteAction<Clevis>>;

/// Ensures that all designated filesystems are gone from pool.
/// Returns a list of the filesystems found, and actually destroyed.
Expand Down Expand Up @@ -380,7 +423,7 @@ pub trait Engine: Debug + Report + Send + Sync {
&self,
name: &str,
blockdev_paths: &[&Path],
encryption_info: Option<&EncryptionInfo>,
encryption_info: Option<&InputEncryptionInfo>,
) -> StratisResult<CreateAction<PoolUuid>>;

/// Handle a libudev event.
Expand Down Expand Up @@ -414,7 +457,7 @@ pub trait Engine: Debug + Report + Send + Sync {
async fn unlock_pool(
&self,
uuid: PoolUuid,
unlock_method: UnlockMethod,
token_slot: UnlockMethod,
) -> StratisResult<SetUnlockAction<DevUuid>>;

/// Find the pool designated by name or UUID.
Expand Down Expand Up @@ -465,7 +508,7 @@ pub trait Engine: Debug + Report + Send + Sync {
async fn start_pool(
&self,
pool_id: PoolIdentifier<PoolUuid>,
unlock_method: Option<UnlockMethod>,
token_slot: TokenUnlockMethod,
passphrase_fd: Option<RawFd>,
) -> StratisResult<StartAction<PoolUuid>>;

Expand Down
15 changes: 8 additions & 7 deletions src/engine/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,13 +17,14 @@ pub use self::{
structures::{AllLockReadGuard, ExclusiveGuard, SharedGuard, Table},
types::{
ActionAvailability, BlockDevTier, ClevisInfo, CreateAction, DeleteAction, DevUuid, Diff,
EncryptionInfo, EngineAction, FilesystemUuid, GrowAction, KeyDescription, Lockable,
LockedPoolInfo, LockedPoolsInfo, MappingCreateAction, MappingDeleteAction,
MaybeInconsistent, Name, PoolDiff, PoolEncryptionInfo, PoolIdentifier, PoolUuid,
PropChangeAction, RenameAction, ReportType, SetCreateAction, SetDeleteAction,
SetUnlockAction, StartAction, StopAction, StoppedPoolInfo, StoppedPoolsInfo,
StratBlockDevDiff, StratFilesystemDiff, StratPoolDiff, StratSigblockVersion, StratisUuid,
ThinPoolDiff, ToDisplay, UdevEngineEvent, UnlockMethod,
EncryptionInfo, EngineAction, FilesystemUuid, GrowAction, InputEncryptionInfo,
KeyDescription, Lockable, LockedPoolInfo, LockedPoolsInfo, MappingCreateAction,
MappingDeleteAction, MaybeInconsistent, Name, OptionalTokenSlotInput, PoolDiff,
PoolEncryptionInfo, PoolIdentifier, PoolUuid, PropChangeAction, RenameAction, ReportType,
SetCreateAction, SetDeleteAction, SetUnlockAction, StartAction, StopAction,
StoppedPoolInfo, StoppedPoolsInfo, StratBlockDevDiff, StratFilesystemDiff, StratPoolDiff,
StratSigblockVersion, StratisUuid, ThinPoolDiff, ToDisplay, TokenUnlockMethod,
UdevEngineEvent, UnlockMechanism, UnlockMethod,
},
};

Expand Down
Loading

0 comments on commit 713979c

Please sign in to comment.