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