Skip to main content

io_smtp/rfc4954/
auth.rs

1//! The SMTP AUTH command (RFC 4954 §4).
2
3use alloc::{borrow::Cow, vec::Vec};
4
5use base64::{Engine, engine::general_purpose::STANDARD as base64};
6use secrecy::{ExposeSecret, SecretBox};
7
8/// The AUTH command (RFC 4954 §4).
9///
10/// Serializes to `AUTH <mechanism> [<base64-ir>]\r\n`.
11pub struct SmtpAuthCommand<'a> {
12    /// The SASL mechanism name as it appears on the wire (e.g. `"PLAIN"`).
13    pub mechanism: Cow<'a, str>,
14    /// Optional initial response (base64-encoded on serialization).
15    pub initial_response: Option<SecretBox<[u8]>>,
16}
17
18impl<'a> From<SmtpAuthCommand<'a>> for Vec<u8> {
19    fn from(cmd: SmtpAuthCommand<'a>) -> Vec<u8> {
20        let mut buf = Vec::new();
21
22        buf.extend_from_slice(b"AUTH ");
23        buf.extend_from_slice(cmd.mechanism.as_bytes());
24
25        if let Some(ir) = cmd.initial_response {
26            let data = ir.expose_secret();
27
28            if data.is_empty() {
29                buf.extend_from_slice(b" =");
30            } else {
31                buf.push(b' ');
32                buf.extend_from_slice(base64.encode(data).as_bytes());
33            }
34        }
35
36        buf.extend_from_slice(b"\r\n");
37        buf
38    }
39}