1use std::{path::Path, ptr};
6
7use libc::{c_int, c_uint};
8
9use crate::{
10 consts::flags::{CryptActivate, CryptDeactivate},
11 device::CryptDevice,
12 err::LibcryptErr,
13};
14
15pub struct CryptActivationHandle<'a> {
17 reference: &'a mut CryptDevice,
18}
19
20impl<'a> CryptActivationHandle<'a> {
21 pub(crate) fn new(reference: &'a mut CryptDevice) -> Self {
22 CryptActivationHandle { reference }
23 }
24
25 pub fn activate_by_passphrase(
30 &mut self,
31 name: Option<&str>,
32 keyslot: Option<c_uint>,
33 passphrase: &[u8],
34 flags: CryptActivate,
35 ) -> Result<c_uint, LibcryptErr> {
36 let name_cstring_option = match name {
37 Some(n) => Some(to_cstring!(n)?),
38 None => None,
39 };
40 errno_int_success!(mutex!(libcryptsetup_rs_sys::crypt_activate_by_passphrase(
41 self.reference.as_ptr(),
42 match name_cstring_option {
43 Some(ref cs) => cs.as_ptr(),
44 None => ptr::null_mut(),
45 },
46 keyslot
47 .map(|k| k as c_int)
48 .unwrap_or(libcryptsetup_rs_sys::CRYPT_ANY_SLOT),
49 to_byte_ptr!(passphrase),
50 passphrase.len(),
51 flags.bits(),
52 )))
53 .map(|k| k as c_uint)
54 }
55
56 pub fn activate_by_keyfile_device_offset(
58 &mut self,
59 name: Option<&str>,
60 keyslot: Option<c_uint>,
61 keyfile: &Path,
62 keyfile_size: Option<crate::size_t>,
63 keyfile_offset: u64,
64 flags: CryptActivate,
65 ) -> Result<c_uint, LibcryptErr> {
66 let name_cstring_option = match name {
67 Some(n) => Some(to_cstring!(n)?),
68 None => None,
69 };
70 let keyfile_cstring = path_to_cstring!(keyfile)?;
71 errno_int_success!(mutex!(
72 libcryptsetup_rs_sys::crypt_activate_by_keyfile_device_offset(
73 self.reference.as_ptr(),
74 match name_cstring_option {
75 Some(ref cs) => cs.as_ptr(),
76 None => ptr::null_mut(),
77 },
78 keyslot
79 .map(|k| k as c_int)
80 .unwrap_or(libcryptsetup_rs_sys::CRYPT_ANY_SLOT),
81 keyfile_cstring.as_ptr(),
82 match keyfile_size {
83 Some(i) => i,
84 None => std::fs::metadata(keyfile)
85 .map_err(LibcryptErr::IOError)?
86 .len() as crate::size_t,
87 },
88 keyfile_offset,
89 flags.bits(),
90 )
91 ))
92 .map(|k| k as c_uint)
93 }
94
95 pub fn activate_by_volume_key(
97 &mut self,
98 name: Option<&str>,
99 volume_key: Option<&[u8]>,
100 flags: CryptActivate,
101 ) -> Result<(), LibcryptErr> {
102 let name_cstring_option = match name {
103 Some(n) => Some(to_cstring!(n)?),
104 None => None,
105 };
106 let (volume_key_ptr, volume_key_len) = match volume_key {
107 Some(vk) => (to_byte_ptr!(vk), vk.len()),
108 None => (ptr::null(), 0),
109 };
110 errno!(mutex!(libcryptsetup_rs_sys::crypt_activate_by_volume_key(
111 self.reference.as_ptr(),
112 match name_cstring_option {
113 Some(ref cs) => cs.as_ptr(),
114 None => ptr::null_mut(),
115 },
116 volume_key_ptr,
117 volume_key_len,
118 flags.bits(),
119 )))
120 }
121
122 pub fn activate_by_keyring(
124 &mut self,
125 name: Option<&str>,
126 key_description: &str,
127 keyslot: Option<c_uint>,
128 flags: CryptActivate,
129 ) -> Result<c_uint, LibcryptErr> {
130 let name_cstring_option = match name {
131 Some(n) => Some(to_cstring!(n)?),
132 None => None,
133 };
134 let description_cstring = to_cstring!(key_description)?;
135 errno_int_success!(mutex!(libcryptsetup_rs_sys::crypt_activate_by_keyring(
136 self.reference.as_ptr(),
137 match name_cstring_option {
138 Some(ref cs) => cs.as_ptr(),
139 None => ptr::null_mut(),
140 },
141 description_cstring.as_ptr(),
142 keyslot
143 .map(|k| k as c_int)
144 .unwrap_or(libcryptsetup_rs_sys::CRYPT_ANY_SLOT),
145 flags.bits(),
146 )))
147 .map(|k| k as c_uint)
148 }
149
150 #[cfg(cryptsetup23supported)]
152 pub fn activate_by_signed_key(
153 &mut self,
154 name: Option<&str>,
155 volume_key: Option<&[u8]>,
156 signature: Option<&[u8]>,
157 flags: CryptActivate,
158 ) -> Result<(), LibcryptErr> {
159 let name_cstring_option = match name {
160 Some(n) => Some(to_cstring!(n)?),
161 None => None,
162 };
163 let (volume_key_ptr, volume_key_len) = match volume_key {
164 Some(vk) => (to_byte_ptr!(vk), vk.len()),
165 None => (ptr::null(), 0),
166 };
167 let (signature_ptr, signature_len) = match signature {
168 Some(sig) => (to_byte_ptr!(sig), sig.len()),
169 None => (ptr::null(), 0),
170 };
171 errno!(mutex!(libcryptsetup_rs_sys::crypt_activate_by_signed_key(
172 self.reference.as_ptr(),
173 match name_cstring_option {
174 Some(ref cs) => cs.as_ptr(),
175 None => ptr::null_mut(),
176 },
177 volume_key_ptr,
178 volume_key_len,
179 signature_ptr,
180 signature_len,
181 flags.bits(),
182 )))
183 }
184
185 pub fn deactivate(&mut self, name: &str, flags: CryptDeactivate) -> Result<(), LibcryptErr> {
187 let name_cstring = to_cstring!(name)?;
188 errno!(mutex!(libcryptsetup_rs_sys::crypt_deactivate_by_name(
189 self.reference.as_ptr(),
190 name_cstring.as_ptr(),
191 flags.bits(),
192 )))
193 }
194
195 #[cfg(cryptsetup27supported)]
199 pub fn set_keyring_to_link(
200 &mut self,
201 key_description: &str,
202 old_key_description: Option<&str>,
203 key_desc_type: Option<&str>,
204 keyring: Option<&str>,
205 ) -> Result<(), LibcryptErr> {
206 let kd_cstring = to_cstring!(key_description)?;
207 let old_kd_cstring = match old_key_description.as_ref() {
208 Some(s) => Some(to_cstring!(s)?),
209 None => None,
210 };
211 let kd_type_cstring = match key_desc_type.as_ref() {
212 Some(s) => Some(to_cstring!(s)?),
213 None => None,
214 };
215 let kr_cstring = match keyring.as_ref() {
216 Some(s) => Some(to_cstring!(s)?),
217 None => None,
218 };
219 errno!(mutex!(libcryptsetup_rs_sys::crypt_set_keyring_to_link(
220 self.reference.as_ptr(),
221 kd_cstring.as_ptr(),
222 old_kd_cstring
223 .as_ref()
224 .map(|s| s.as_ptr())
225 .unwrap_or(ptr::null()),
226 kd_type_cstring
227 .as_ref()
228 .map(|s| s.as_ptr())
229 .unwrap_or(ptr::null()),
230 kr_cstring
231 .as_ref()
232 .map(|s| s.as_ptr())
233 .unwrap_or(ptr::null()),
234 )))
235 }
236}