use std::{path::Path, ptr};
use libc::{c_int, c_uint};
use crate::{
consts::flags::{CryptActivate, CryptDeactivate},
device::CryptDevice,
err::LibcryptErr,
};
pub struct CryptActivationHandle<'a> {
reference: &'a mut CryptDevice,
}
impl<'a> CryptActivationHandle<'a> {
pub(crate) fn new(reference: &'a mut CryptDevice) -> Self {
CryptActivationHandle { reference }
}
pub fn activate_by_passphrase(
&mut self,
name: Option<&str>,
keyslot: Option<c_uint>,
passphrase: &[u8],
flags: CryptActivate,
) -> Result<c_uint, LibcryptErr> {
let name_cstring_option = match name {
Some(n) => Some(to_cstring!(n)?),
None => None,
};
errno_int_success!(mutex!(libcryptsetup_rs_sys::crypt_activate_by_passphrase(
self.reference.as_ptr(),
match name_cstring_option {
Some(ref cs) => cs.as_ptr(),
None => ptr::null_mut(),
},
keyslot
.map(|k| k as c_int)
.unwrap_or(libcryptsetup_rs_sys::CRYPT_ANY_SLOT),
to_byte_ptr!(passphrase),
passphrase.len(),
flags.bits(),
)))
.map(|k| k as c_uint)
}
pub fn activate_by_keyfile_device_offset(
&mut self,
name: Option<&str>,
keyslot: Option<c_uint>,
keyfile: &Path,
keyfile_size: Option<crate::size_t>,
keyfile_offset: u64,
flags: CryptActivate,
) -> Result<c_uint, LibcryptErr> {
let name_cstring_option = match name {
Some(n) => Some(to_cstring!(n)?),
None => None,
};
let keyfile_cstring = path_to_cstring!(keyfile)?;
errno_int_success!(mutex!(
libcryptsetup_rs_sys::crypt_activate_by_keyfile_device_offset(
self.reference.as_ptr(),
match name_cstring_option {
Some(ref cs) => cs.as_ptr(),
None => ptr::null_mut(),
},
keyslot
.map(|k| k as c_int)
.unwrap_or(libcryptsetup_rs_sys::CRYPT_ANY_SLOT),
keyfile_cstring.as_ptr(),
match keyfile_size {
Some(i) => i,
None => std::fs::metadata(keyfile)
.map_err(LibcryptErr::IOError)?
.len() as crate::size_t,
},
keyfile_offset,
flags.bits(),
)
))
.map(|k| k as c_uint)
}
pub fn activate_by_volume_key(
&mut self,
name: Option<&str>,
volume_key: Option<&[u8]>,
flags: CryptActivate,
) -> Result<(), LibcryptErr> {
let name_cstring_option = match name {
Some(n) => Some(to_cstring!(n)?),
None => None,
};
let (volume_key_ptr, volume_key_len) = match volume_key {
Some(vk) => (to_byte_ptr!(vk), vk.len()),
None => (ptr::null(), 0),
};
errno!(mutex!(libcryptsetup_rs_sys::crypt_activate_by_volume_key(
self.reference.as_ptr(),
match name_cstring_option {
Some(ref cs) => cs.as_ptr(),
None => ptr::null_mut(),
},
volume_key_ptr,
volume_key_len,
flags.bits(),
)))
}
pub fn activate_by_keyring(
&mut self,
name: Option<&str>,
key_description: &str,
keyslot: Option<c_uint>,
flags: CryptActivate,
) -> Result<c_uint, LibcryptErr> {
let name_cstring_option = match name {
Some(n) => Some(to_cstring!(n)?),
None => None,
};
let description_cstring = to_cstring!(key_description)?;
errno_int_success!(mutex!(libcryptsetup_rs_sys::crypt_activate_by_keyring(
self.reference.as_ptr(),
match name_cstring_option {
Some(ref cs) => cs.as_ptr(),
None => ptr::null_mut(),
},
description_cstring.as_ptr(),
keyslot
.map(|k| k as c_int)
.unwrap_or(libcryptsetup_rs_sys::CRYPT_ANY_SLOT),
flags.bits(),
)))
.map(|k| k as c_uint)
}
pub fn deactivate(&mut self, name: &str, flags: CryptDeactivate) -> Result<(), LibcryptErr> {
let name_cstring = to_cstring!(name)?;
errno!(mutex!(libcryptsetup_rs_sys::crypt_deactivate_by_name(
self.reference.as_ptr(),
name_cstring.as_ptr(),
flags.bits(),
)))
}
}