use crate::events::SmtpdEvent;
use serde_json;
pub fn format_smtpd_event(smtpd_event: &SmtpdEvent) -> serde_json::Map<String, serde_json::Value> {
let mut event_data = serde_json::Map::new();
match smtpd_event {
SmtpdEvent::Connect {
client_ip,
client_hostname,
port,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("connect".to_string()),
);
event_data.insert(
"client_ip".to_string(),
serde_json::Value::String(client_ip.clone()),
);
event_data.insert(
"client_hostname".to_string(),
serde_json::Value::String(client_hostname.clone()),
);
if let Some(port_num) = port {
event_data.insert(
"port".to_string(),
serde_json::Value::Number(serde_json::Number::from(*port_num)),
);
}
}
SmtpdEvent::Disconnect {
client_ip,
client_hostname,
port,
command_stats,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("disconnect".to_string()),
);
event_data.insert(
"client_ip".to_string(),
serde_json::Value::String(client_ip.clone()),
);
event_data.insert(
"client_hostname".to_string(),
serde_json::Value::String(client_hostname.clone()),
);
if let Some(port_num) = port {
event_data.insert(
"port".to_string(),
serde_json::Value::Number(serde_json::Number::from(*port_num)),
);
}
if let Some(stats) = command_stats {
let mut stats_obj = serde_json::Map::new();
if let Some(ehlo) = stats.ehlo {
stats_obj.insert(
"ehlo".to_string(),
serde_json::Value::Number(serde_json::Number::from(ehlo)),
);
}
if let Some(mail) = stats.mail {
stats_obj.insert(
"mail".to_string(),
serde_json::Value::Number(serde_json::Number::from(mail)),
);
}
if let Some(rcpt) = stats.rcpt {
stats_obj.insert(
"rcpt".to_string(),
serde_json::Value::Number(serde_json::Number::from(rcpt)),
);
}
if let Some(commands) = stats.commands {
stats_obj.insert(
"commands".to_string(),
serde_json::Value::Number(serde_json::Number::from(commands)),
);
}
event_data.insert(
"command_stats".to_string(),
serde_json::Value::Object(stats_obj),
);
}
}
SmtpdEvent::ClientAssignment {
queue_id,
client_ip,
client_hostname,
port,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("client_assignment".to_string()),
);
event_data.insert(
"queue_id".to_string(),
serde_json::Value::String(queue_id.clone()),
);
event_data.insert(
"client_ip".to_string(),
serde_json::Value::String(client_ip.clone()),
);
event_data.insert(
"client_hostname".to_string(),
serde_json::Value::String(client_hostname.clone()),
);
if let Some(port_num) = port {
event_data.insert(
"port".to_string(),
serde_json::Value::Number(serde_json::Number::from(*port_num)),
);
}
}
SmtpdEvent::LostConnection {
client_ip,
client_hostname,
last_command,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("lost_connection".to_string()),
);
event_data.insert(
"client_ip".to_string(),
serde_json::Value::String(client_ip.clone()),
);
event_data.insert(
"client_hostname".to_string(),
serde_json::Value::String(client_hostname.clone()),
);
if let Some(cmd) = last_command {
event_data.insert(
"last_command".to_string(),
serde_json::Value::String(cmd.clone()),
);
}
}
SmtpdEvent::Timeout {
client_ip,
client_hostname,
last_command,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("timeout".to_string()),
);
event_data.insert(
"client_ip".to_string(),
serde_json::Value::String(client_ip.clone()),
);
event_data.insert(
"client_hostname".to_string(),
serde_json::Value::String(client_hostname.clone()),
);
if let Some(cmd) = last_command {
event_data.insert(
"last_command".to_string(),
serde_json::Value::String(cmd.clone()),
);
}
}
SmtpdEvent::NoQueueFilter {
client_ip,
client_hostname,
filter_info,
filter_target,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("noqueue_filter".to_string()),
);
event_data.insert(
"client_ip".to_string(),
serde_json::Value::String(client_ip.clone()),
);
event_data.insert(
"client_hostname".to_string(),
serde_json::Value::String(client_hostname.clone()),
);
event_data.insert(
"filter_info".to_string(),
serde_json::Value::String(filter_info.clone()),
);
event_data.insert(
"filter_target".to_string(),
serde_json::Value::String(filter_target.clone()),
);
}
SmtpdEvent::SystemWarning {
warning_type,
message,
client_info: _,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("system_warning".to_string()),
);
event_data.insert(
"warning_type".to_string(),
serde_json::Value::String(warning_type.clone()),
);
event_data.insert(
"message".to_string(),
serde_json::Value::String(message.clone()),
);
}
SmtpdEvent::Reject {
reason,
code,
reject_type,
from,
to,
client_ip,
client_hostname,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("reject".to_string()),
);
event_data.insert(
"reason".to_string(),
serde_json::Value::String(reason.clone()),
);
event_data.insert(
"reject_type".to_string(),
serde_json::Value::String(format!("{:?}", reject_type)),
);
if let Some(code_num) = code {
event_data.insert(
"code".to_string(),
serde_json::Value::Number(serde_json::Number::from(*code_num)),
);
}
if let Some(from_addr) = from {
event_data.insert(
"from".to_string(),
serde_json::Value::String(from_addr.clone()),
);
}
if let Some(to_addr) = to {
event_data.insert("to".to_string(), serde_json::Value::String(to_addr.clone()));
}
if let Some(ip) = client_ip {
event_data.insert(
"client_ip".to_string(),
serde_json::Value::String(ip.clone()),
);
}
if let Some(hostname) = client_hostname {
event_data.insert(
"client_hostname".to_string(),
serde_json::Value::String(hostname.clone()),
);
}
}
SmtpdEvent::Helo {
hostname,
client_ip,
client_hostname,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("helo".to_string()),
);
event_data.insert(
"helo_hostname".to_string(),
serde_json::Value::String(hostname.clone()),
);
if let Some(ip) = client_ip {
event_data.insert(
"client_ip".to_string(),
serde_json::Value::String(ip.clone()),
);
}
if let Some(hostname) = client_hostname {
event_data.insert(
"client_hostname".to_string(),
serde_json::Value::String(hostname.clone()),
);
}
}
SmtpdEvent::Auth {
method,
username,
success,
failure_reason,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("auth".to_string()),
);
event_data.insert(
"auth_method".to_string(),
serde_json::Value::String(method.clone()),
);
event_data.insert(
"username".to_string(),
serde_json::Value::String(username.clone()),
);
event_data.insert("success".to_string(), serde_json::Value::Bool(*success));
if let Some(reason) = failure_reason {
event_data.insert(
"failure_reason".to_string(),
serde_json::Value::String(reason.clone()),
);
}
}
SmtpdEvent::Accept {
from,
to,
size,
queue_id,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("accept".to_string()),
);
if let Some(from_addr) = from {
event_data.insert(
"from".to_string(),
serde_json::Value::String(from_addr.clone()),
);
}
if !to.is_empty() {
let to_array: Vec<serde_json::Value> = to
.iter()
.map(|addr| serde_json::Value::String(addr.clone()))
.collect();
event_data.insert("to".to_string(), serde_json::Value::Array(to_array));
}
if let Some(message_size) = size {
event_data.insert(
"size".to_string(),
serde_json::Value::Number(serde_json::Number::from(*message_size)),
);
}
if let Some(qid) = queue_id {
event_data.insert(
"queue_id".to_string(),
serde_json::Value::String(qid.clone()),
);
}
}
SmtpdEvent::ProtocolViolation {
client_ip,
client_hostname,
violation_type,
details,
} => {
event_data.insert(
"event_type".to_string(),
serde_json::Value::String("protocol_violation".to_string()),
);
event_data.insert(
"client_ip".to_string(),
serde_json::Value::String(client_ip.clone()),
);
event_data.insert(
"client_hostname".to_string(),
serde_json::Value::String(client_hostname.clone()),
);
event_data.insert(
"violation_type".to_string(),
serde_json::Value::String(violation_type.clone()),
);
event_data.insert(
"details".to_string(),
serde_json::Value::String(details.clone()),
);
}
}
event_data
}