nucleus/security/
state.rs1use crate::error::StateTransition;
2
3#[derive(Debug, Clone, Copy, PartialEq, Eq)]
13pub enum SecurityState {
14 Privileged,
16 CapabilitiesDropped,
18 SeccompApplied,
20 LandlockApplied,
22 Locked,
24}
25
26impl StateTransition for SecurityState {
27 fn can_transition_to(&self, next: &SecurityState) -> bool {
28 use SecurityState::*;
29
30 matches!(
31 (self, next),
32 (Privileged, CapabilitiesDropped)
33 | (CapabilitiesDropped, SeccompApplied)
34 | (SeccompApplied, LandlockApplied)
35 | (LandlockApplied, Locked)
36 | (Privileged, Privileged)
37 | (CapabilitiesDropped, CapabilitiesDropped)
38 | (SeccompApplied, SeccompApplied)
39 | (LandlockApplied, LandlockApplied)
40 | (Locked, Locked)
41 )
42 }
43
44 fn is_terminal(&self) -> bool {
45 matches!(self, SecurityState::Locked)
46 }
47}
48
49#[cfg(test)]
50mod tests {
51 use super::*;
52
53 #[test]
54 fn test_valid_transitions() {
55 assert!(SecurityState::Privileged.can_transition_to(&SecurityState::CapabilitiesDropped));
56 assert!(
57 SecurityState::CapabilitiesDropped.can_transition_to(&SecurityState::SeccompApplied)
58 );
59 assert!(SecurityState::SeccompApplied.can_transition_to(&SecurityState::LandlockApplied));
60 assert!(SecurityState::LandlockApplied.can_transition_to(&SecurityState::Locked));
61 }
62
63 #[test]
64 fn test_self_transitions() {
65 assert!(SecurityState::Privileged.can_transition_to(&SecurityState::Privileged));
66 assert!(SecurityState::CapabilitiesDropped
67 .can_transition_to(&SecurityState::CapabilitiesDropped));
68 assert!(SecurityState::SeccompApplied.can_transition_to(&SecurityState::SeccompApplied));
69 assert!(SecurityState::LandlockApplied.can_transition_to(&SecurityState::LandlockApplied));
70 assert!(SecurityState::Locked.can_transition_to(&SecurityState::Locked));
71 }
72
73 #[test]
74 fn test_invalid_transitions() {
75 assert!(!SecurityState::Privileged.can_transition_to(&SecurityState::SeccompApplied));
77 assert!(!SecurityState::Privileged.can_transition_to(&SecurityState::LandlockApplied));
78 assert!(!SecurityState::Privileged.can_transition_to(&SecurityState::Locked));
79 assert!(
80 !SecurityState::CapabilitiesDropped.can_transition_to(&SecurityState::LandlockApplied)
81 );
82 assert!(!SecurityState::CapabilitiesDropped.can_transition_to(&SecurityState::Locked));
83 assert!(!SecurityState::SeccompApplied.can_transition_to(&SecurityState::Locked));
84
85 assert!(!SecurityState::CapabilitiesDropped.can_transition_to(&SecurityState::Privileged));
87 assert!(!SecurityState::SeccompApplied.can_transition_to(&SecurityState::Privileged));
88 assert!(
89 !SecurityState::SeccompApplied.can_transition_to(&SecurityState::CapabilitiesDropped)
90 );
91 assert!(!SecurityState::LandlockApplied.can_transition_to(&SecurityState::Privileged));
92 assert!(
93 !SecurityState::LandlockApplied.can_transition_to(&SecurityState::CapabilitiesDropped)
94 );
95 assert!(!SecurityState::LandlockApplied.can_transition_to(&SecurityState::SeccompApplied));
96 assert!(!SecurityState::Locked.can_transition_to(&SecurityState::LandlockApplied));
97 assert!(!SecurityState::Locked.can_transition_to(&SecurityState::SeccompApplied));
98 }
99
100 #[test]
101 fn test_terminal_state() {
102 assert!(!SecurityState::Privileged.is_terminal());
103 assert!(!SecurityState::CapabilitiesDropped.is_terminal());
104 assert!(!SecurityState::SeccompApplied.is_terminal());
105 assert!(!SecurityState::LandlockApplied.is_terminal());
106 assert!(SecurityState::Locked.is_terminal());
107 }
108}