1use crate::sasl;
2
3use anyhow::{anyhow, bail, Result};
4
5pub const ANONYMOUS: &str = "ANONYMOUS";
7
8pub struct AnonymousClient {
11 trace: String,
12}
13
14impl AnonymousClient {
15 pub fn new(trace: String) -> Self {
16 Self {
17 trace,
18 }
19 }
20}
21
22impl sasl::Client for AnonymousClient {
23 fn start(&mut self) -> Result<(String, Vec<u8>)> {
24 Ok((
25 ANONYMOUS.to_string(),
26 self.trace.clone().into_bytes(),
27 ))
28 }
29
30 fn next(&mut self, _challenge: &[u8]) -> Result<Vec<u8>> {
31 Err(anyhow!(sasl::ERR_UNEXPECTED_SERVER_CHALLENGE))
32 }
33}
34
35pub type AnonymousAuthenticator = Box<dyn Fn(&str) -> Result<()> + Send>;
37
38pub struct AnonymousServer {
41 done: bool,
42 authenticator: AnonymousAuthenticator,
43}
44
45impl AnonymousServer {
46 pub fn new(authenticator: AnonymousAuthenticator) -> Self {
47 Self {
48 done: false,
49 authenticator,
50 }
51 }
52}
53
54impl sasl::Server for AnonymousServer {
55 fn next(&mut self, response: Option<&[u8]>) -> Result<(Vec<u8>, bool)> {
56 if self.done {
57 bail!(sasl::ERR_UNEXPECTED_CLIENT_RESPONSE);
58 }
59
60 if response.is_none() {
62 return Ok((Vec::new(), false));
63 }
64 let response = response.unwrap();
65
66 self.done = true;
67
68 (self.authenticator)(std::str::from_utf8(response)?)?;
69 Ok((Vec::new(), true))
70 }
71}