From b7e51587954eefbd87fec3aaa13f5208f4cd2ef3 Mon Sep 17 00:00:00 2001 From: John Baublitz Date: Mon, 3 Jun 2024 11:30:02 -0400 Subject: [PATCH] Fix --- src/engine/strat_engine/crypt/handle/v1.rs | 38 ++++----- src/engine/strat_engine/crypt/handle/v2.rs | 38 ++++----- src/engine/strat_engine/crypt/shared.rs | 92 ++++++++++++---------- 3 files changed, 83 insertions(+), 85 deletions(-) diff --git a/src/engine/strat_engine/crypt/handle/v1.rs b/src/engine/strat_engine/crypt/handle/v1.rs index f1a39fa68d..0837bd033d 100644 --- a/src/engine/strat_engine/crypt/handle/v1.rs +++ b/src/engine/strat_engine/crypt/handle/v1.rs @@ -851,7 +851,7 @@ impl CryptHandle { } /// Get the keyslot associated with the given token ID. - pub fn keyslots(&self, token_id: c_uint) -> StratisResult>> { + pub fn keyslot(&self, token_id: c_uint) -> StratisResult> { get_keyslot_number(&mut self.acquire_crypt_device()?, token_id) } @@ -896,18 +896,16 @@ impl CryptHandle { )); } - let keyslots = self.keyslots(CLEVIS_LUKS_TOKEN_ID)?.ok_or_else(|| { + let keyslot = self.keyslot(CLEVIS_LUKS_TOKEN_ID)?.ok_or_else(|| { StratisError::Msg(format!( "Token slot {CLEVIS_LUKS_TOKEN_ID} appears to be empty; could not determine keyslots" )) })?; - for keyslot in keyslots { - log_on_failure!( - clevis_luks_unbind(self.luks2_device_path(), keyslot), - "Failed to unbind device {} from Clevis", - self.luks2_device_path().display() - ); - } + log_on_failure!( + clevis_luks_unbind(self.luks2_device_path(), keyslot), + "Failed to unbind device {} from Clevis", + self.luks2_device_path().display() + ); self.metadata.encryption_info = self.metadata.encryption_info.clone().unset_clevis_info(); Ok(()) } @@ -925,11 +923,9 @@ impl CryptHandle { } let mut device = self.acquire_crypt_device()?; - let keyslot = get_keyslot_number(&mut device, CLEVIS_LUKS_TOKEN_ID)? - .and_then(|vec| vec.into_iter().next()) - .ok_or_else(|| { - StratisError::Msg("Clevis binding found but no keyslot was associated".to_string()) - })?; + let keyslot = get_keyslot_number(&mut device, CLEVIS_LUKS_TOKEN_ID)?.ok_or_else(|| { + StratisError::Msg("Clevis binding found but no keyslot was associated".to_string()) + })?; clevis_luks_regen(self.luks2_device_path(), keyslot)?; // Need to reload LUKS2 metadata after Clevis metadata modification. @@ -990,15 +986,13 @@ impl CryptHandle { } let mut device = self.acquire_crypt_device()?; - let keyslots = get_keyslot_number(&mut device, LUKS2_TOKEN_ID)? + let keyslot = get_keyslot_number(&mut device, LUKS2_TOKEN_ID)? .ok_or_else(|| StratisError::Msg("No LUKS2 keyring token was found".to_string()))?; - for keyslot in keyslots { - log_on_failure!( - device.keyslot_handle().destroy(keyslot), - "Failed partway through the kernel keyring unbinding operation \ - which cannot be rolled back; manual intervention may be required" - ) - } + log_on_failure!( + device.keyslot_handle().destroy(keyslot), + "Failed partway through the kernel keyring unbinding operation \ + which cannot be rolled back; manual intervention may be required" + ); device .token_handle() .json_set(TokenInput::RemoveToken(LUKS2_TOKEN_ID))?; diff --git a/src/engine/strat_engine/crypt/handle/v2.rs b/src/engine/strat_engine/crypt/handle/v2.rs index 8c8c49d9f1..527ca83ed2 100644 --- a/src/engine/strat_engine/crypt/handle/v2.rs +++ b/src/engine/strat_engine/crypt/handle/v2.rs @@ -537,7 +537,7 @@ impl CryptHandle { } /// Get the keyslot associated with the given token ID. - pub fn keyslots(&self, token_id: c_uint) -> StratisResult>> { + pub fn keyslot(&self, token_id: c_uint) -> StratisResult> { get_keyslot_number(&mut self.acquire_crypt_device()?, token_id) } @@ -582,18 +582,16 @@ impl CryptHandle { )); } - let keyslots = self.keyslots(CLEVIS_LUKS_TOKEN_ID)?.ok_or_else(|| { + let keyslot = self.keyslot(CLEVIS_LUKS_TOKEN_ID)?.ok_or_else(|| { StratisError::Msg(format!( "Token slot {CLEVIS_LUKS_TOKEN_ID} appears to be empty; could not determine keyslots" )) })?; - for keyslot in keyslots { - log_on_failure!( - clevis_luks_unbind(self.luks2_device_path(), keyslot), - "Failed to unbind device {} from Clevis", - self.luks2_device_path().display() - ); - } + log_on_failure!( + clevis_luks_unbind(self.luks2_device_path(), keyslot), + "Failed to unbind device {} from Clevis", + self.luks2_device_path().display() + ); self.metadata.encryption_info = self.metadata.encryption_info.clone().unset_clevis_info(); Ok(()) } @@ -611,11 +609,9 @@ impl CryptHandle { } let mut device = self.acquire_crypt_device()?; - let keyslot = get_keyslot_number(&mut device, CLEVIS_LUKS_TOKEN_ID)? - .and_then(|vec| vec.into_iter().next()) - .ok_or_else(|| { - StratisError::Msg("Clevis binding found but no keyslot was associated".to_string()) - })?; + let keyslot = get_keyslot_number(&mut device, CLEVIS_LUKS_TOKEN_ID)?.ok_or_else(|| { + StratisError::Msg("Clevis binding found but no keyslot was associated".to_string()) + })?; clevis_luks_regen(self.luks2_device_path(), keyslot)?; // Need to reload LUKS2 metadata after Clevis metadata modification. @@ -676,15 +672,13 @@ impl CryptHandle { } let mut device = self.acquire_crypt_device()?; - let keyslots = get_keyslot_number(&mut device, LUKS2_TOKEN_ID)? + let keyslot = get_keyslot_number(&mut device, LUKS2_TOKEN_ID)? .ok_or_else(|| StratisError::Msg("No LUKS2 keyring token was found".to_string()))?; - for keyslot in keyslots { - log_on_failure!( - device.keyslot_handle().destroy(keyslot), - "Failed partway through the kernel keyring unbinding operation \ - which cannot be rolled back; manual intervention may be required" - ) - } + log_on_failure!( + device.keyslot_handle().destroy(keyslot), + "Failed partway through the kernel keyring unbinding operation \ + which cannot be rolled back; manual intervention may be required" + ); device .token_handle() .json_set(TokenInput::RemoveToken(LUKS2_TOKEN_ID))?; diff --git a/src/engine/strat_engine/crypt/shared.rs b/src/engine/strat_engine/crypt/shared.rs index efa23d9669..cb8114da5b 100644 --- a/src/engine/strat_engine/crypt/shared.rs +++ b/src/engine/strat_engine/crypt/shared.rs @@ -501,16 +501,22 @@ pub fn activate( .is_err() { if let Some(p) = passphrase { + let key_slot = if unlock_method == UnlockMethod::Keyring { + Some(get_keyslot_number(device, LUKS2_TOKEN_ID)?.ok_or_else(|| { + StratisError::Msg("LUKS keyring keyslot not found".to_string()) + })?) + } else if unlock_method == UnlockMethod::Clevis { + Some( + get_keyslot_number(device, CLEVIS_LUKS_TOKEN_ID)? + .ok_or_else(|| StratisError::Msg("Clevis keyslot not found".to_string()))?, + ) + } else { + None + }; log_on_failure!( device.activate_handle().activate_by_passphrase( Some(&name.to_string()), - if unlock_method == UnlockMethod::Keyring { - Some(LUKS2_TOKEN_ID) - } else if unlock_method == UnlockMethod::Clevis { - Some(CLEVIS_LUKS_TOKEN_ID) - } else { - None - }, + key_slot, p.as_ref(), CryptActivate::empty(), ), @@ -532,7 +538,7 @@ pub fn activate( pub fn get_keyslot_number( device: &mut CryptDevice, token_id: c_uint, -) -> StratisResult>> { +) -> StratisResult> { let json = match device.token_handle().json_get(token_id) { Ok(j) => j, Err(_) => return Ok(None), @@ -541,32 +547,38 @@ pub fn get_keyslot_number( .get(TOKEN_KEYSLOTS_KEY) .and_then(|k| k.as_array()) .ok_or_else(|| StratisError::Msg("keyslots value was malformed".to_string()))?; - Ok(Some( - vec.iter() - .filter_map(|int_val| { - let as_str = int_val.as_str(); - if as_str.is_none() { - warn!( - "Discarding invalid value in LUKS2 token keyslot array: {}", - int_val - ); - } - let s = match as_str { - Some(s) => s, - None => return None, - }; - let as_c_uint = s.parse::(); - if let Err(ref e) = as_c_uint { - warn!( - "Discarding invalid value in LUKS2 token keyslot array: {}; \ + let mut keyslots = vec + .iter() + .filter_map(|int_val| { + let as_str = int_val.as_str(); + if as_str.is_none() { + warn!( + "Discarding invalid value in LUKS2 token keyslot array: {}", + int_val + ); + } + let s = match as_str { + Some(s) => s, + None => return None, + }; + let as_c_uint = s.parse::(); + if let Err(ref e) = as_c_uint { + warn!( + "Discarding invalid value in LUKS2 token keyslot array: {}; \ failed to convert it to an integer: {}", - s, e, - ); - } - as_c_uint.ok() - }) - .collect::>(), - )) + s, e, + ); + } + as_c_uint.ok() + }) + .collect::>(); + if keyslots.len() > 1 { + return Err(StratisError::Msg(format!( + "Each token should be associated with exactly one keyslot; found {}", + keyslots.len() + ))); + } + Ok(keyslots.pop()) } /// Deactivate an encrypted Stratis device but do not wipe it. This is not @@ -639,14 +651,12 @@ pub fn ensure_wiped( ensure_inactive(device, name)?; let keyslot_number = get_keyslot_number(device, LUKS2_TOKEN_ID); match keyslot_number { - Ok(Some(nums)) => { - for i in nums.iter() { - log_on_failure!( - device.keyslot_handle().destroy(*i), - "Failed to destroy keyslot at index {}", - i - ); - } + Ok(Some(keyslot)) => { + log_on_failure!( + device.keyslot_handle().destroy(keyslot), + "Failed to destroy keyslot at index {}", + keyslot + ); } Ok(None) => { info!(