1use crate::events::SmtpdEvent;
2use serde_json;
3
4pub fn format_smtpd_event(smtpd_event: &SmtpdEvent) -> serde_json::Map<String, serde_json::Value> {
6 let mut event_data = serde_json::Map::new();
7
8 match smtpd_event {
9 SmtpdEvent::Connect {
10 client_ip,
11 client_hostname,
12 port,
13 } => {
14 event_data.insert(
15 "event_type".to_string(),
16 serde_json::Value::String("connect".to_string()),
17 );
18 event_data.insert(
19 "client_ip".to_string(),
20 serde_json::Value::String(client_ip.clone()),
21 );
22 event_data.insert(
23 "client_hostname".to_string(),
24 serde_json::Value::String(client_hostname.clone()),
25 );
26 if let Some(port_num) = port {
27 event_data.insert(
28 "port".to_string(),
29 serde_json::Value::Number(serde_json::Number::from(*port_num)),
30 );
31 }
32 }
33 SmtpdEvent::Disconnect {
34 client_ip,
35 client_hostname,
36 port,
37 command_stats,
38 } => {
39 event_data.insert(
40 "event_type".to_string(),
41 serde_json::Value::String("disconnect".to_string()),
42 );
43 event_data.insert(
44 "client_ip".to_string(),
45 serde_json::Value::String(client_ip.clone()),
46 );
47 event_data.insert(
48 "client_hostname".to_string(),
49 serde_json::Value::String(client_hostname.clone()),
50 );
51 if let Some(port_num) = port {
52 event_data.insert(
53 "port".to_string(),
54 serde_json::Value::Number(serde_json::Number::from(*port_num)),
55 );
56 }
57 if let Some(stats) = command_stats {
58 let mut stats_obj = serde_json::Map::new();
59 if let Some(ehlo) = stats.ehlo {
60 stats_obj.insert(
61 "ehlo".to_string(),
62 serde_json::Value::Number(serde_json::Number::from(ehlo)),
63 );
64 }
65 if let Some(mail) = stats.mail {
66 stats_obj.insert(
67 "mail".to_string(),
68 serde_json::Value::Number(serde_json::Number::from(mail)),
69 );
70 }
71 if let Some(rcpt) = stats.rcpt {
72 stats_obj.insert(
73 "rcpt".to_string(),
74 serde_json::Value::Number(serde_json::Number::from(rcpt)),
75 );
76 }
77 if let Some(commands) = stats.commands {
78 stats_obj.insert(
79 "commands".to_string(),
80 serde_json::Value::Number(serde_json::Number::from(commands)),
81 );
82 }
83 event_data.insert(
84 "command_stats".to_string(),
85 serde_json::Value::Object(stats_obj),
86 );
87 }
88 }
89 SmtpdEvent::ClientAssignment {
90 queue_id,
91 client_ip,
92 client_hostname,
93 port,
94 } => {
95 event_data.insert(
96 "event_type".to_string(),
97 serde_json::Value::String("client_assignment".to_string()),
98 );
99 event_data.insert(
100 "queue_id".to_string(),
101 serde_json::Value::String(queue_id.clone()),
102 );
103 event_data.insert(
104 "client_ip".to_string(),
105 serde_json::Value::String(client_ip.clone()),
106 );
107 event_data.insert(
108 "client_hostname".to_string(),
109 serde_json::Value::String(client_hostname.clone()),
110 );
111 if let Some(port_num) = port {
112 event_data.insert(
113 "port".to_string(),
114 serde_json::Value::Number(serde_json::Number::from(*port_num)),
115 );
116 }
117 }
118 SmtpdEvent::LostConnection {
119 client_ip,
120 client_hostname,
121 last_command,
122 } => {
123 event_data.insert(
124 "event_type".to_string(),
125 serde_json::Value::String("lost_connection".to_string()),
126 );
127 event_data.insert(
128 "client_ip".to_string(),
129 serde_json::Value::String(client_ip.clone()),
130 );
131 event_data.insert(
132 "client_hostname".to_string(),
133 serde_json::Value::String(client_hostname.clone()),
134 );
135 if let Some(cmd) = last_command {
136 event_data.insert(
137 "last_command".to_string(),
138 serde_json::Value::String(cmd.clone()),
139 );
140 }
141 }
142 SmtpdEvent::Timeout {
143 client_ip,
144 client_hostname,
145 last_command,
146 } => {
147 event_data.insert(
148 "event_type".to_string(),
149 serde_json::Value::String("timeout".to_string()),
150 );
151 event_data.insert(
152 "client_ip".to_string(),
153 serde_json::Value::String(client_ip.clone()),
154 );
155 event_data.insert(
156 "client_hostname".to_string(),
157 serde_json::Value::String(client_hostname.clone()),
158 );
159 if let Some(cmd) = last_command {
160 event_data.insert(
161 "last_command".to_string(),
162 serde_json::Value::String(cmd.clone()),
163 );
164 }
165 }
166 SmtpdEvent::NoQueueFilter {
167 client_ip,
168 client_hostname,
169 filter_info,
170 filter_target,
171 } => {
172 event_data.insert(
173 "event_type".to_string(),
174 serde_json::Value::String("noqueue_filter".to_string()),
175 );
176 event_data.insert(
177 "client_ip".to_string(),
178 serde_json::Value::String(client_ip.clone()),
179 );
180 event_data.insert(
181 "client_hostname".to_string(),
182 serde_json::Value::String(client_hostname.clone()),
183 );
184 event_data.insert(
185 "filter_info".to_string(),
186 serde_json::Value::String(filter_info.clone()),
187 );
188 event_data.insert(
189 "filter_target".to_string(),
190 serde_json::Value::String(filter_target.clone()),
191 );
192 }
193 SmtpdEvent::SystemWarning {
194 warning_type,
195 message,
196 client_info: _,
197 } => {
198 event_data.insert(
199 "event_type".to_string(),
200 serde_json::Value::String("system_warning".to_string()),
201 );
202 event_data.insert(
203 "warning_type".to_string(),
204 serde_json::Value::String(warning_type.clone()),
205 );
206 event_data.insert(
207 "message".to_string(),
208 serde_json::Value::String(message.clone()),
209 );
210 }
211 SmtpdEvent::Reject {
212 reason,
213 code,
214 reject_type,
215 from,
216 to,
217 client_ip,
218 client_hostname,
219 } => {
220 event_data.insert(
221 "event_type".to_string(),
222 serde_json::Value::String("reject".to_string()),
223 );
224 event_data.insert(
225 "reason".to_string(),
226 serde_json::Value::String(reason.clone()),
227 );
228 event_data.insert(
229 "reject_type".to_string(),
230 serde_json::Value::String(format!("{:?}", reject_type)),
231 );
232 if let Some(code_num) = code {
233 event_data.insert(
234 "code".to_string(),
235 serde_json::Value::Number(serde_json::Number::from(*code_num)),
236 );
237 }
238 if let Some(from_addr) = from {
239 event_data.insert(
240 "from".to_string(),
241 serde_json::Value::String(from_addr.clone()),
242 );
243 }
244 if let Some(to_addr) = to {
245 event_data.insert("to".to_string(), serde_json::Value::String(to_addr.clone()));
246 }
247 if let Some(ip) = client_ip {
248 event_data.insert(
249 "client_ip".to_string(),
250 serde_json::Value::String(ip.clone()),
251 );
252 }
253 if let Some(hostname) = client_hostname {
254 event_data.insert(
255 "client_hostname".to_string(),
256 serde_json::Value::String(hostname.clone()),
257 );
258 }
259 }
260 SmtpdEvent::Helo {
261 hostname,
262 client_ip,
263 client_hostname,
264 } => {
265 event_data.insert(
266 "event_type".to_string(),
267 serde_json::Value::String("helo".to_string()),
268 );
269 event_data.insert(
270 "helo_hostname".to_string(),
271 serde_json::Value::String(hostname.clone()),
272 );
273 if let Some(ip) = client_ip {
274 event_data.insert(
275 "client_ip".to_string(),
276 serde_json::Value::String(ip.clone()),
277 );
278 }
279 if let Some(hostname) = client_hostname {
280 event_data.insert(
281 "client_hostname".to_string(),
282 serde_json::Value::String(hostname.clone()),
283 );
284 }
285 }
286 SmtpdEvent::Auth {
287 method,
288 username,
289 success,
290 failure_reason,
291 } => {
292 event_data.insert(
293 "event_type".to_string(),
294 serde_json::Value::String("auth".to_string()),
295 );
296 event_data.insert(
297 "auth_method".to_string(),
298 serde_json::Value::String(method.clone()),
299 );
300 event_data.insert(
301 "username".to_string(),
302 serde_json::Value::String(username.clone()),
303 );
304 event_data.insert("success".to_string(), serde_json::Value::Bool(*success));
305 if let Some(reason) = failure_reason {
306 event_data.insert(
307 "failure_reason".to_string(),
308 serde_json::Value::String(reason.clone()),
309 );
310 }
311 }
312 SmtpdEvent::Accept {
313 from,
314 to,
315 size,
316 queue_id,
317 } => {
318 event_data.insert(
319 "event_type".to_string(),
320 serde_json::Value::String("accept".to_string()),
321 );
322 if let Some(from_addr) = from {
323 event_data.insert(
324 "from".to_string(),
325 serde_json::Value::String(from_addr.clone()),
326 );
327 }
328 if !to.is_empty() {
329 let to_array: Vec<serde_json::Value> = to
330 .iter()
331 .map(|addr| serde_json::Value::String(addr.clone()))
332 .collect();
333 event_data.insert("to".to_string(), serde_json::Value::Array(to_array));
334 }
335 if let Some(message_size) = size {
336 event_data.insert(
337 "size".to_string(),
338 serde_json::Value::Number(serde_json::Number::from(*message_size)),
339 );
340 }
341 if let Some(qid) = queue_id {
342 event_data.insert(
343 "queue_id".to_string(),
344 serde_json::Value::String(qid.clone()),
345 );
346 }
347 }
348 SmtpdEvent::ProtocolViolation {
349 client_ip,
350 client_hostname,
351 violation_type,
352 details,
353 } => {
354 event_data.insert(
355 "event_type".to_string(),
356 serde_json::Value::String("protocol_violation".to_string()),
357 );
358 event_data.insert(
359 "client_ip".to_string(),
360 serde_json::Value::String(client_ip.clone()),
361 );
362 event_data.insert(
363 "client_hostname".to_string(),
364 serde_json::Value::String(client_hostname.clone()),
365 );
366 event_data.insert(
367 "violation_type".to_string(),
368 serde_json::Value::String(violation_type.clone()),
369 );
370 event_data.insert(
371 "details".to_string(),
372 serde_json::Value::String(details.clone()),
373 );
374 }
375 }
376
377 event_data
378}