1#[cfg(feature = "std")]
20use std::fmt;
21#[cfg(not(feature = "std"))]
22use core::fmt;
23
24#[cfg(not(feature = "std"))]
25use alloc::string::String;
26
27#[derive(Clone, Eq, PartialEq)]
28pub struct ScramRuntimeError
29{
30 pub err_code: ScramErrorCode,
32 pub err_serv: ScramServerError,
35 pub message: String,
37}
38
39impl ScramRuntimeError
40{
41 pub
42 fn new(err_code: ScramErrorCode, err_serv: ScramServerError, msg: String) -> Self
43 {
44 return ScramRuntimeError{err_code: err_code, err_serv: err_serv, message: msg};
45 }
46
47 pub
49 fn serv_err_value(&self) -> &str
50 {
51 return
52 match self.err_serv
53 {
54 ScramServerError::None => "e=other-error",
55 ScramServerError::InvalidEncoding => "e=invalid-encoding",
56 ScramServerError::ExtensionsNotSupported => "e=extensions-not-supported",
57 ScramServerError::InvalidProof => "e=invalid-proof",
58 ScramServerError::ChannelBindingsDontMatch => "e=channel-bindings-dont-match",
59 ScramServerError::ServerDoesSupportChannelBinding => "e=server-does-support-channel-binding",
60 ScramServerError::ChannelBindingNotSupported => "e=channel-binding-not-supported",
61 ScramServerError::UnsupportedChannelBindingType => "e=unsupported-channel-binding-type",
62 ScramServerError::UnknownUser => "e=unknown-user",
63 ScramServerError::InvalidUsernameEncoding => "e=invalid-username-encoding",
64 ScramServerError::NoResources => "e=no-resources",
65 ScramServerError::OtherError => "e=other-error"
66 };
67 }
68}
69
70impl fmt::Display for ScramRuntimeError
71{
72 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
73 {
74 write!(f, "scram: {}, {}", self.err_code, self.message)
75 }
76}
77impl fmt::Debug for ScramRuntimeError
78{
79 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
80 {
81 write!(f, "scram: {}, {}", self.err_code, self.message)
82 }
83}
84
85#[repr(u32)]
86#[derive(Copy, Clone, PartialEq, Eq)]
87pub enum ScramServerError
88{
89 None,
91 InvalidEncoding,
92
93 ExtensionsNotSupported,
95 InvalidProof,
96 ChannelBindingsDontMatch,
97 ServerDoesSupportChannelBinding,
98 ChannelBindingNotSupported,
99 UnsupportedChannelBindingType,
100 UnknownUser,
103 InvalidUsernameEncoding,
104 NoResources,
105
106 OtherError
108}
109
110
111
112impl fmt::Display for ScramServerError
113{
114 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
115 {
116 let d =
117 match *self
118 {
119 Self::None =>
120 "None",
121 Self::InvalidEncoding =>
122 "Invalid Encoding",
123 Self::ExtensionsNotSupported =>
124 "Extension Not Supported, unrecognized 'm' value",
125 Self::InvalidProof =>
126 "Invalid Proof",
127 Self::ChannelBindingsDontMatch =>
128 "Channel Bindings Don't Match",
129 Self::ServerDoesSupportChannelBinding =>
130 "Server Does Support Channel Binding",
131 Self::ChannelBindingNotSupported =>
132 "Channel Binding Not Supported",
133 Self::UnsupportedChannelBindingType =>
134 "Unsupported Channel Binding Type",
135 Self::UnknownUser =>
136 "Unknown User",
137 Self::InvalidUsernameEncoding =>
138 "Invalid Username Enconding",
139 Self::NoResources =>
140 "No Resources",
141 Self::OtherError =>
142 "Other Error"
143 };
144
145 return write!(f, "{}", d);
146 }
147}
148impl fmt::Debug for ScramServerError
149{
150 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
151 {
152 let d =
153 match *self
154 {
155 Self::None =>
156 "None",
157 Self::InvalidEncoding =>
158 "Invalid Encoding",
159 Self::ExtensionsNotSupported =>
160 "Extension Not Supported, unrecognized 'm' value",
161 Self::InvalidProof =>
162 "Invalid Proof",
163 Self::ChannelBindingsDontMatch =>
164 "Channel Bindings Don't Match",
165 Self::ServerDoesSupportChannelBinding =>
166 "Server Does Support Channel Binding",
167 Self::ChannelBindingNotSupported =>
168 "Channel Binding Not Supported",
169 Self::UnsupportedChannelBindingType =>
170 "Unsupported Channel Binding Type",
171 Self::UnknownUser =>
172 "Unknown User",
173 Self::InvalidUsernameEncoding =>
174 "Invalid Username Enconding",
175 Self::NoResources =>
176 "No Resources",
177 Self::OtherError =>
178 "Other Error"
179 };
180
181 return write!(f, "{}", d);
182 }
183}
184
185impl From<&str> for ScramServerError
186{
187 fn from(value: &str) -> Self
188 {
189 match value
190 {
191 "invalid-encoding" =>
192 Self::InvalidEncoding,
193 "extensions-not-supported" =>
194 Self::ExtensionsNotSupported,
195 "invalid-proof" =>
196 Self::InvalidProof,
197 "channel-bindings-dont-match" =>
198 Self::ChannelBindingsDontMatch,
199 "server-does-support-channel-binding" =>
200 Self::ServerDoesSupportChannelBinding,
201 "channel-binding-not-supported" =>
202 Self::ChannelBindingNotSupported,
203 "unsupported-channel-binding-type" =>
204 Self::UnsupportedChannelBindingType,
205 "unknown-user" =>
206 Self::UnknownUser,
207 "invalid-username-encoding" =>
208 Self::InvalidUsernameEncoding,
209 "no-resources" =>
210 Self::NoResources,
211 "other-error" => Self::OtherError,
212 _ => Self::OtherError,
213 }
214 }
215}
216
217#[repr(u32)]
219#[derive(Debug, Copy, Clone, Eq, PartialEq)]
220pub enum ScramErrorCode
221{
222 InternalError,
224
225 VerificationError,
227
228 ExternalError,
230
231 MalformedScramMsg,
233
234 FeatureNotSupported,
236
237 ProtocolViolation,
239
240 AuthSeqCompleted,
242
243 ClientSide,
245
246 ChanBindNotImplemented
248}
249
250impl fmt::Display for ScramErrorCode
251{
252 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
253 {
254 match *self
255 {
256 Self::InternalError => write!(f, "Internal Server Error"),
257 Self::VerificationError => write!(f, "Data Verification Error"),
258 Self::ExternalError => write!(f, "External Server Error"),
259 Self::MalformedScramMsg => write!(f, "Malformed Scram Message"),
260 Self::FeatureNotSupported => write!(f, "Feature is not supported"),
261 Self::ProtocolViolation => write!(f, "Protocol Violation"),
262 Self::AuthSeqCompleted => write!(f, "Completed!"),
263 Self::ClientSide => write!(f, "Server reported error"),
264 Self::ChanBindNotImplemented => write!(f, "Channel bind not implemented"),
265 }
266 }
267}
268
269pub type ScramResult<T> = Result<T, ScramRuntimeError>;
271
272#[cfg(feature = "std")]
273#[macro_export]
274macro_rules! scram_error
275{
276 ($src:expr, $serv_err:expr, $($arg:tt)*) => (
277 return std::result::Result::Err($crate::ScramRuntimeError::new($src, $serv_err, format!($($arg)*)))
278 )
279}
280
281#[cfg(not(feature = "std"))]
282#[macro_export]
283macro_rules! scram_error
284{
285 ($src:expr, $serv_err:expr, $($arg:tt)*) => (
286 return core::result::Result::Err($crate::ScramRuntimeError::new($src, $serv_err, alloc::format!($($arg)*)))
287 )
288}
289
290#[cfg(feature = "std")]
291#[macro_export]
292macro_rules! scram_ierror
293{
294 ($src:expr, $($arg:tt)*) => (
295 return std::result::Result::Err($crate::ScramRuntimeError::new($src, $crate::ScramServerError::None, format!($($arg)*)))
296 )
297}
298
299#[cfg(not(feature = "std"))]
300#[macro_export]
301macro_rules! scram_ierror
302{
303 ($src:expr, $($arg:tt)*) => (
304 return core::result::Result::Err($crate::ScramRuntimeError::new($src, $crate::ScramServerError::None, alloc::format!($($arg)*)))
305 )
306}
307
308#[cfg(feature = "std")]
309#[macro_export]
310macro_rules! scram_ierror_map
311{
312 ($src:expr, $($arg:tt)*) => (
313 $crate::ScramRuntimeError::new($src, $crate::ScramServerError::None, format!($($arg)*))
314 )
315}
316
317#[cfg(not(feature = "std"))]
318#[macro_export]
319macro_rules! scram_ierror_map
320{
321 ($src:expr, $($arg:tt)*) => (
322 $crate::ScramRuntimeError::new($src, $crate::ScramServerError::None, alloc::format!($($arg)*))
323 )
324}
325
326#[cfg(feature = "std")]
327#[macro_export]
328macro_rules! scram_error_map
329{
330 ($src:expr, $serv_err:expr, $($arg:tt)*) => (
331 $crate::ScramRuntimeError::new($src, $serv_err, format!($($arg)*))
332 )
333}
334
335
336#[cfg(not(feature = "std"))]
337#[macro_export]
338macro_rules! scram_error_map
339{
340 ($src:expr, $serv_err:expr, $($arg:tt)*) => (
341 $crate::ScramRuntimeError::new($src, $serv_err, alloc::format!($($arg)*))
342 )
343}
344