From a6b9d183742eb58e3d6ef3f5d7cfcff8f054dd2e Mon Sep 17 00:00:00 2001 From: Rodolphe Breard Date: Sat, 5 Jan 2019 11:40:19 +0100 Subject: [PATCH] Update the entry parser The latest OpenSMTPD draft added the timeout event, it therefore has been added to the parser. As shown in the new sessions examples, the timestamp format changed and the parameters are also optional. --- examples/samples/dual_session.txt | 14 ++++++--- examples/samples/single_session.txt | 7 +++-- src/entry.rs | 46 ++++++++++++++++++++++------- 3 files changed, 51 insertions(+), 16 deletions(-) diff --git a/examples/samples/dual_session.txt b/examples/samples/dual_session.txt index 762ebce..3788750 100644 --- a/examples/samples/dual_session.txt +++ b/examples/samples/dual_session.txt @@ -1,4 +1,10 @@ -report|1|1544130229|smtp-in|tx-mail|4b0148c60f798628|fc08ce7d||ok -report|1|1544130229|smtp-in|tx-mail|0f3004c08c82d33e|fc08ce7d||ok -report|1|1544130229|smtp-in|tx-rcpt|4b0148c60f798628|fc08ce7d||ok -report|1|1544130229|smtp-in|tx-rcpt|0f3004c08c82d33e|fc08ce7d||ok +report|1|1546681202.276920|smtp-in|link-connect|dbd829906c50e764|localhost|pass|127.0.0.1:34818|127.0.0.1:25 +report|1|1546681202.277715|smtp-in|filter-response|dbd829906c50e764|connected|proceed +report|1|1546681202.276920|smtp-in|link-connect|4b0148c60f798628|localhost|pass|127.0.0.1:34818|127.0.0.1:25 +report|1|1546681202.277715|smtp-in|filter-response|4b0148c60f798628|connected|proceed +report|1|1546681202.277761|smtp-in|protocol-server|dbd829906c50e764|220 laptop.home ESMTP OpenSMTPD +report|1|1546681232.283049|smtp-in|timeout|dbd829906c50e764 +report|1|1546681202.277761|smtp-in|protocol-server|4b0148c60f798628|220 laptop.home ESMTP OpenSMTPD +report|1|1546681232.283049|smtp-in|timeout|4b0148c60f798628 +report|1|1546681232.283083|smtp-in|link-disconnect|dbd829906c50e764 +report|1|1546681232.283083|smtp-in|link-disconnect|4b0148c60f798628 diff --git a/examples/samples/single_session.txt b/examples/samples/single_session.txt index ee5fd76..170b499 100644 --- a/examples/samples/single_session.txt +++ b/examples/samples/single_session.txt @@ -1,2 +1,5 @@ -report|1|1544130229|smtp-in|tx-mail|0f3004c08c82d33e|fc08ce7d||ok -report|1|1544130229|smtp-in|tx-rcpt|0f3004c08c82d33e|fc08ce7d||ok +report|1|1546681202.276920|smtp-in|link-connect|dbd829906c50e764|localhost|pass|127.0.0.1:34818|127.0.0.1:25 +report|1|1546681202.277715|smtp-in|filter-response|dbd829906c50e764|connected|proceed +report|1|1546681202.277761|smtp-in|protocol-server|dbd829906c50e764|220 laptop.home ESMTP OpenSMTPD +report|1|1546681232.283049|smtp-in|timeout|dbd829906c50e764 +report|1|1546681232.283083|smtp-in|link-disconnect|dbd829906c50e764 diff --git a/src/entry.rs b/src/entry.rs index f6134aa..99a3bbb 100644 --- a/src/entry.rs +++ b/src/entry.rs @@ -1,20 +1,20 @@ use crate::errors::Error; -use nom::{alt, alt_complete, call, complete, cond, do_parse, error_position, map_res, named, tag, - take_until, take_while}; +use nom::{alt, alt_complete, call, complete, cond, do_parse, error_position, map_res, named, opt, + tag, take_until, take_while}; -#[derive(Debug, PartialEq)] +#[derive(Clone, Debug, PartialEq)] pub enum Kind { Report, Filter, } -#[derive(Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum Subsystem { SmtpIn, SmtpOut, } -#[derive(Debug)] +#[derive(Clone, Debug, PartialEq)] pub enum Event { LinkConnect, LinkDisconnect, @@ -29,6 +29,7 @@ pub enum Event { TxRollback, ProtocolClient, ProtocolServer, + Timeout, FilterResponse, } @@ -41,7 +42,7 @@ pub struct Entry { pub event: Event, pub token: Option, pub session_id: u64, - pub params: String, + pub params: Option, } fn is_ascii_digit(c: char) -> bool { @@ -56,6 +57,10 @@ fn to_u8(s: &str) -> Result { s.parse() } +fn to_i32(s: &str) -> Result { + s.parse() +} + fn to_u64(s: &str) -> Result { s.parse() } @@ -93,14 +98,28 @@ named!(parse_event<&str, Event>, tag!("tx-rollback") => { |_| Event::TxRollback } | tag!("protocol-client") => { |_| Event::ProtocolClient } | tag!("protocol-server") => { |_| Event::ProtocolServer } | + tag!("timeout") => { |_| Event::Timeout } | tag!("filter-response") => { |_| Event::FilterResponse } ) ); +named!(parse_timestamp<&str, u64>, + do_parse!( + sec: parse_u64 >> + tag!(".") >> + nsec: parse_i32 >> + (sec) + ) +); + named!(parse_version<&str, u8>, map_res!(take_while!(is_ascii_digit), to_u8) ); +named!(parse_i32<&str, i32>, + map_res!(take_while!(is_ascii_digit), to_i32) +); + named!(parse_u64<&str, u64>, map_res!(take_while!(is_ascii_digit), to_u64) ); @@ -117,6 +136,14 @@ named!(parse_token<&str, u64>, ) ); +named!(parse_params<&str, String>, + do_parse!( + tag!("|") >> + s: take_until!("\n") >> + (s.to_string()) + ) +); + named!( parse_entry<&str, Entry>, do_parse!( @@ -124,7 +151,7 @@ named!( tag!("|") >> version: parse_version >> tag!("|") >> - timestamp: parse_u64 >> + timestamp: parse_timestamp >> tag!("|") >> subsystem: parse_subsystem >> tag!("|") >> @@ -132,8 +159,7 @@ named!( tag!("|") >> token: cond!(kind == Kind::Filter, parse_token) >> session_id: parse_u64_hex >> - tag!("|") >> - params: take_until!("\n") >> + params: opt!(parse_params) >> (Entry { kind, version, @@ -142,7 +168,7 @@ named!( event, token, session_id, - params: params.to_string(), + params: params, }) ) );