postfix_log_parser/formatters/json/
smtpd.rs

1use crate::events::SmtpdEvent;
2use serde_json;
3
4/// 将SMTPD事件转换为JSON对象
5pub 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}