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!(
67 SecurityState::CapabilitiesDropped
68 .can_transition_to(&SecurityState::CapabilitiesDropped)
69 );
70 assert!(SecurityState::SeccompApplied.can_transition_to(&SecurityState::SeccompApplied));
71 assert!(SecurityState::LandlockApplied.can_transition_to(&SecurityState::LandlockApplied));
72 assert!(SecurityState::Locked.can_transition_to(&SecurityState::Locked));
73 }
74
75 #[test]
76 fn test_invalid_transitions() {
77 assert!(!SecurityState::Privileged.can_transition_to(&SecurityState::SeccompApplied));
79 assert!(!SecurityState::Privileged.can_transition_to(&SecurityState::LandlockApplied));
80 assert!(!SecurityState::Privileged.can_transition_to(&SecurityState::Locked));
81 assert!(
82 !SecurityState::CapabilitiesDropped
83 .can_transition_to(&SecurityState::LandlockApplied)
84 );
85 assert!(!SecurityState::CapabilitiesDropped.can_transition_to(&SecurityState::Locked));
86 assert!(!SecurityState::SeccompApplied.can_transition_to(&SecurityState::Locked));
87
88 assert!(!SecurityState::CapabilitiesDropped.can_transition_to(&SecurityState::Privileged));
90 assert!(!SecurityState::SeccompApplied.can_transition_to(&SecurityState::Privileged));
91 assert!(
92 !SecurityState::SeccompApplied.can_transition_to(&SecurityState::CapabilitiesDropped)
93 );
94 assert!(!SecurityState::LandlockApplied.can_transition_to(&SecurityState::Privileged));
95 assert!(
96 !SecurityState::LandlockApplied.can_transition_to(&SecurityState::CapabilitiesDropped)
97 );
98 assert!(!SecurityState::LandlockApplied.can_transition_to(&SecurityState::SeccompApplied));
99 assert!(!SecurityState::Locked.can_transition_to(&SecurityState::LandlockApplied));
100 assert!(!SecurityState::Locked.can_transition_to(&SecurityState::SeccompApplied));
101 }
102
103 #[test]
104 fn test_terminal_state() {
105 assert!(!SecurityState::Privileged.is_terminal());
106 assert!(!SecurityState::CapabilitiesDropped.is_terminal());
107 assert!(!SecurityState::SeccompApplied.is_terminal());
108 assert!(!SecurityState::LandlockApplied.is_terminal());
109 assert!(SecurityState::Locked.is_terminal());
110 }
111}