rust_smtp_server/
server.rs

1use crate::backend::{
2    Backend,
3    Session,
4};
5use crate::conn::Conn;
6use crate::parse::parse_cmd;
7use std::pin::Pin;
8use std::sync::Arc;
9
10
11use anyhow::Result;
12use tokio::sync::Mutex;
13use std::time::Duration;
14
15use tokio::io::{self, BufWriter, AsyncBufReadExt, AsyncReadExt};
16use tokio::net::{TcpListener, TcpStream};
17use tokio_rustls::TlsAcceptor;
18
19
20const ERR_TCP_AND_LMTP: &str = "smtp: cannot start LMTP server listening on a TCP socket";
21
22pub struct Server<B: Backend> {
23    pub addr: String,
24    pub tls_acceptor: Option<TlsAcceptor>,
25
26    pub domain: String,
27    pub max_recipients: usize,
28    pub max_message_bytes: usize,
29    pub max_line_length: usize,
30    pub allow_insecure_auth: bool,
31    pub strict: bool,
32
33    pub read_timeout: Duration,
34    pub write_timeout: Duration,
35
36    pub enable_smtputf8: bool,
37    pub enable_requiretls: bool,
38    pub enable_binarymime: bool,
39
40    pub auth_disabled: bool,
41
42    pub backend: B,
43
44    pub caps: Vec<String>,
45
46    //pub listeners: Mutex<Vec<TcpListener>>,
47
48    //pub conns: HashMap<String, Arc<Mutex<Conn<B, S>>>>,
49}
50
51impl<B: Backend> Server<B> {
52    pub fn new(be: B) -> Self {
53        return Server{
54            addr: String::new(),
55            tls_acceptor: None,
56            domain: String::new(),
57            max_recipients: 0,
58            max_message_bytes: 0,
59            max_line_length: 2000,
60            allow_insecure_auth: true,
61            strict: false,
62            read_timeout: Duration::from_secs(0),
63            write_timeout: Duration::from_secs(0),
64            enable_smtputf8: false,
65            enable_requiretls: false,
66            enable_binarymime: false,
67            auth_disabled: false,
68            backend: be,
69            caps: vec!["PIPELINING".to_string(), "8BITMIME".to_string(), "ENHANCEDSTATUSCODES".to_string(), "CHUNKING".to_string()],
70            //listeners: Mutex::new(vec![]),
71        }
72    }
73
74    pub async fn serve(self, l: TcpListener) -> Result<()> {
75        let mut server = Arc::new(self);
76        loop {
77            match l.accept().await {
78                Ok((conn, _)) => {
79                    let mut server = server.clone();
80                    tokio::spawn(async move {
81                        if let Err(err) = server.handle_conn(Conn::new(conn, server.max_line_length)).await {
82                            println!("Error: {}", err);
83                        }
84                    });
85                }
86                Err(e) => {
87                    println!("Error: {}", e);
88                }
89            }
90        }
91    }
92
93    pub async fn handle_conn(&self, mut c: Conn<B>) -> Result<()> {
94        c.greet(self.domain.clone()).await;
95
96        let mut buf_reader = io::BufReader::new(c.text.conn.clone());
97
98        loop {
99            let mut line = String::new();
100            match buf_reader.read_line(&mut line).await {
101                Ok(0) => {
102                    return Ok(());
103                }
104                Ok(_) => {
105                    match parse_cmd(line) {
106                        Ok((cmd, arg)) => {
107                            c.handle(cmd, arg, self).await;
108                        }
109                        Err(err) => {
110                            println!("Error: {}", err);
111                            c.write_response(501, [5,5,2], &["Bad command"]).await;
112                            continue;
113                        }
114                    }
115                }
116                Err(err) => {
117                    match err.kind() {
118                        std::io::ErrorKind::TimedOut => {
119                            c.write_response(221, [2,4,2], &["Idle timeout, bye bye"]).await;
120                            return Ok(());
121                        }
122                        _ => {
123                            c.write_response(221, [2,4,0], &["Connection error, sorry"]).await;
124                            return Err(err.into());
125                        }
126                    }
127                }
128            }
129        }
130    }
131
132    pub async fn listen_and_serve(self) -> Result<()> {
133        let l = TcpListener::bind(&self.addr).await?;
134        self.serve(l).await
135    }
136
137    /*
138    pub async fn listen_and_serve_tls(&mut self) -> Result<()> {
139        let tls = self.server.tls_acceptor.as_ref().unwrap();
140        let l = TcpListener::bind(&self.server.addr).await?;
141        let l = tls.accept(l)?;
142        self.serve(l).await
143    }
144    */
145}