ipmi_rs/app/auth/
mod.rs

1mod get_channel_authentication_capabilities;
2use core::cmp::Ordering;
3
4pub use get_channel_authentication_capabilities::{
5    ChannelAuthenticationCapabilities, GetChannelAuthenticationCapabilities,
6};
7
8mod get_session_challenge;
9pub use get_session_challenge::{GetSessionChallenge, SessionChallenge};
10
11mod activate_session;
12pub use activate_session::{ActivateSession, BeginSessionInfo};
13
14mod get_channel_cipher_suites;
15pub use get_channel_cipher_suites::{ChannelCipherSuites, CipherSuite, GetChannelCipherSuites};
16
17#[derive(Debug, Clone)]
18pub enum AuthError {
19    /// A non-zero session ID was received at a stage where
20    /// non-zero session numbers are not allowed.
21    InvalidZeroSession,
22    /// An invalid auth type was encountered.
23    InvalidAuthType(u8),
24    /// An unknown privilege level was encountered.
25    InvalidPrivilegeLevel(u8),
26}
27
28#[derive(Debug, Clone, Copy, PartialEq)]
29pub enum AuthType {
30    None,
31    MD2,
32    MD5,
33    Key,
34}
35
36impl AuthType {
37    pub fn compare_strength(&self, other: &Self) -> Ordering {
38        if self == other {
39            Ordering::Equal
40        } else if self == &AuthType::None {
41            Ordering::Less
42        } else if other == &AuthType::None {
43            Ordering::Greater
44        } else if self == &AuthType::Key {
45            Ordering::Less
46        } else if other == &AuthType::Key {
47            Ordering::Greater
48        } else if self == &AuthType::MD2 {
49            Ordering::Less
50        } else {
51            Ordering::Greater
52        }
53    }
54}
55
56#[test]
57pub fn strength_ordering_individual() {
58    let gt_pairs = [
59        (AuthType::Key, AuthType::None),
60        (AuthType::MD2, AuthType::None),
61        (AuthType::MD5, AuthType::None),
62        (AuthType::MD2, AuthType::Key),
63        (AuthType::MD5, AuthType::Key),
64        (AuthType::MD5, AuthType::MD2),
65    ];
66
67    for (greater, lesser) in gt_pairs {
68        assert_eq!(greater.compare_strength(&lesser), Ordering::Greater);
69        assert_eq!(lesser.compare_strength(&greater), Ordering::Less);
70    }
71}
72
73#[test]
74pub fn strength_ordering() {
75    let types = [AuthType::None, AuthType::MD2, AuthType::MD5, AuthType::Key];
76
77    let max = types.into_iter().max_by(AuthType::compare_strength);
78    let min = types.into_iter().min_by(AuthType::compare_strength);
79
80    assert_eq!(max, Some(AuthType::MD5));
81    assert_eq!(min, Some(AuthType::None));
82}
83
84impl TryFrom<u8> for AuthType {
85    type Error = ();
86
87    fn try_from(value: u8) -> Result<Self, Self::Error> {
88        let value = match value {
89            0 => Self::None,
90            0x01 => Self::MD2,
91            0x02 => Self::MD5,
92            0x04 => Self::Key,
93            _ => return Err(()),
94        };
95
96        Ok(value)
97    }
98}
99
100impl From<AuthType> for u8 {
101    fn from(value: AuthType) -> Self {
102        match value {
103            AuthType::None => 0x00,
104            AuthType::MD2 => 0x01,
105            AuthType::MD5 => 0x02,
106            AuthType::Key => 0x04,
107        }
108    }
109}
110
111#[derive(Debug, Clone, Copy, PartialEq)]
112pub enum PrivilegeLevel {
113    Callback,
114    User,
115    Operator,
116    Administrator,
117    OemProperietary,
118}
119
120impl TryFrom<u8> for PrivilegeLevel {
121    type Error = ();
122
123    fn try_from(value: u8) -> Result<Self, Self::Error> {
124        let value = value & 0x0F;
125        let level = match value {
126            1 => Self::Callback,
127            2 => Self::User,
128            3 => Self::Operator,
129            4 => Self::Administrator,
130            5 => Self::OemProperietary,
131            _ => return Err(()),
132        };
133        Ok(level)
134    }
135}
136
137impl From<PrivilegeLevel> for u8 {
138    fn from(value: PrivilegeLevel) -> Self {
139        match value {
140            PrivilegeLevel::Callback => 1,
141            PrivilegeLevel::User => 2,
142            PrivilegeLevel::Operator => 3,
143            PrivilegeLevel::Administrator => 4,
144            PrivilegeLevel::OemProperietary => 5,
145        }
146    }
147}