1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
use crate::error::SessionError;
use crate::error::SessionError::NoSecurityLayer;
use crate::session::{SessionData, StepResult};
use std::io::Write;

/// Trait implemented to be one party in an authentication exchange
///
/// This trait is used irrespectively of the side of the authentication exchange, i.e. it gets
/// used both on the client side and on the server side. If the Mechanism being implemented is not
/// symmetric but has different behaviour depending on the side an Implementation should define two
/// distinct types representing the client and server side:
///
/// ```rust
/// # use std::io::Write;
/// # use rsasl::mechanism::Authentication;
/// # use rsasl::session::{SessionData, StepResult};
/// // Data required for both sides
/// struct Common {
///     step: usize,
///     hash: [u8; 64],
/// }
/// #[repr(transparent)]
/// pub struct Client(Common);
/// #[repr(transparent)]
/// pub struct Server(Common);
///
/// impl Authentication for Client {
///     fn step(&mut self, session: &mut SessionData, input: Option<&[u8]>, writer: &mut dyn Write) -> StepResult {
///         match self.0.step {
///             0 => { }
///             _ => { }
///         }
///         # unimplemented!()
///     }
/// }
/// impl Authentication for Server {
///     fn step(&mut self, session: &mut SessionData, input: Option<&[u8]>, writer: &mut dyn Write) -> StepResult {
///         # unimplemented!()
///     }
/// }
/// ```
///
/// And register the two types separately
pub trait Authentication {
    /// Do a single step of authentication with the other party
    fn step(
        &mut self,
        session: &mut SessionData,
        input: Option<&[u8]>,
        writer: &mut dyn Write,
    ) -> StepResult;

    // TODO: Document the problems with SASL security layers before release
    fn encode(&mut self, _input: &[u8]) -> Result<Box<[u8]>, SessionError> {
        Err(NoSecurityLayer)
    }
    fn decode(&mut self, _input: &[u8]) -> Result<Box<[u8]>, SessionError> {
        Err(NoSecurityLayer)
    }
}