|
1
|
use crate::{handle_starttls::handle_starttls, storage::MessageStorage}; |
|
2
|
use tokio::{ |
|
3
|
io::{AsyncBufReadExt, AsyncWriteExt, BufReader, BufWriter}, |
|
4
|
net::TcpStream, |
|
5
|
}; |
|
6
|
|
|
7
|
pub async fn handle_unsecured_session(stream: &mut TcpStream, storage: Option<MessageStorage>) -> anyhow::Result<()> { |
|
8
|
let (reader, writer) = stream.split(); |
|
9
|
let mut reader = BufReader::new(reader); |
|
10
|
let mut writer = BufWriter::new(writer); |
|
11
|
let mut is_tls = false; |
|
12
|
let mut line = String::new(); |
|
13
|
while reader.read_line(&mut line).await? != 0 { |
|
14
|
let space_pos = line.find(" ").unwrap_or(line.len()); |
|
15
|
let (command, _) = line.split_at(space_pos); |
|
16
|
|
|
17
|
match command.trim().to_uppercase().as_ref() { |
|
18
|
"EHLO" | "HELO" => { |
|
19
|
writer.write_all(b"250-windmill Hello\r\n").await?; |
|
20
|
writer.write_all(b"250-STARTTLS\r\n").await?; |
|
21
|
writer.write_all(b"250 What you've got?\r\n").await?; |
|
22
|
writer.flush().await?; |
|
23
|
} |
|
24
|
"STARTTLS" => { |
|
25
|
writer.write_all(b"220 GO ON\r\n").await?; |
|
26
|
writer.flush().await?; |
|
27
|
is_tls = true; |
|
28
|
break; |
|
29
|
} |
|
30
|
"QUIT" => { |
|
31
|
writer.write_all(b"221 Have a nice day!\r\n").await?; |
|
32
|
writer.flush().await?; |
|
33
|
break; |
|
34
|
} |
|
35
|
"NOOP" => { |
|
36
|
writer.write_all(b"250 OK\r\n").await?; |
|
37
|
writer.flush().await?; |
|
38
|
} |
|
39
|
"MAIL" | "RCPT" | "DATA" | "RSET" => { |
|
40
|
writer |
|
41
|
.write_all(b"530 Must issue a STARTTLS command first\r\n") |
|
42
|
.await?; |
|
43
|
writer.flush().await?; |
|
44
|
} |
|
45
|
_ => { |
|
46
|
writer.write_all(b"500 Unknown command\r\n").await?; |
|
47
|
writer.flush().await?; |
|
48
|
} |
|
49
|
} |
|
50
|
|
|
51
|
line.clear(); |
|
52
|
} |
|
53
|
|
|
54
|
if is_tls { |
|
55
|
handle_starttls(stream, storage).await?; |
|
56
|
} |
|
57
|
|
|
58
|
Ok(()) |
|
59
|
} |