aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/smtp.rs34
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"))
}
}
XMR address: 854DmXNrxULU3ZFJVs4Wc8PFhbq29RhqHhY8W6cdWrtFN3qmooKyyeYPcDzZTNRxphhJ5UzASQfAdEMwSteVqymk28aLhqj