libcryptsetup_rs/
activate.rs

1// This Source Code Form is subject to the terms of the Mozilla Public
2// License, v. 2.0. If a copy of the MPL was not distributed with this
3// file, You can obtain one at http://mozilla.org/MPL/2.0/.
4
5use 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
15/// Handle for activation options
16pub 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    /// Activate device by passphrase.
26    ///
27    /// A value of `None` for the name will only check the passphrase and will
28    /// not activate the keyslot.
29    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    /// Activate device by key file
57    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    /// Activate device by volume key
96    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    /// Activeate device using passphrase in kernel keyring
123    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    /// Deactivate crypt device
151    pub fn deactivate(&mut self, name: &str, flags: CryptDeactivate) -> Result<(), LibcryptErr> {
152        let name_cstring = to_cstring!(name)?;
153        errno!(mutex!(libcryptsetup_rs_sys::crypt_deactivate_by_name(
154            self.reference.as_ptr(),
155            name_cstring.as_ptr(),
156            flags.bits(),
157        )))
158    }
159
160    /// Set the keyring to link the volume key to on activation.
161    ///
162    /// If `keyring` is None, linking will be disabled.
163    #[cfg(cryptsetup27supported)]
164    pub fn set_keyring_to_link(
165        &mut self,
166        key_description: &str,
167        old_key_description: Option<&str>,
168        key_desc_type: Option<&str>,
169        keyring: Option<&str>,
170    ) -> Result<(), LibcryptErr> {
171        let kd_cstring = to_cstring!(key_description)?;
172        let old_kd_cstring = match old_key_description.as_ref() {
173            Some(s) => Some(to_cstring!(s)?),
174            None => None,
175        };
176        let kd_type_cstring = match key_desc_type.as_ref() {
177            Some(s) => Some(to_cstring!(s)?),
178            None => None,
179        };
180        let kr_cstring = match keyring.as_ref() {
181            Some(s) => Some(to_cstring!(s)?),
182            None => None,
183        };
184        errno!(mutex!(libcryptsetup_rs_sys::crypt_set_keyring_to_link(
185            self.reference.as_ptr(),
186            kd_cstring.as_ptr(),
187            old_kd_cstring
188                .as_ref()
189                .map(|s| s.as_ptr())
190                .unwrap_or(ptr::null()),
191            kd_type_cstring
192                .as_ref()
193                .map(|s| s.as_ptr())
194                .unwrap_or(ptr::null()),
195            kr_cstring
196                .as_ref()
197                .map(|s| s.as_ptr())
198                .unwrap_or(ptr::null()),
199        )))
200    }
201}