diff options
Diffstat (limited to 'src/smtp.rs')
| -rw-r--r-- | src/smtp.rs | 34 |
1 files changed, 31 insertions, 3 deletions
diff --git a/src/smtp.rs b/src/smtp.rs index 6614897..2ab79f8 100644 --- a/src/smtp.rs +++ b/src/smtp.rs @@ -30,6 +30,7 @@ impl SmtpServer { addr, state: SessionState::default(), client_host: String::new(), + from: None, }; spawn(session.run(stream)); } @@ -41,6 +42,7 @@ struct SessionHandler { addr: SocketAddr, state: SessionState, client_host: String, + from: Option<String>, } impl SessionHandler { @@ -81,21 +83,36 @@ impl SessionHandler { async fn apply(&mut self, command: Command) -> Result<Reply> { match &command { Command::HELO(hostname) => self.helo(hostname).await, + Command::MAIL(from) => self.mail(from).await, } } /// HELO resets buffers async fn helo(&mut self, hostname: &str) -> Result<Reply> { self.client_host = String::from(hostname); - self.state = SessionState::NextState; + self.state = SessionState::Normal; + self.from = None; Ok(Reply::Completed(String::from(SERVER_NAME))) } + + /// TODO: Validate email address + /// MAIL resets buffers + async fn mail(&mut self, from: &str) -> Result<Reply> { + if from.is_empty() { + return Ok(Reply::InvalidParameter); + } + + self.from = Some(String::from(from)); + self.state = SessionState::MailTransaction; + + Ok(Reply::Completed(String::from("Ok"))) + } } enum SessionState { WaitingHelo, - /// This is a dev state - NextState, + MailTransaction, + Normal, } impl Default for SessionState { @@ -108,6 +125,7 @@ enum Reply { Ready(String), Completed(String), InvalidCommand, + InvalidParameter, } impl ToString for Reply { @@ -116,12 +134,14 @@ impl ToString for Reply { Reply::Ready(hostname) => format!("220 {}", hostname), Reply::Completed(hostname) => format!("250 {}", hostname), Reply::InvalidCommand => format!("500 Command not recognized"), + Reply::InvalidParameter => format!("501 Parameter error"), } } } enum Command { HELO(String), + MAIL(String), } impl TryFrom<&str> for Command { @@ -132,6 +152,14 @@ impl TryFrom<&str> for Command { return Ok(Command::HELO(String::from(&value[5..]))); } + if value.len() >= 11 + && value.to_lowercase().starts_with("mail from:<") + && value.contains('>') + { + let from = &value[11..value.find('>').unwrap()]; + return Ok(Command::MAIL(String::from(from))); + } + Err(anyhow::format_err!("Invalid command")) } } |
