Skip to content

Commit d162918

Browse files
docs: add docs for sasl
1 parent a7c6633 commit d162918

File tree

3 files changed

+50
-4
lines changed

3 files changed

+50
-4
lines changed

src/response/parser/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,7 +25,7 @@ pub(crate) fn parse<'a>(input: &'a [u8], request: &Command) -> IResult<&'a [u8],
2525

2626
#[cfg(feature = "sasl")]
2727
match request {
28-
Command::Base64(_) => match rfc1734::auth(input) {
28+
Command::Base64(_) | Command::Auth => match rfc1734::auth(input) {
2929
Ok((input, base64_challenge)) => {
3030
if let Ok(challenge) = crate::base64::decode(base64_challenge) {
3131
return Ok((input, Response::Challenge(challenge.into())));

src/sasl.rs

Lines changed: 46 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,46 @@
1+
/*!
2+
# Sasl
3+
4+
This module provides support for SASL (Simple Authentication and Security Layer), as specified in [RFC4422](https://datatracker.ietf.org/doc/html/rfc4422)
5+
6+
It allows one to use these mechanisms to authenticate with a Pop3 compatible server and implement more mechanisms if they are needed.
7+
8+
The mechanisms for PLAIN and XOAUTH2 are already present as they are commonly used.
9+
10+
Implementing a mechanism is simple:
11+
12+
```rust,ignore
13+
pub struct MyAuthenticator {
14+
username: String,
15+
secret_token: String,
16+
}
17+
18+
impl Authenticator for MyAuthenticator {
19+
fn mechanism(&self) -> &str {
20+
"SUPER_COOL_MECHANISM"
21+
}
22+
23+
fn auth(&self) -> Option<String> {
24+
// Specify your cool format
25+
Some(format!("\x00{}\x00{}", self.username, self.secret_token))
26+
}
27+
28+
async fn handle<'a, S: Read + Write + Unpin + Send>(
29+
&self,
30+
communicator: Communicator<'a, S>,
31+
) -> Result<()> {
32+
let challenge = communicator.next_challenge().await?;
33+
34+
let response = mechanism_lib::handle_challenge(challenge)?;
35+
36+
communicator.send(response).await?;
37+
38+
Ok(())
39+
}
40+
}
41+
```
42+
*/
43+
144
use std::collections::VecDeque;
245

346
use async_trait::async_trait;
@@ -79,7 +122,9 @@ pub trait Authenticator {
79122
None
80123
}
81124

82-
/// Get
125+
/// Handle a handshake conversation between the server and the client.
126+
///
127+
/// The [Communicator] allows you to send and receive data needed for authentication
83128
async fn handle<'a, S: Read + Write + Unpin + Send>(
84129
&self,
85130
_communicator: Communicator<'a, S>,

src/test.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ use tokio::net::TcpStream;
1010

1111
use crate::{
1212
response::{capability::Capability, list::ListResponse, types::DataType, uidl::UidlResponse},
13-
sasl::PlainAuthenticator,
1413
ClientState,
1514
};
1615

@@ -98,6 +97,7 @@ async fn e2e_login() {
9897

9998
#[cfg_attr(feature = "runtime-tokio", tokio::test)]
10099
#[cfg_attr(feature = "runtime-async-std", async_std::test)]
100+
#[cfg(feature = "sasl")]
101101
async fn e2e_auth() {
102102
let client_info = create_client_info();
103103

@@ -106,7 +106,8 @@ async fn e2e_auth() {
106106

107107
let mut client = super::connect_plain((server, port)).await.unwrap();
108108

109-
let plain_auth = PlainAuthenticator::new(client_info.username, client_info.password);
109+
let plain_auth =
110+
crate::sasl::PlainAuthenticator::new(client_info.username, client_info.password);
110111

111112
client.auth(plain_auth).await.unwrap();
112113

0 commit comments

Comments
 (0)