use serde::{Deserialize, Serialize};
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum SmtpdEvent {
Connect {
client_ip: String,
client_hostname: String,
port: Option<u16>,
},
Disconnect {
client_ip: String,
client_hostname: String,
port: Option<u16>,
command_stats: Option<CommandStats>,
},
LostConnection {
client_ip: String,
client_hostname: String,
last_command: Option<String>,
},
Timeout {
client_ip: String,
client_hostname: String,
last_command: Option<String>,
},
ClientAssignment {
queue_id: String,
client_ip: String,
client_hostname: String,
port: Option<u16>,
},
Auth {
method: String,
username: String,
success: bool,
failure_reason: Option<String>,
},
Reject {
reason: String,
code: Option<u16>,
reject_type: RejectType,
from: Option<String>,
to: Option<String>,
client_ip: Option<String>,
client_hostname: Option<String>,
},
NoQueueFilter {
client_ip: String,
client_hostname: String,
filter_info: String,
filter_target: String,
},
Helo {
hostname: String,
client_ip: Option<String>,
client_hostname: Option<String>,
},
Accept {
from: Option<String>,
to: Vec<String>,
size: Option<u64>,
queue_id: Option<String>,
},
ProtocolViolation {
client_ip: String,
client_hostname: String,
violation_type: String,
details: String,
},
SystemWarning {
warning_type: String,
message: String,
client_info: Option<ClientInfo>,
},
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct CommandStats {
pub ehlo: Option<u32>,
pub helo: Option<u32>,
pub mail: Option<u32>,
pub rcpt: Option<u32>,
pub data: Option<u32>,
pub bdat: Option<u32>,
pub quit: Option<u32>,
pub commands: Option<u32>,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub enum RejectType {
NoQueue,
Queued,
Unknown,
}
#[derive(Debug, Clone, Serialize, Deserialize)]
pub struct ClientInfo {
pub ip: String,
pub hostname: String,
pub port: Option<u16>,
}
impl SmtpdEvent {
pub fn event_type(&self) -> &'static str {
match self {
SmtpdEvent::Connect { .. } => "connect",
SmtpdEvent::Disconnect { .. } => "disconnect",
SmtpdEvent::LostConnection { .. } => "lost_connection",
SmtpdEvent::Timeout { .. } => "timeout",
SmtpdEvent::ClientAssignment { .. } => "client_assignment",
SmtpdEvent::Auth { .. } => "auth",
SmtpdEvent::Reject { .. } => "reject",
SmtpdEvent::NoQueueFilter { .. } => "noqueue_filter",
SmtpdEvent::Helo { .. } => "helo",
SmtpdEvent::Accept { .. } => "accept",
SmtpdEvent::ProtocolViolation { .. } => "protocol_violation",
SmtpdEvent::SystemWarning { .. } => "system_warning",
}
}
pub fn queue_id(&self) -> Option<&str> {
match self {
SmtpdEvent::ClientAssignment { queue_id, .. } => Some(queue_id),
SmtpdEvent::Accept { queue_id, .. } => queue_id.as_deref(),
_ => None,
}
}
}