fm/modes/menu/
password.rs

1/// Different kind of password
2#[derive(Debug, Clone, Copy, Eq, PartialEq)]
3pub enum PasswordKind {
4    SUDO,
5    CRYPTSETUP,
6}
7
8impl std::fmt::Display for PasswordKind {
9    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
10        let asker = match self {
11            Self::SUDO => "sudo   ",
12            Self::CRYPTSETUP => "device ",
13        };
14        write!(f, "{asker}")
15    }
16}
17
18/// What will this password be used for ?
19/// ATM only 3 usages are supported:
20/// * mounting an ISO file,
21/// * opening an mounting an encrypted device.
22/// * running a sudo command
23#[derive(Debug, Clone, Copy, Eq, PartialEq)]
24pub enum PasswordUsage {
25    ISO,
26    CRYPTSETUP(PasswordKind),
27    SUDOCOMMAND,
28    DEVICE,
29}
30
31type Password = String;
32
33/// Holds passwords allowing to mount or unmount an encrypted drive.
34#[derive(Default, Clone)]
35pub struct PasswordHolder {
36    sudo: Option<Password>,
37    cryptsetup: Option<Password>,
38}
39
40/// Custom debug format to prevent leaking passwords in logs.
41impl std::fmt::Debug for PasswordHolder {
42    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
43        f.debug_struct("PasswordHodler")
44            .field("sudo", &self.hide_option(PasswordKind::SUDO))
45            .field("cryptsetup", &self.hide_option(PasswordKind::CRYPTSETUP))
46            .finish()
47    }
48}
49
50impl PasswordHolder {
51    const fn hide_option(&self, password_kind: PasswordKind) -> &str {
52        match password_kind {
53            PasswordKind::SUDO => Self::hide(self.has_sudo()),
54            PasswordKind::CRYPTSETUP => Self::hide(self.has_cryptsetup()),
55        }
56    }
57
58    const fn hide(is_set: bool) -> &'static str {
59        if is_set {
60            "Some(****)"
61        } else {
62            "None"
63        }
64    }
65
66    /// Set the sudo password.
67    pub fn set_sudo(&mut self, password: Password) {
68        self.sudo = Some(password);
69    }
70
71    /// Set the encrypted device passphrase
72    pub fn set_cryptsetup(&mut self, passphrase: Password) {
73        self.cryptsetup = Some(passphrase);
74    }
75
76    /// Reads the cryptsetup password
77    #[must_use]
78    pub fn cryptsetup(&mut self) -> Option<Password> {
79        std::mem::take(&mut self.cryptsetup)
80    }
81
82    /// Reads the sudo password
83    #[must_use]
84    pub fn sudo(&mut self) -> Option<Password> {
85        std::mem::take(&mut self.sudo)
86    }
87
88    /// True if the sudo password was set
89    #[must_use]
90    pub const fn has_sudo(&self) -> bool {
91        self.sudo.is_some()
92    }
93
94    /// True if the encrypted device passphrase was set
95    #[must_use]
96    pub const fn has_cryptsetup(&self) -> bool {
97        self.cryptsetup.is_some()
98    }
99
100    /// Reset every known password, dropping them.
101    /// It should be called ASAP.
102    pub fn reset(&mut self) {
103        std::mem::take(&mut self.sudo);
104        std::mem::take(&mut self.cryptsetup);
105        self.sudo = None;
106        self.cryptsetup = None;
107    }
108}